diff options
| author | Keith Packard <keithp@keithp.com> | 2017-12-01 18:28:16 +0100 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2017-12-01 18:28:16 +0100 | 
| commit | 98923ae1189f062b8b94120d47a56892db25493f (patch) | |
| tree | eb585acd5600f529397077cddbe7edcecfb1d0a3 /src | |
| parent | 835bf4131f9e20575bfdf2179462ebdf54a14761 (diff) | |
altos/lisp: Split out frame vals from frame struct
This lets the frame be resized without moving the base structure. The
plan is to allow all frames to be resized, not just the global frame.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/lisp/ao_lisp.h | 38 | ||||
| -rw-r--r-- | src/lisp/ao_lisp_error.c | 5 | ||||
| -rw-r--r-- | src/lisp/ao_lisp_frame.c | 207 | ||||
| -rw-r--r-- | src/lisp/ao_lisp_make_const.c | 5 | ||||
| -rw-r--r-- | src/lisp/ao_lisp_mem.c | 42 | ||||
| -rw-r--r-- | src/lisp/ao_lisp_poly.c | 4 | 
6 files changed, 200 insertions, 101 deletions
| diff --git a/src/lisp/ao_lisp.h b/src/lisp/ao_lisp.h index 858212dd..96a7a05f 100644 --- a/src/lisp/ao_lisp.h +++ b/src/lisp/ao_lisp.h @@ -92,12 +92,13 @@ extern uint8_t		ao_lisp_pool[AO_LISP_POOL + AO_LISP_POOL_EXTRA] __attribute__((a  #define AO_LISP_ATOM		4  #define AO_LISP_BUILTIN		5  #define AO_LISP_FRAME		6 -#define AO_LISP_LAMBDA		7 -#define AO_LISP_STACK		8 -#define AO_LISP_BOOL		9 -#define AO_LISP_BIGINT		10 -#define AO_LISP_FLOAT		11 -#define AO_LISP_NUM_TYPE	12 +#define AO_LISP_FRAME_VALS	7 +#define AO_LISP_LAMBDA		8 +#define AO_LISP_STACK		9 +#define AO_LISP_BOOL		10 +#define AO_LISP_BIGINT		11 +#define AO_LISP_FLOAT		12 +#define AO_LISP_NUM_TYPE	13  /* Leave two bits for types to use as they please */  #define AO_LISP_OTHER_TYPE_MASK	0x3f @@ -154,11 +155,17 @@ struct ao_lisp_val {  	ao_poly		val;  }; +struct ao_lisp_frame_vals { +	uint8_t			type; +	uint8_t			size; +	struct ao_lisp_val	vals[]; +}; +  struct ao_lisp_frame {  	uint8_t			type;  	uint8_t			num;  	ao_poly			prev; -	struct ao_lisp_val	vals[]; +	ao_poly			vals;  };  struct ao_lisp_bool { @@ -221,6 +228,16 @@ ao_lisp_frame_poly(struct ao_lisp_frame *frame) {  	return ao_lisp_poly(frame, AO_LISP_OTHER);  } +static inline struct ao_lisp_frame_vals * +ao_lisp_poly_frame_vals(ao_poly poly) { +	return ao_lisp_ref(poly); +} + +static inline ao_poly +ao_lisp_frame_vals_poly(struct ao_lisp_frame_vals *vals) { +	return ao_lisp_poly(vals, AO_LISP_OTHER); +} +  enum eval_state {  	eval_sexpr,		/* Evaluate an sexpr */  	eval_val,		/* Value computed */ @@ -528,6 +545,12 @@ ao_lisp_stack_fetch(int id) {  	return ao_lisp_poly_stack(ao_lisp_poly_fetch(id));  } +void +ao_lisp_frame_stash(int id, struct ao_lisp_frame *frame); + +struct ao_lisp_frame * +ao_lisp_frame_fetch(int id); +  /* bool */  extern const struct ao_lisp_type ao_lisp_bool_type; @@ -713,6 +736,7 @@ ao_lisp_read_eval_print(void);  /* frame */  extern const struct ao_lisp_type ao_lisp_frame_type; +extern const struct ao_lisp_type ao_lisp_frame_vals_type;  #define AO_LISP_FRAME_FREE	6 diff --git a/src/lisp/ao_lisp_error.c b/src/lisp/ao_lisp_error.c index d1c9b941..ba135834 100644 --- a/src/lisp/ao_lisp_error.c +++ b/src/lisp/ao_lisp_error.c @@ -57,6 +57,7 @@ ao_lisp_error_frame(int indent, char *name, struct ao_lisp_frame *frame)  	tabs(indent);  	printf ("%s{", name);  	if (frame) { +		struct ao_lisp_frame_vals	*vals = ao_lisp_poly_frame_vals(frame->vals);  		if (frame->type & AO_LISP_FRAME_PRINT)  			printf("recurse...");  		else { @@ -66,9 +67,9 @@ ao_lisp_error_frame(int indent, char *name, struct ao_lisp_frame *frame)  					tabs(indent);  					printf("         ");  				} -				ao_lisp_poly_write(frame->vals[f].atom); +				ao_lisp_poly_write(vals->vals[f].atom);  				printf(" = "); -				ao_lisp_poly_write(frame->vals[f].val); +				ao_lisp_poly_write(vals->vals[f].val);  				printf("\n");  			}  			if (frame->prev) diff --git a/src/lisp/ao_lisp_frame.c b/src/lisp/ao_lisp_frame.c index ebdb7757..dd29e079 100644 --- a/src/lisp/ao_lisp_frame.c +++ b/src/lisp/ao_lisp_frame.c @@ -15,37 +15,77 @@  #include "ao_lisp.h"  static inline int -frame_num_size(int num) +frame_vals_num_size(int num)  { -	return sizeof (struct ao_lisp_frame) + num * sizeof (struct ao_lisp_val); +	return sizeof (struct ao_lisp_frame_vals) + num * sizeof (struct ao_lisp_val);  }  static int +frame_vals_size(void *addr) +{ +	struct ao_lisp_frame_vals	*vals = addr; +	return frame_vals_num_size(vals->size); +} + +static void +frame_vals_mark(void *addr) +{ +	struct ao_lisp_frame_vals	*vals = addr; +	int				f; + +	for (f = 0; f < vals->size; f++) { +		struct ao_lisp_val	*v = &vals->vals[f]; + +		ao_lisp_poly_mark(v->val, 0); +		MDBG_MOVE("frame mark atom %s %d val %d at %d\n", +			  ao_lisp_poly_atom(v->atom)->name, +			  MDBG_OFFSET(ao_lisp_ref(v->atom)), +			  MDBG_OFFSET(ao_lisp_ref(v->val)), f); +	} +} + +static void +frame_vals_move(void *addr) +{ +	struct ao_lisp_frame_vals	*vals = addr; +	int				f; + +	for (f = 0; f < vals->size; f++) { +		struct ao_lisp_val	*v = &vals->vals[f]; + +		ao_lisp_poly_move(&v->atom, 0); +		ao_lisp_poly_move(&v->val, 0); +		MDBG_MOVE("frame move atom %s %d val %d at %d\n", +			  ao_lisp_poly_atom(v->atom)->name, +			  MDBG_OFFSET(ao_lisp_ref(v->atom)), +			  MDBG_OFFSET(ao_lisp_ref(v->val)), f); +	} +} + +const struct ao_lisp_type ao_lisp_frame_vals_type = { +	.mark = frame_vals_mark, +	.size = frame_vals_size, +	.move = frame_vals_move, +	.name = "frame_vals" +}; + +static int  frame_size(void *addr)  { -	struct ao_lisp_frame	*frame = addr; -	return frame_num_size(frame->num); +	(void) addr; +	return sizeof (struct ao_lisp_frame);  }  static void  frame_mark(void *addr)  {  	struct ao_lisp_frame	*frame = addr; -	int			f;  	for (;;) {  		MDBG_MOVE("frame mark %d\n", MDBG_OFFSET(frame));  		if (!AO_LISP_IS_POOL(frame))  			break; -		for (f = 0; f < frame->num; f++) { -			struct ao_lisp_val	*v = &frame->vals[f]; - -			ao_lisp_poly_mark(v->val, 0); -			MDBG_MOVE("frame mark atom %s %d val %d at %d\n", -				  ao_lisp_poly_atom(v->atom)->name, -				  MDBG_OFFSET(ao_lisp_ref(v->atom)), -				  MDBG_OFFSET(ao_lisp_ref(v->val)), f); -		} +		ao_lisp_poly_mark(frame->vals, 0);  		frame = ao_lisp_poly_frame(frame->prev);  		MDBG_MOVE("frame next %d\n", MDBG_OFFSET(frame));  		if (!frame) @@ -59,7 +99,6 @@ static void  frame_move(void *addr)  {  	struct ao_lisp_frame	*frame = addr; -	int			f;  	for (;;) {  		struct ao_lisp_frame	*prev; @@ -68,16 +107,7 @@ frame_move(void *addr)  		MDBG_MOVE("frame move %d\n", MDBG_OFFSET(frame));  		if (!AO_LISP_IS_POOL(frame))  			break; -		for (f = 0; f < frame->num; f++) { -			struct ao_lisp_val	*v = &frame->vals[f]; - -			ao_lisp_poly_move(&v->atom, 0); -			ao_lisp_poly_move(&v->val, 0); -			MDBG_MOVE("frame move atom %s %d val %d at %d\n", -				  ao_lisp_poly_atom(v->atom)->name, -				  MDBG_OFFSET(ao_lisp_ref(v->atom)), -				  MDBG_OFFSET(ao_lisp_ref(v->val)), f); -		} +		ao_lisp_poly_move(&frame->vals, 0);  		prev = ao_lisp_poly_frame(frame->prev);  		if (!prev)  			break; @@ -104,8 +134,9 @@ const struct ao_lisp_type ao_lisp_frame_type = {  void  ao_lisp_frame_write(ao_poly p)  { -	struct ao_lisp_frame	*frame = ao_lisp_poly_frame(p); -	int			f; +	struct ao_lisp_frame		*frame = ao_lisp_poly_frame(p); +	struct ao_lisp_frame_vals	*vals = ao_lisp_poly_frame_vals(frame->vals); +	int				f;  	printf ("{");  	if (frame) { @@ -116,9 +147,9 @@ ao_lisp_frame_write(ao_poly p)  			for (f = 0; f < frame->num; f++) {  				if (f != 0)  					printf(", "); -				ao_lisp_poly_write(frame->vals[f].atom); +				ao_lisp_poly_write(vals->vals[f].atom);  				printf(" = "); -				ao_lisp_poly_write(frame->vals[f].val); +				ao_lisp_poly_write(vals->vals[f].val);  			}  			if (frame->prev)  				ao_lisp_poly_write(frame->prev); @@ -131,11 +162,13 @@ ao_lisp_frame_write(ao_poly p)  static int  ao_lisp_frame_find(struct ao_lisp_frame *frame, int top, ao_poly atom)  { -	int l = 0; -	int r = top - 1; +	struct ao_lisp_frame_vals	*vals = ao_lisp_poly_frame_vals(frame->vals); +	int 				l = 0; +	int 				r = top - 1; +  	while (l <= r) {  		int m = (l + r) >> 1; -		if (frame->vals[m].atom < atom) +		if (vals->vals[m].atom < atom)  			l = m + 1;  		else  			r = m - 1; @@ -146,62 +179,57 @@ ao_lisp_frame_find(struct ao_lisp_frame *frame, int top, ao_poly atom)  ao_poly *  ao_lisp_frame_ref(struct ao_lisp_frame *frame, ao_poly atom)  { -	int l = ao_lisp_frame_find(frame, frame->num, atom); +	struct ao_lisp_frame_vals	*vals = ao_lisp_poly_frame_vals(frame->vals); +	int				l = ao_lisp_frame_find(frame, frame->num, atom);  	if (l >= frame->num)  		return NULL; -	if (frame->vals[l].atom != atom) +	if (vals->vals[l].atom != atom)  		return NULL; -	return &frame->vals[l].val; +	return &vals->vals[l].val;  } -int -ao_lisp_frame_set(struct ao_lisp_frame *frame, ao_poly atom, ao_poly val) -{ -	while (frame) { -		if (!AO_LISP_IS_CONST(frame)) { -			ao_poly *ref = ao_lisp_frame_ref(frame, atom); -			if (ref) { -				*ref = val; -				return 1; -			} -		} -		frame = ao_lisp_poly_frame(frame->prev); -	} -	return 0; -} +struct ao_lisp_frame	*ao_lisp_frame_free_list[AO_LISP_FRAME_FREE]; -ao_poly -ao_lisp_frame_get(struct ao_lisp_frame *frame, ao_poly atom) +static struct ao_lisp_frame_vals * +ao_lisp_frame_vals_new(int num)  { -	while (frame) { -		ao_poly *ref = ao_lisp_frame_ref(frame, atom); -		if (ref) -			return *ref; -		frame = ao_lisp_poly_frame(frame->prev); -	} -	return AO_LISP_NIL; -} +	struct ao_lisp_frame_vals	*vals; -struct ao_lisp_frame	*ao_lisp_frame_free_list[AO_LISP_FRAME_FREE]; +	vals = ao_lisp_alloc(frame_vals_num_size(num)); +	if (!vals) +		return NULL; +	vals->type = AO_LISP_FRAME_VALS; +	vals->size = num; +	return vals; +}  struct ao_lisp_frame *  ao_lisp_frame_new(int num)  { -	struct ao_lisp_frame	*frame; +	struct ao_lisp_frame		*frame; +	struct ao_lisp_frame_vals	*vals; -	if (num < AO_LISP_FRAME_FREE && (frame = ao_lisp_frame_free_list[num])) +	if (num < AO_LISP_FRAME_FREE && (frame = ao_lisp_frame_free_list[num])) {  		ao_lisp_frame_free_list[num] = ao_lisp_poly_frame(frame->prev); -	else { -		frame = ao_lisp_alloc(frame_num_size(num)); +		vals = ao_lisp_poly_frame_vals(frame->vals); +	} else { +		frame = ao_lisp_alloc(sizeof (struct ao_lisp_frame));  		if (!frame)  			return NULL; +		frame->type = AO_LISP_FRAME; +		frame->num = 0; +		frame->prev = AO_LISP_NIL; +		frame->vals = AO_LISP_NIL; +		ao_lisp_poly_stash(0, ao_lisp_frame_poly(frame)); +		vals = ao_lisp_frame_vals_new(num); +		frame = ao_lisp_poly_frame(ao_lisp_poly_fetch(0)); +		frame->vals = ao_lisp_frame_vals_poly(vals);  	} -	frame->type = AO_LISP_FRAME;  	frame->num = num;  	frame->prev = AO_LISP_NIL; -	memset(frame->vals, '\0', num * sizeof (struct ao_lisp_val)); +	memset(vals, '\0', vals->size * sizeof (struct ao_lisp_val));  	return frame;  } @@ -227,47 +255,46 @@ ao_lisp_frame_free(struct ao_lisp_frame *frame)  }  static struct ao_lisp_frame * -ao_lisp_frame_realloc(struct ao_lisp_frame **frame_ref, int new_num) +ao_lisp_frame_realloc(struct ao_lisp_frame *frame, int new_num)  { -	struct ao_lisp_frame	*frame = *frame_ref; -	struct ao_lisp_frame	*new; -	int			copy; +	struct ao_lisp_frame_vals	*vals; +	struct ao_lisp_frame_vals	*new_vals; +	int				copy;  	if (new_num == frame->num)  		return frame; -	new = ao_lisp_frame_new(new_num); -	if (!new) +	ao_lisp_frame_stash(0, frame); +	new_vals = ao_lisp_frame_vals_new(new_num); +	if (!new_vals)  		return NULL; -	/* -	 * Re-fetch the frame as it may have moved -	 * during the allocation -	 */ -	frame = *frame_ref; +	frame = ao_lisp_frame_fetch(0); +	vals = ao_lisp_poly_frame_vals(frame->vals);  	copy = new_num;  	if (copy > frame->num)  		copy = frame->num; -	memcpy(new->vals, frame->vals, copy * sizeof (struct ao_lisp_val)); -	new->prev = frame->prev; -	ao_lisp_frame_free(frame); -	return new; +	memcpy(new_vals->vals, vals->vals, copy * sizeof (struct ao_lisp_val)); +	frame->vals = ao_lisp_frame_vals_poly(new_vals); +	frame->num = new_num; +	return frame;  }  void  ao_lisp_frame_bind(struct ao_lisp_frame *frame, int num, ao_poly atom, ao_poly val)  { -	int l = ao_lisp_frame_find(frame, num, atom); +	struct ao_lisp_frame_vals	*vals = ao_lisp_poly_frame_vals(frame->vals); +	int 				l = ao_lisp_frame_find(frame, num, atom); -	memmove(&frame->vals[l+1], -		&frame->vals[l], +	memmove(&vals->vals[l+1], +		&vals->vals[l],  		(num - l) * sizeof (struct ao_lisp_val)); -	frame->vals[l].atom = atom; -	frame->vals[l].val = val; +	vals->vals[l].atom = atom; +	vals->vals[l].val = val;  }  int  ao_lisp_frame_add(struct ao_lisp_frame **frame_ref, ao_poly atom, ao_poly val)  { -	struct ao_lisp_frame *frame = *frame_ref; +	struct ao_lisp_frame	*frame = *frame_ref;  	ao_poly *ref = frame ? ao_lisp_frame_ref(frame, atom) : NULL;  	if (!ref) { @@ -276,14 +303,14 @@ ao_lisp_frame_add(struct ao_lisp_frame **frame_ref, ao_poly atom, ao_poly val)  		ao_lisp_poly_stash(1, val);  		if (frame) {  			f = frame->num; -			frame = ao_lisp_frame_realloc(frame_ref, f + 1); +			frame = ao_lisp_frame_realloc(frame, f + 1);  		} else {  			f = 0;  			frame = ao_lisp_frame_new(1); +			*frame_ref = frame;  		}  		if (!frame)  			return 0; -		*frame_ref = frame;  		atom = ao_lisp_poly_fetch(0);  		val = ao_lisp_poly_fetch(1);  		ao_lisp_frame_bind(frame, frame->num - 1, atom, val); diff --git a/src/lisp/ao_lisp_make_const.c b/src/lisp/ao_lisp_make_const.c index f23d34db..f9bb5452 100644 --- a/src/lisp/ao_lisp_make_const.c +++ b/src/lisp/ao_lisp_make_const.c @@ -326,10 +326,11 @@ main(int argc, char **argv)  	ao_lisp_collect(AO_LISP_COLLECT_FULL);  	for (f = 0; f < ao_lisp_frame_global->num; f++) { -		val = ao_has_macro(ao_lisp_frame_global->vals[f].val); +		struct ao_lisp_frame_vals	*vals = ao_lisp_poly_frame_vals(ao_lisp_frame_global->vals); +		val = ao_has_macro(vals->vals[f].val);  		if (val != AO_LISP_NIL) {  			printf("error: function %s contains unresolved macro: ", -			       ao_lisp_poly_atom(ao_lisp_frame_global->vals[f].atom)->name); +			       ao_lisp_poly_atom(vals->vals[f].atom)->name);  			ao_lisp_poly_write(val);  			printf("\n");  			exit(1); diff --git a/src/lisp/ao_lisp_mem.c b/src/lisp/ao_lisp_mem.c index dc0008c4..890eba1b 100644 --- a/src/lisp/ao_lisp_mem.c +++ b/src/lisp/ao_lisp_mem.c @@ -148,6 +148,7 @@ struct ao_lisp_root {  static struct ao_lisp_cons 	*save_cons[2];  static char			*save_string[2]; +static struct ao_lisp_frame	*save_frame[1];  static ao_poly			save_poly[3];  static const struct ao_lisp_root	ao_lisp_root[] = { @@ -168,6 +169,10 @@ static const struct ao_lisp_root	ao_lisp_root[] = {  		.addr = (void **) &save_string[1],  	},  	{ +		.type = &ao_lisp_frame_type, +		.addr = (void **) &save_frame[0], +	}, +	{  		.type = NULL,  		.addr = (void **) (void *) &save_poly[0]  	}, @@ -455,6 +460,7 @@ static const struct ao_lisp_type *ao_lisp_types[AO_LISP_NUM_TYPE] = {  	[AO_LISP_ATOM] = &ao_lisp_atom_type,  	[AO_LISP_BUILTIN] = &ao_lisp_builtin_type,  	[AO_LISP_FRAME] = &ao_lisp_frame_type, +	[AO_LISP_FRAME_VALS] = &ao_lisp_frame_vals_type,  	[AO_LISP_LAMBDA] = &ao_lisp_lambda_type,  	[AO_LISP_STACK] = &ao_lisp_stack_type,  	[AO_LISP_BOOL] = &ao_lisp_bool_type, @@ -620,6 +626,29 @@ ao_lisp_collect(uint8_t style)   * Mark interfaces for objects   */ + +/* + * Mark a block of memory with an explicit size + */ + +int +ao_lisp_mark_block(void *addr, int size) +{ +	int offset; +	if (!AO_LISP_IS_POOL(addr)) +		return 1; + +	offset = pool_offset(addr); +	MDBG_MOVE("mark memory %d\n", MDBG_OFFSET(addr)); +	if (busy(ao_lisp_busy, offset)) { +		MDBG_MOVE("already marked\n"); +		return 1; +	} +	mark(ao_lisp_busy, offset); +	note_chunk(offset, size); +	return 0; +} +  /*   * Note a reference to memory and collect information about a few   * object sizes at a time @@ -891,3 +920,16 @@ ao_lisp_string_fetch(int id)  	return string;  } +void +ao_lisp_frame_stash(int id, struct ao_lisp_frame *frame) +{ +	save_frame[id] = frame; +} + +struct ao_lisp_frame * +ao_lisp_frame_fetch(int id) +{ +	struct ao_lisp_frame *frame = save_frame[id]; +	save_frame[id] = NULL; +	return frame; +} diff --git a/src/lisp/ao_lisp_poly.c b/src/lisp/ao_lisp_poly.c index e93e1192..d14f4151 100644 --- a/src/lisp/ao_lisp_poly.c +++ b/src/lisp/ao_lisp_poly.c @@ -44,6 +44,10 @@ static const struct ao_lisp_funcs ao_lisp_funcs[AO_LISP_NUM_TYPE] = {  		.write = ao_lisp_frame_write,  		.display = ao_lisp_frame_write,  	}, +	[AO_LISP_FRAME_VALS] = { +		.write = NULL, +		.display = NULL, +	},  	[AO_LISP_LAMBDA] = {  		.write = ao_lisp_lambda_write,  		.display = ao_lisp_lambda_write, | 
