X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Flisp%2Fao_lisp_frame.c;h=90344719afedc7881e5687cbc635a290f19acf7b;hb=7da6bfc195fad97e3afc576c609897c131fd4d8c;hp=8bf985710c73d7b94ae4b5be0046131604be9cb7;hpb=3366efb139653939f053c1fe4aba352ba3b66c94;p=fw%2Faltos diff --git a/src/lisp/ao_lisp_frame.c b/src/lisp/ao_lisp_frame.c index 8bf98571..90344719 100644 --- a/src/lisp/ao_lisp_frame.c +++ b/src/lisp/ao_lisp_frame.c @@ -48,7 +48,7 @@ frame_mark(void *addr) for (f = 0; f < frame->num; f++) { struct ao_lisp_val *v = &frame->vals[f]; - ao_lisp_poly_mark(v->val); + ao_lisp_poly_mark(v->val, 0); DBG ("\tframe mark atom %s %d val %d at %d\n", ao_lisp_poly_atom(v->atom)->name, OFFSET(v->atom), OFFSET(v->val), f); @@ -69,19 +69,28 @@ frame_move(void *addr) int f; for (;;) { + struct ao_lisp_frame *next; + int ret; + DBG("frame move %p\n", 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); + ao_lisp_poly_move(&v->atom, 0); DBG("moved atom %s\n", ao_lisp_poly_atom(v->atom)->name); - ao_lisp_poly_move(&v->val); + ao_lisp_poly_move(&v->val, 0); } - if (ao_lisp_poly_move(&frame->next)) + next = ao_lisp_poly_frame(frame->next); + ret = 1; + if (next) + ret = ao_lisp_move_memory((void **) &next, frame_size(next)); + if (next != ao_lisp_poly_frame(frame->next)) + frame->next = ao_lisp_frame_poly(next); + if (ret) break; - frame = ao_lisp_poly_frame(frame->next); + frame = next; } } @@ -91,6 +100,27 @@ const struct ao_lisp_type ao_lisp_frame_type = { .move = frame_move }; +void +ao_lisp_frame_print(ao_poly p) +{ + struct ao_lisp_frame *frame = ao_lisp_poly_frame(p); + int f; + + printf ("{"); + if (frame) { + for (f = 0; f < frame->num; 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); + } + printf("}"); +} + ao_poly * ao_lisp_frame_ref(struct ao_lisp_frame *frame, ao_poly atom) { @@ -144,8 +174,9 @@ ao_lisp_frame_new(int num) } static struct ao_lisp_frame * -ao_lisp_frame_realloc(struct ao_lisp_frame *frame, int new_num) +ao_lisp_frame_realloc(struct ao_lisp_frame **frame_ref, int new_num) { + struct ao_lisp_frame *frame = *frame_ref; struct ao_lisp_frame *new; int copy; @@ -154,34 +185,45 @@ ao_lisp_frame_realloc(struct ao_lisp_frame *frame, int new_num) new = ao_lisp_frame_new(new_num); if (!new) return NULL; + /* + * Re-fetch the frame as it may have moved + * during the allocation + */ + frame = *frame_ref; copy = new_num; if (copy > frame->num) copy = frame->num; memcpy(new->vals, frame->vals, copy * sizeof (struct ao_lisp_val)); - if (frame) - new->next = frame->next; + new->next = frame->next; return new; } -struct ao_lisp_frame * -ao_lisp_frame_add(struct ao_lisp_frame *frame, ao_poly atom, ao_poly 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; ao_poly *ref = frame ? ao_lisp_frame_ref(frame, atom) : NULL; + if (!ref) { int f; + ao_lisp_root_poly_add(&atom); + ao_lisp_root_poly_add(&val); if (frame) { f = frame->num; - frame = ao_lisp_frame_realloc(frame, f + 1); + frame = ao_lisp_frame_realloc(frame_ref, f + 1); } else { f = 0; frame = ao_lisp_frame_new(1); } + ao_lisp_root_clear(&atom); + ao_lisp_root_clear(&val); if (!frame) - return NULL; + return 0; + *frame_ref = frame; DBG ("add atom %s %d, val %d at %d\n", ao_lisp_poly_atom(atom)->name, OFFSET(atom), OFFSET(val), f); frame->vals[f].atom = atom; ref = &frame->vals[f].val; } *ref = val; - return frame; + return 1; }