diff --git a/eval.c b/eval.c index b7a8fe1b..758eaab3 100644 --- a/eval.c +++ b/eval.c @@ -363,26 +363,29 @@ static sexp sexp_compile_error(sexp ctx, char *message, sexp obj) { } while (0) static sexp analyze_app (sexp ctx, sexp x) { - sexp tmp; sexp_gc_var(ctx, res, s_res); + sexp_gc_var(ctx, tmp, s_tmp); sexp_gc_preserve(ctx, res, s_res); + sexp_gc_preserve(ctx, tmp, s_tmp); for (res=SEXP_NULL; sexp_pairp(x); x=sexp_cdr(x)) { sexp_push(ctx, res, SEXP_FALSE); tmp = analyze(ctx, sexp_car(x)); if (sexp_exceptionp(tmp)) { res = tmp; break; - } else + } else { sexp_car(res) = tmp; + } } sexp_gc_release(ctx, res, s_res); return (sexp_pairp(res) ? sexp_nreverse(ctx, res) : res); } static sexp analyze_seq (sexp ctx, sexp ls) { - sexp tmp; sexp_gc_var(ctx, res, s_res); + sexp_gc_var(ctx, tmp, s_tmp); sexp_gc_preserve(ctx, res, s_res); + sexp_gc_preserve(ctx, tmp, s_tmp); if (sexp_nullp(ls)) res = SEXP_VOID; else if (sexp_nullp(sexp_cdr(ls))) @@ -517,13 +520,16 @@ static sexp analyze_if (sexp ctx, sexp x) { } static sexp analyze_define (sexp ctx, sexp x) { - sexp name, res, env = sexp_context_env(ctx); + sexp name, res; sexp_gc_var(ctx, ref, s_ref); sexp_gc_var(ctx, value, s_value); sexp_gc_var(ctx, tmp, s_tmp); + sexp_gc_var(ctx, env, s_env); sexp_gc_preserve(ctx, ref, s_ref); sexp_gc_preserve(ctx, value, s_value); sexp_gc_preserve(ctx, tmp, s_tmp); + sexp_gc_preserve(ctx, env, s_env); + env = sexp_context_env(ctx); name = (sexp_pairp(sexp_cadr(x)) ? sexp_caadr(x) : sexp_cadr(x)); if (sexp_env_lambda(env) && sexp_lambdap(sexp_env_lambda(env))) { tmp = sexp_cons(ctx, name, sexp_context_lambda(ctx)); @@ -613,13 +619,15 @@ static sexp analyze_letrec_syntax (sexp ctx, sexp x) { } static sexp analyze (sexp ctx, sexp object) { - sexp op, cell; + sexp op; sexp_gc_var(ctx, res, s_res); sexp_gc_var(ctx, tmp, s_tmp); sexp_gc_var(ctx, x, s_x); + sexp_gc_var(ctx, cell, s_cell); sexp_gc_preserve(ctx, res, s_res); sexp_gc_preserve(ctx, tmp, s_tmp); sexp_gc_preserve(ctx, x, s_x); + sexp_gc_preserve(ctx, cell, s_cell); x = object; loop: if (sexp_pairp(x)) { @@ -1104,15 +1112,19 @@ static sexp make_param_list(sexp ctx, sexp_uint_t i) { } static sexp make_opcode_procedure (sexp ctx, sexp op, sexp_uint_t i) { - sexp ctx2, lambda, ls, bc, res, env; + sexp ls, bc, res, env; sexp_gc_var(ctx, params, s_params); sexp_gc_var(ctx, ref, s_ref); sexp_gc_var(ctx, refs, s_refs); + sexp_gc_var(ctx, lambda, s_lambda); + sexp_gc_var(ctx, ctx2, s_ctx2); if (i == sexp_opcode_num_args(op) && sexp_opcode_proc(op)) return sexp_opcode_proc(op); /* return before preserving */ sexp_gc_preserve(ctx, params, s_params); sexp_gc_preserve(ctx, ref, s_ref); sexp_gc_preserve(ctx, refs, s_refs); + sexp_gc_preserve(ctx, lambda, s_lambda); + sexp_gc_preserve(ctx, ctx2, s_ctx2); params = make_param_list(ctx, i); lambda = sexp_make_lambda(ctx, params); ctx2 = sexp_make_child_context(ctx, lambda); @@ -1201,7 +1213,6 @@ sexp vm (sexp ctx, sexp proc) { fprintf(stderr, "%s\n", (*ip<=71)?reverse_opcode_names[*ip]:"UNKNOWN"); } #endif - sexp_context_top(ctx) = top; /* debugging */ switch (*ip++) { case OP_NOOP: break; diff --git a/gc.c b/gc.c index 636e2579..0f5c63d7 100644 --- a/gc.c +++ b/gc.c @@ -4,16 +4,22 @@ #include "sexp.h" -/* #define SEXP_INITIAL_HEAP_SIZE (3*1024*1024) */ -#define SEXP_INITIAL_HEAP_SIZE 37000 +#define SEXP_INITIAL_HEAP_SIZE (2*1024*1024) #define SEXP_MAXIMUM_HEAP_SIZE 0 #define SEXP_MINIMUM_OBJECT_SIZE (sexp_sizeof(flonum)) -static char* sexp_heap; -static char* sexp_heap_end; -static sexp sexp_free_list; +typedef struct sexp_heap *sexp_heap; +struct sexp_heap { + sexp_uint_t size; + sexp free_list; + sexp_heap next; + char *data; +}; + +static sexp_heap heap; static sexp* stack_base; +extern sexp continuation_resumer, final_resumer; sexp_uint_t sexp_allocated_bytes (sexp x) { sexp_uint_t res, *len_ptr; @@ -51,531 +57,149 @@ void sexp_mark (sexp x) { } } -void simple_write (sexp obj, int depth, FILE *out) { - unsigned long len, c, res; - long i=0; - double f; - char *str=NULL; - - if (! obj) { - fputs("#", out); - } else if (! sexp_pointerp(obj)) { - if (sexp_integerp(obj)) { - fprintf(out, "%ld", sexp_unbox_integer(obj)); - } else if (sexp_charp(obj)) { - if (obj == sexp_make_character(' ')) - fputs("#\\space", out); - else if (obj == sexp_make_character('\n')) - fputs("#\\newline", out); - else if (obj == sexp_make_character('\r')) - fputs("#\\return", out); - else if (obj == sexp_make_character('\t')) - fputs("#\\tab", out); - else if ((33 <= sexp_unbox_character(obj)) - && (sexp_unbox_character(obj) < 127)) - fprintf(out, "#\\%c", sexp_unbox_character(obj)); - else - fprintf(out, "#\\x%02d", sexp_unbox_character(obj)); - } else if (sexp_symbolp(obj)) { - -#if USE_HUFF_SYMS - if (((sexp_uint_t)obj&7)==7) { - c = ((sexp_uint_t)obj)>>3; - while (c) { -#include "sexp-unhuff.c" - putc(res, out); - } - } -#endif - - } else { - switch ((sexp_uint_t) obj) { - case (sexp_uint_t) SEXP_NULL: - fputs("()", out); break; - case (sexp_uint_t) SEXP_TRUE: - fputs("#t", out); break; - case (sexp_uint_t) SEXP_FALSE: - fputs("#f", out); break; - case (sexp_uint_t) SEXP_EOF: - fputs("#", out); break; - case (sexp_uint_t) SEXP_UNDEF: - case (sexp_uint_t) SEXP_VOID: - fputs("#", out); break; - default: - fprintf(out, "#", obj); - } - } - } else if (depth <= 0) { - fprintf(out, "#<...>"); - } else { - switch (sexp_pointer_tag(obj)) { - case SEXP_PAIR: - putc('(', out); - simple_write(sexp_car(obj), depth-1, out); - if (sexp_pairp(sexp_cdr(obj))) { - fputs(" ...", out); - } else if (! sexp_nullp(sexp_cdr(obj))) { - fputs(" . ", out); - simple_write(sexp_cdr(obj), depth-1, out); - } - putc(')', out); - break; - case SEXP_VECTOR: - len = sexp_vector_length(obj); - if (len == 0) { - fputs("#()", out); - } else { - fprintf(out, "#(... %ld ...)", len); - } - break; - case SEXP_FLONUM: - f = sexp_flonum_value(obj); - fprintf(out, "%.15g%s", f, (f == trunc(f)) ? ".0" : ""); - break; - case SEXP_PROCEDURE: - fputs("#', out); - break; - case SEXP_IPORT: - fputs("#", out); break; - case SEXP_OPORT: - fputs("#", out); break; - case SEXP_CORE: - fputs("#", out); break; - case SEXP_OPCODE: - fputs("#", out); break; - case SEXP_BYTECODE: - fputs("#", out); break; - case SEXP_ENV: - fprintf(out, "#", obj); break; - case SEXP_EXCEPTION: - fputs("#", out); break; - case SEXP_MACRO: - fputs("#", out); break; - case SEXP_LAMBDA: - fputs("#', out); - break; - case SEXP_SEQ: - fputs("#', out); - break; - case SEXP_CND: - fputs("#', out); - break; - case SEXP_REF: - fputs("#", sexp_ref_loc(obj)); - break; - case SEXP_SET: - fputs("#', out); - break; - case SEXP_LIT: - fputs("#', out); - break; - case SEXP_CONTEXT: - fputs("#", out); - break; - case SEXP_SYNCLO: - fputs("#', out); - break; - case SEXP_STRING: - putc('"', out); - i = sexp_string_length(obj); - str = sexp_string_data(obj); - for ( ; i>0; str++, i--) { - switch (str[0]) { - case '\\': fputs("\\\\", out); break; - case '"': fputs("\\\"", out); break; - case '\n': fputs("\\n", out); break; - case '\r': fputs("\\r", out); break; - case '\t': fputs("\\t", out); break; - default: putc(str[0], out); - } - } - putc('"', out); - break; - case SEXP_SYMBOL: - i = sexp_string_length(sexp_symbol_string(obj)); - str = sexp_string_data(sexp_symbol_string(obj)); - for ( ; i>0; str++, i--) { - if ((str[0] == '\\') || is_separator(str[0])) - putc('\\', out); - putc(str[0], out); - } - break; - default: - fprintf(out, "#", sexp_pointer_tag(obj)); - break; - } - } -} - -void sexp_show_free_list (sexp ctx) { - sexp p=sexp_free_list, prev=NULL; - fputs("free-list:", stderr); - while (p && sexp_pairp(p) && ((char*) p < sexp_heap_end)) { - if (p < prev) { - fprintf(stderr, " \x1B[31m%p-%p\x1B[0m", p, ((char*)p)+(sexp_uint_t)sexp_car(p)); - } else { - fprintf(stderr, " %p-%p", p, ((char*)p)+(sexp_uint_t)sexp_car(p)); - } - prev = (sexp) (((char*)p)+(sexp_uint_t)sexp_car(p)); - p = sexp_cdr(p); - } - putc('\n', stderr); -} - -void validate_free_list () { - sexp p=sexp_free_list, prev=NULL; - while (p && sexp_pairp(p) && ((char*) p < sexp_heap_end)) { - if (((char*)p < sexp_heap) || ((char*)p >= sexp_heap_end)) - fprintf(stderr, " \x1B[31mfree-list outside heap: %p prev: %p\x1B[0m", p, prev); - if (p < prev) - fprintf(stderr, " \x1B[31mfree-list out of order at: %p prev: %p cdr: %p\x1B[0m", p, prev, sexp_cdr(p)); - if ((sexp_uint_t)p != sexp_align((sexp_uint_t)p, 4)) - fprintf(stderr, " \x1B[31mfree-list misaligned: %p prev: %p\x1B[0m", p, prev); - prev = (sexp) (((char*)p)+(sexp_uint_t)sexp_car(p)); - p = sexp_cdr(p); - } -} - -void validate_heap (sexp ctx) { - sexp_uint_t size; - sexp p=(sexp)(sexp_heap+sexp_align(SEXP_MINIMUM_OBJECT_SIZE, 4)); - sexp q=sexp_free_list, r; - /* scan over the whole heap */ - while (((char*)p) < sexp_heap_end) { - /* find the preceding and succeeding free list pointers */ - for (r=sexp_cdr(q); r && sexp_pairp(r) && (r= 0x29e00) && ((sexp_uint_t)p <= 0x2a000)) */ - /* fprintf(stderr, "validate heap: %p (%p .. %p)\n", p, q, r); */ - size = sexp_align(sexp_allocated_bytes(p), 4); - if (sexp_pointer_tag(p) == 0) { - fprintf(stderr, "bare object found at %p\n", p); - } else if (sexp_pointer_tag(p) > SEXP_CONTEXT) { - fprintf(stderr, "bad type at %p: %d\n", p, sexp_pointer_tag(p)); - } - p = (sexp) (((char*)p)+size); - } -} - -void validate_gc_vars (sexp ctx) { - struct sexp_gc_var_t *saves, *prev=NULL; - if (! ctx) - return; - for (saves=sexp_context_saves(ctx); saves; saves=saves->next) { - if (saves->var && *(saves->var) && sexp_pointerp(*(saves->var))) { - if (((char*)*(saves->var) < sexp_heap) - || ((char*)*(saves->var) >= sexp_heap_end)) - fprintf(stderr, "bad variable in gc var: %s => %p\n", saves->name, *(saves->var)); - if ((sexp_uint_t)*(saves->var) - != sexp_align((sexp_uint_t)*(saves->var), 4)) - fprintf(stderr, "misaligned gc var: %p\n", *(saves->var)); - } - if (prev && (prev > saves)) { - fprintf(stderr, "gc vars out of order: %p > %p\n", prev, saves); - return; - } else if (prev == saves) { - fprintf(stderr, "loop in gc vars at %p\n", saves); - return; - } - prev = saves; - } -} - -int validate_freed_pointer (sexp ctx, sexp x) { - int freep = 1; +#ifdef USE_DEBUG_GC +int stack_references_pointer_p (sexp ctx, sexp x) { sexp *p; - struct sexp_gc_var_t *saves, *prev=NULL; - char *v1, *v2; - - for (p=&x; pnext) { - if (saves->var && prev && prev->var - && (((saves->var <= p) && (prev->var >= p)) - || ((saves->var >= p) && (prev->var <= p)))) { - v1 = saves->name; - v2 = prev->name; - break; - } - prev = saves; - } - if (v1 && v2) - fprintf(stderr, "reference to freed var %p at %p between %s and %s: ", - x, p, v1, v2); - else if (sexp_context_saves(ctx) && (p <= sexp_context_saves(ctx)->var)) - fprintf(stderr, "reference to freed var %p at %p after %s: ", - x, p, sexp_context_saves(ctx)->name); - else if (prev && (p >= prev->var)) - fprintf(stderr, "reference to freed var %p at %p before %s: ", - x, p, prev->name); - else - fprintf(stderr, "reference to freed var %p at %p: ", x, p); - simple_write(x, 1, stderr); - putc('\n', stderr); - freep = 0; - } - } - - return freep; + for (p=&x; pnext) { + p = (sexp) (h->data + sexp_align(sexp_sizeof(pair), 4)); + q = h->free_list; + end = (char*)h->data + h->size; + while (((char*)p) < end) { + /* find the preceding and succeeding free list pointers */ + for (r=sexp_cdr(q); r && sexp_pairp(r) && (rfree_list)) { + /* merge q with p */ + if (r && sexp_pairp(r) && ((((char*)p)+size) == (char*)r)) { + /* ... and with r */ + sexp_cdr(q) = sexp_cdr(r); + freed = (sexp_uint_t)sexp_car(q) + size + (sexp_uint_t)sexp_car(r); + p = (sexp) (((char*)p)+size+(sexp_uint_t)sexp_car(r)); + } else { + freed = (sexp_uint_t)sexp_car(q) + size; + p = (sexp) (((char*)p)+size); + } + sexp_car(q) = (sexp)freed; + } else { + if (r && sexp_pairp(r) && ((((char*)p)+size) == (char*)r)) { + sexp_car(p) = (sexp)(size+(sexp_uint_t)sexp_car(r)); + sexp_cdr(p) = sexp_cdr(r); + sexp_cdr(q) = p; + freed = size + (sexp_uint_t)sexp_car(r); + } else { + sexp_car(p) = (sexp)size; + sexp_cdr(p) = r; + sexp_cdr(q) = p; + freed = size; + } + sexp_pointer_tag(p) = SEXP_PAIR; + p = (sexp) (((char*)p)+freed); + } + if (freed > max_freed) + max_freed = freed; + } else { + sexp_gc_mark(p) = 0; + p = (sexp) (((char*)p)+size); } - if (freed > max_freed) - max_freed = freed; - } else { -/* fprintf(stderr, "\x1B[32msaving %lu bytes @ %p (%x) ", size, p, sexp_pointer_tag(p)); */ -/* simple_write(p, 1, stderr); */ -/* fprintf(stderr, "\x1B[0m\n"); */ - sexp_gc_mark(p) = 0; - p = (sexp) (((char*)p)+size); } } - fprintf(stderr, "**************** freed %ld bytes, max %ld ****************\n", sum_freed, max_freed); return sexp_make_integer(max_freed); } -extern sexp continuation_resumer, final_resumer; - sexp sexp_gc (sexp ctx) { sexp res; int i; - fprintf(stderr, "************* garbage collecting *************\n"); - /* sexp_show_free_list(ctx); */ sexp_mark(continuation_resumer); sexp_mark(final_resumer); for (i=0; inext) - if (saves->var) _adjust(*(saves->var)); - t = &(sexp_types[sexp_pointer_tag(x)]); - p = (sexp*) (((char*)x) + sexp_type_field_base(t)); - len_ptr = (sexp_uint_t*) (((char*)x) + sexp_type_field_len_off(t)); - len = sexp_type_field_len_base(t) + len_ptr[0]*sexp_type_field_len_scale(t); - for (i=0; isize = size; + h->data = (char*) sexp_align((sexp_uint_t)&(h->data), 4); + free = h->free_list = (sexp) h->data; + h->next = NULL; + next = (sexp) ((char*)free + sexp_align(sexp_sizeof(pair), 4)); + sexp_pointer_tag(free) = SEXP_PAIR; + sexp_car(free) = 0; /* actually sexp_sizeof(pair) */ + sexp_cdr(free) = next; + sexp_pointer_tag(next) = SEXP_PAIR; + sexp_car(next) = (sexp) (size - sexp_align(sexp_sizeof(pair), 4)); + sexp_cdr(next) = SEXP_NULL; } - fprintf(stderr, "************* done adjusting heap *************\n"); - for (t=(sexp*)start; t<(sexp*)end; t++) - if (*t && sexp_pointerp(*t) - && (*t > (sexp)(start-offset)) && (*t < (sexp)(end-offset))) - fprintf(stderr, "bad address at %p: %p\n", t, *t); + return h; } -void* sexp_realloc_heap (char *heap, size_t cur_size, size_t new_size) { - char *res = malloc(new_size); - memcpy(res, heap, cur_size); - return res; -} - -/* #define sexp_realloc_heap(h, cs, ns) realloc(h, ns) */ - int sexp_grow_heap (sexp ctx, size_t size) { - char *tmp1, *tmp2; - sexp q; - size_t cur_size = sexp_heap_end - sexp_heap, new_size; + size_t cur_size, new_size; + sexp_heap h; + for (h=heap; h->next; h=h->next) + ; + cur_size = h->size; new_size = sexp_align(((cur_size > size) ? cur_size : size) * 2, 4); - fprintf(stderr, "************* growing heap *************\n"); - validate_heap(ctx); - if (SEXP_MAXIMUM_HEAP_SIZE && (new_size > SEXP_MAXIMUM_HEAP_SIZE)) { - fprintf(stderr, "************* heap too large *************\n"); - return 0; - } - if (! (tmp1 = sexp_realloc_heap(sexp_heap, cur_size, new_size))) { - fprintf(stderr, "************* couldn't realloc *************\n"); - return 0; - } - if (tmp1 != sexp_heap) { - fprintf(stderr, "************* adjusting heap: %p => %p (%d) *************\n", sexp_heap, tmp1, tmp1-sexp_heap); - sexp_adjust_heap(tmp1, tmp1+cur_size, tmp1-sexp_heap, new_size); - fprintf(stderr, "************* done adjusting *************\n"); - tmp2 = sexp_heap; - sexp_heap = tmp1; - free(tmp2); - } else { - for (q = sexp_free_list; - sexp_cdr(q) && sexp_pairp(sexp_cdr(q)); - q = sexp_cdr(q)) - ; - sexp_cdr(q) = (sexp) sexp_heap_end; - q = sexp_cdr(q); - sexp_pointer_tag(q) = SEXP_PAIR; - sexp_car(q) = (sexp) (new_size - cur_size); - sexp_cdr(q) = SEXP_NULL; - } - sexp_heap_end = sexp_heap + new_size; - sexp_show_free_list(ctx); - return 1; + h->next = sexp_make_heap(new_size); + return (h->next != NULL); } void* sexp_try_alloc (sexp ctx, size_t size) { sexp ls1, ls2, ls3; - ls1 = sexp_free_list; - ls2 = sexp_cdr(ls1); - while (sexp_pairp(ls2)) { - if ((sexp_uint_t)sexp_car(ls2) >= size) { - if ((sexp_uint_t)sexp_car(ls2) >= (size + SEXP_MINIMUM_OBJECT_SIZE)) { - ls3 = (sexp) (((char*)ls2)+size); /* the free tail after ls2 */ - sexp_pointer_tag(ls3) = SEXP_PAIR; - sexp_car(ls3) = (sexp) (((sexp_uint_t)sexp_car(ls2)) - size); - sexp_cdr(ls3) = sexp_cdr(ls2); - sexp_cdr(ls1) = ls3; - } else { /* take the whole chunk */ - sexp_cdr(ls1) = sexp_cdr(ls2); + sexp_heap h; + for (h=heap; h; h=h->next) { + ls1 = h->free_list; + ls2 = sexp_cdr(ls1); + while (sexp_pairp(ls2)) { + if ((sexp_uint_t)sexp_car(ls2) >= size) { + if ((sexp_uint_t)sexp_car(ls2) >= (size + SEXP_MINIMUM_OBJECT_SIZE)) { + ls3 = (sexp) (((char*)ls2)+size); /* the free tail after ls2 */ + sexp_pointer_tag(ls3) = SEXP_PAIR; + sexp_car(ls3) = (sexp) (((sexp_uint_t)sexp_car(ls2)) - size); + sexp_cdr(ls3) = sexp_cdr(ls2); + sexp_cdr(ls1) = ls3; + } else { /* take the whole chunk */ + sexp_cdr(ls1) = sexp_cdr(ls2); + } + bzero((void*)ls2, size); + return ls2; } - bzero((void*)ls2, size); - return ls2; + ls1 = ls2; + ls2 = sexp_cdr(ls2); } - ls1 = ls2; - ls2 = sexp_cdr(ls2); } return NULL; } void* sexp_alloc (sexp ctx, size_t size) { void *res; -/* validate_heap(ctx); */ -/* validate_free_list(ctx); */ -/* validate_gc_vars(ctx); */ size = sexp_align(size, 4); res = sexp_try_alloc(ctx, size); if (! res) { @@ -590,25 +214,12 @@ void* sexp_alloc (sexp ctx, size_t size) { exit(70); } } - /* fprintf(stderr, "sexp_alloc %lu => %p\n", size, res); */ return res; } void sexp_gc_init () { sexp_uint_t size = sexp_align(SEXP_INITIAL_HEAP_SIZE, 4); - sexp next; - sexp_heap = malloc(size); - sexp_heap_end = sexp_heap + size; - sexp_free_list = (sexp)sexp_heap; - next = (sexp) (sexp_heap + sexp_align(sexp_sizeof(pair), 4)); - sexp_pointer_tag(sexp_free_list) = SEXP_PAIR; - sexp_car(sexp_free_list) = 0; /* actually sexp_sizeof(pair) */ - sexp_cdr(sexp_free_list) = next; - sexp_pointer_tag(next) = SEXP_PAIR; - sexp_car(next) = (sexp) (size - sexp_align(sexp_sizeof(pair), 4)); - sexp_cdr(next) = SEXP_NULL; - stack_base = &next + 32; - fprintf(stderr, "heap: %p - %p, next: %p, stack_base: %p\n", - sexp_heap, sexp_heap_end, next, stack_base); + heap = sexp_make_heap(size); + stack_base = ((sexp*)&size) + 32; } diff --git a/sexp.c b/sexp.c index cc4244d9..79269495 100644 --- a/sexp.c +++ b/sexp.c @@ -84,7 +84,7 @@ static struct sexp_struct sexp_types[] = { _TYPE(SEXP_SET, sexp_offsetof(set, var), 2, 0, 0, sexp_sizeof(set), 0, 0, "set!"), _TYPE(SEXP_SEQ, sexp_offsetof(seq, ls), 1, 0, 0, sexp_sizeof(seq), 0, 0, "sequence"), _TYPE(SEXP_LIT, sexp_offsetof(lit, value), 1, 0, 0, sexp_sizeof(lit), 0, 0, "literal"), - _TYPE(SEXP_STACK, sexp_offsetof(stack, data), 0, sexp_offsetof(stack, top), 1, sexp_sizeof(stack), offsetof(struct sexp_struct, value.stack.length), 4, "stack"), + _TYPE(SEXP_STACK, sexp_offsetof(stack, data), 1, sexp_offsetof(stack, top), 1, sexp_sizeof(stack), offsetof(struct sexp_struct, value.stack.length), 4, "stack"), _TYPE(SEXP_CONTEXT, sexp_offsetof(context, bc), 6, 0, 0, sexp_sizeof(context), 0, 0, "context"), }; diff --git a/sexp.h b/sexp.h index 620f860c..bded73f8 100644 --- a/sexp.h +++ b/sexp.h @@ -224,8 +224,8 @@ struct sexp_struct { #else -#define sexp_gc_var(ctx, x, y) \ - sexp x = SEXP_VOID; \ +#define sexp_gc_var(ctx, x, y) \ + sexp x = SEXP_VOID; \ struct sexp_gc_var_t y = {NULL, NULL}; #define sexp_gc_preserve(ctx, x, y) \ @@ -255,21 +255,6 @@ void *sexp_realloc(sexp ctx, sexp x, size_t size); #endif #endif -#define sexp_with_gc_var1(ctx, x, body) \ - sexp_gc_var(ctx, x, _sexp_gcv1); \ - sexp_gc_preserve(ctx, x, _sexp_gcv1); \ - do {body} while (0); \ - sexp_gc_release(ctx, x, _sexp_gcv1); - -#define sexp_with_gc_var2(ctx, x, y, body) \ - sexp_gc_var(ctx, x, _sexp_gcv1); \ - sexp_gc_var(ctx, y, _sexp_gcv2); \ - sexp_gc_preserve(ctx, x, _sexp_gcv1); \ - sexp_gc_preserve(ctx, y, _sexp_gcv2); \ - do {body} while (0); \ - sexp_gc_release(ctx, x, _sexp_gcv1); \ - sexp_gc_release(ctx, y, _sexp_gcv2); - #define sexp_align(n, bits) (((n)+(1<<(bits))-1)&(((sexp_uint_t)-1)-((1<<(bits))-1))) #define sexp_sizeof(x) (offsetof(struct sexp_struct, value) \