diff options
Diffstat (limited to 'src/lisp/ao_lisp_frame.c')
| -rw-r--r-- | src/lisp/ao_lisp_frame.c | 91 | 
1 files changed, 61 insertions, 30 deletions
| diff --git a/src/lisp/ao_lisp_frame.c b/src/lisp/ao_lisp_frame.c index e23a6413..052d27d7 100644 --- a/src/lisp/ao_lisp_frame.c +++ b/src/lisp/ao_lisp_frame.c @@ -24,7 +24,7 @@ static int  frame_size(void *addr)  {  	struct ao_lisp_frame	*frame = addr; -	return frame_num_size(frame->num); +	return frame_num_size(ao_lisp_frame_num(frame));  }  static void @@ -37,7 +37,7 @@ frame_mark(void *addr)  		MDBG_MOVE("frame mark %d\n", MDBG_OFFSET(frame));  		if (!AO_LISP_IS_POOL(frame))  			break; -		for (f = 0; f < frame->num; f++) { +		for (f = 0; f < ao_lisp_frame_num(frame); f++) {  			struct ao_lisp_val	*v = &frame->vals[f];  			ao_lisp_poly_mark(v->val, 0); @@ -46,7 +46,7 @@ frame_mark(void *addr)  				  MDBG_OFFSET(ao_lisp_ref(v->atom)),  				  MDBG_OFFSET(ao_lisp_ref(v->val)), f);  		} -		frame = ao_lisp_poly_frame(frame->next); +		frame = ao_lisp_poly_frame(frame->prev);  		MDBG_MOVE("frame next %d\n", MDBG_OFFSET(frame));  		if (!frame)  			break; @@ -62,13 +62,13 @@ frame_move(void *addr)  	int			f;  	for (;;) { -		struct ao_lisp_frame	*next; +		struct ao_lisp_frame	*prev;  		int			ret;  		MDBG_MOVE("frame move %d\n", MDBG_OFFSET(frame));  		if (!AO_LISP_IS_POOL(frame))  			break; -		for (f = 0; f < frame->num; f++) { +		for (f = 0; f < ao_lisp_frame_num(frame); f++) {  			struct ao_lisp_val	*v = &frame->vals[f];  			ao_lisp_poly_move(&v->atom, 0); @@ -78,19 +78,19 @@ frame_move(void *addr)  				  MDBG_OFFSET(ao_lisp_ref(v->atom)),  				  MDBG_OFFSET(ao_lisp_ref(v->val)), f);  		} -		next = ao_lisp_poly_frame(frame->next); -		if (!next) +		prev = ao_lisp_poly_frame(frame->prev); +		if (!prev)  			break; -		ret = ao_lisp_move_memory(&ao_lisp_frame_type, (void **) &next); -		if (next != ao_lisp_poly_frame(frame->next)) { -			MDBG_MOVE("frame next moved from %d to %d\n", -				  MDBG_OFFSET(ao_lisp_poly_frame(frame->next)), -				  MDBG_OFFSET(next)); -			frame->next = ao_lisp_frame_poly(next); +		ret = ao_lisp_move_memory(&ao_lisp_frame_type, (void **) &prev); +		if (prev != ao_lisp_poly_frame(frame->prev)) { +			MDBG_MOVE("frame prev moved from %d to %d\n", +				  MDBG_OFFSET(ao_lisp_poly_frame(frame->prev)), +				  MDBG_OFFSET(prev)); +			frame->prev = ao_lisp_frame_poly(prev);  		}  		if (ret)  			break; -		frame = next; +		frame = prev;  	}  } @@ -109,15 +109,15 @@ ao_lisp_frame_print(ao_poly p)  	printf ("{");  	if (frame) { -		for (f = 0; f < frame->num; f++) { +		for (f = 0; f < ao_lisp_frame_num(frame); f++) {  			if (f != 0)  				printf(", ");  			ao_lisp_poly_print(frame->vals[f].atom);  			printf(" = ");  			ao_lisp_poly_print(frame->vals[f].val);  		} -		if (frame->next) -			ao_lisp_poly_print(frame->next); +		if (frame->prev) +			ao_lisp_poly_print(frame->prev);  	}  	printf("}");  } @@ -126,7 +126,7 @@ ao_poly *  ao_lisp_frame_ref(struct ao_lisp_frame *frame, ao_poly atom)  {  	int f; -	for (f = 0; f < frame->num; f++) +	for (f = 0; f < ao_lisp_frame_num(frame); f++)  		if (frame->vals[f].atom == atom)  			return &frame->vals[f].val;  	return NULL; @@ -143,7 +143,7 @@ ao_lisp_frame_set(struct ao_lisp_frame *frame, ao_poly atom, ao_poly val)  				return 1;  			}  		} -		frame = ao_lisp_poly_frame(frame->next); +		frame = ao_lisp_poly_frame(frame->prev);  	}  	return 0;  } @@ -155,25 +155,55 @@ ao_lisp_frame_get(struct ao_lisp_frame *frame, ao_poly atom)  		ao_poly *ref = ao_lisp_frame_ref(frame, atom);  		if (ref)  			return *ref; -		frame = ao_lisp_poly_frame(frame->next); +		frame = ao_lisp_poly_frame(frame->prev);  	}  	return AO_LISP_NIL;  } +struct ao_lisp_frame	*ao_lisp_frame_free_list[AO_LISP_FRAME_FREE]; +  struct ao_lisp_frame *  ao_lisp_frame_new(int num)  { -	struct ao_lisp_frame *frame = ao_lisp_alloc(frame_num_size(num)); +	struct ao_lisp_frame	*frame; -	if (!frame) -		return NULL; +	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)); +		if (!frame) +			return NULL; +	}  	frame->type = AO_LISP_FRAME; -	frame->num = num; -	frame->next = AO_LISP_NIL; +	frame->_num = num; +	frame->prev = AO_LISP_NIL;  	memset(frame->vals, '\0', num * sizeof (struct ao_lisp_val));  	return frame;  } +ao_poly +ao_lisp_frame_mark(struct ao_lisp_frame *frame) +{ +	if (!frame) +		return AO_LISP_NIL; +	if (frame->_num == 0xff) +		ao_lisp_abort(); +	frame->_num |= AO_LISP_FRAME_MARK; +	return ao_lisp_frame_poly(frame); +} + +void +ao_lisp_frame_free(struct ao_lisp_frame *frame) +{ +	if (!ao_lisp_frame_marked(frame)) { +		int	num = ao_lisp_frame_num(frame); +		if (num < AO_LISP_FRAME_FREE) { +			frame->prev = ao_lisp_frame_poly(ao_lisp_frame_free_list[num]); +			ao_lisp_frame_free_list[num] = frame; +		} +	} +} +  static struct ao_lisp_frame *  ao_lisp_frame_realloc(struct ao_lisp_frame **frame_ref, int new_num)  { @@ -181,7 +211,7 @@ ao_lisp_frame_realloc(struct ao_lisp_frame **frame_ref, int new_num)  	struct ao_lisp_frame	*new;  	int			copy; -	if (new_num == frame->num) +	if (new_num == ao_lisp_frame_num(frame))  		return frame;  	new = ao_lisp_frame_new(new_num);  	if (!new) @@ -192,10 +222,11 @@ ao_lisp_frame_realloc(struct ao_lisp_frame **frame_ref, int new_num)  	 */  	frame = *frame_ref;  	copy = new_num; -	if (copy > frame->num) -		copy = frame->num; +	if (copy > ao_lisp_frame_num(frame)) +		copy = ao_lisp_frame_num(frame);  	memcpy(new->vals, frame->vals, copy * sizeof (struct ao_lisp_val)); -	new->next = frame->next; +	new->prev = frame->prev; +	ao_lisp_frame_free(frame);  	return new;  } @@ -210,7 +241,7 @@ ao_lisp_frame_add(struct ao_lisp_frame **frame_ref, ao_poly atom, ao_poly val)  		ao_lisp_poly_stash(0, atom);  		ao_lisp_poly_stash(1, val);  		if (frame) { -			f = frame->num; +			f = ao_lisp_frame_num(frame);  			frame = ao_lisp_frame_realloc(frame_ref, f + 1);  		} else {  			f = 0; | 
