X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Flisp%2Fao_lisp_frame.c;h=dd29e0799d742f520c633c63d955dc78eab1e596;hb=98923ae1189f062b8b94120d47a56892db25493f;hp=05f6d253ca23159fee0413c516e32cbbc9be0c8d;hpb=c3a4d7721f0f5d082336b8cc9c9d765ad2f7d17e;p=fw%2Faltos diff --git a/src/lisp/ao_lisp_frame.c b/src/lisp/ao_lisp_frame.c index 05f6d253..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; @@ -102,10 +132,11 @@ const struct ao_lisp_type ao_lisp_frame_type = { }; void -ao_lisp_frame_print(ao_poly p) +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,12 +147,12 @@ ao_lisp_frame_print(ao_poly p) for (f = 0; f < frame->num; f++) { if (f != 0) printf(", "); - ao_lisp_poly_print(frame->vals[f].atom); + ao_lisp_poly_write(vals->vals[f].atom); printf(" = "); - ao_lisp_poly_print(frame->vals[f].val); + ao_lisp_poly_write(vals->vals[f].val); } if (frame->prev) - ao_lisp_poly_print(frame->prev); + ao_lisp_poly_write(frame->prev); frame->type &= ~AO_LISP_FRAME_PRINT; } } @@ -131,11 +162,13 @@ ao_lisp_frame_print(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);