diff options
Diffstat (limited to 'src/lisp/ao_lisp_frame.c')
| -rw-r--r-- | src/lisp/ao_lisp_frame.c | 207 | 
1 files changed, 117 insertions, 90 deletions
| 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); | 
