diff --git a/regression/Makefile b/regression/Makefile index 0fc4b3f96..384fefd72 100644 --- a/regression/Makefile +++ b/regression/Makefile @@ -12,4 +12,7 @@ $(TESTS): %: %.expr @cat $@.input | $(RC) -s $< > $@.log && diff $@.log orig/$@.log clean: - rm -f test*.log *.s *~ $(TESTS) + $(RM) test*.log *.s *~ $(TESTS) + $(MAKE) clean -C expressions + $(MAKE) clean -C deep-expressions + $(MAKE) clean -C x86only diff --git a/regression/deep-expressions/Makefile b/regression/deep-expressions/Makefile index fe0e5468b..e46f56420 100644 --- a/regression/deep-expressions/Makefile +++ b/regression/deep-expressions/Makefile @@ -12,4 +12,5 @@ $(TESTS): %: %.expr @cat $@.input | $(RC) -s $< > $@.log && diff $@.log orig/$@.log clean: - rm -f *.log *.s *~ $(TESTS) + rm -f *.log *.s *~ + find . -maxdepth 1 -type f -not -name '*.*' -not -name 'Makefile' -delete diff --git a/regression/expressions/Makefile b/regression/expressions/Makefile index fe0e5468b..3b2afb53a 100644 --- a/regression/expressions/Makefile +++ b/regression/expressions/Makefile @@ -12,4 +12,6 @@ $(TESTS): %: %.expr @cat $@.input | $(RC) -s $< > $@.log && diff $@.log orig/$@.log clean: - rm -f *.log *.s *~ $(TESTS) + rm -f *.log *.s *~ + find . -maxdepth 1 -type f -not -name '*.*' -not -name 'Makefile' -delete + diff --git a/regression/test039.expr b/regression/test039.expr index 1eaff0a70..1075d8de7 100644 --- a/regression/test039.expr +++ b/regression/test039.expr @@ -28,4 +28,3 @@ write (find (t, 6)); write (find (t, 3)); write (find (t, 2)); write (find (t, 1)) - diff --git a/runtime/Makefile b/runtime/Makefile index c4414a5c8..457906978 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -1,6 +1,12 @@ -all: - gcc -m32 -c runtime.c +all: gc_runtime.o runtime.o + ar rc runtime.a gc_runtime.o runtime.o + +gc_runtime.o: gc_runtime.s + gcc -g -fstack-protector-all -m32 -c gc_runtime.s + +runtime.o: runtime.c + gcc -g -fstack-protector-all -m32 -c runtime.c clean: - rm -f runtime.o *~ + rm -f *.a *.o *~ diff --git a/runtime/gc_runtime.s b/runtime/gc_runtime.s new file mode 100644 index 000000000..e10fcc71b --- /dev/null +++ b/runtime/gc_runtime.s @@ -0,0 +1,114 @@ + .data +printf_format: .string "Stack root: %lx\n" +printf_format2: .string "BOT: %lx\n" +printf_format3: .string "TOP: %lx\n" +printf_format4: .string "EAX: %lx\n" +printf_format5: .string "LOL\n" +__gc_stack_bottom: .long 0 +__gc_stack_top: .long 0 + + .globl __pre_gc + .globl __post_gc + .globl L__gc_init + .globl __gc_root_scan_stack + .extern init_pool + .extern gc_test_and_copy_root + .text + +L__gc_init: movl %esp, __gc_stack_bottom + addl $4, __gc_stack_bottom + call init_pool + ret + + // if __gc_stack_top is equal to 0 + // then set __gc_stack_top to %ebp + // else return +__pre_gc: + pushl %eax + movl __gc_stack_top, %eax + cmpl $0, %eax + jne __pre_gc_2 + movl %ebp, %eax + // addl $8, %eax + movl %eax, __gc_stack_top +__pre_gc_2: + popl %eax + ret + + // if __gc_stack_top has been set by the caller + // (i.e. it is equal to its %ebp) + // then set __gc_stack_top to 0 + // else return +__post_gc: + pushl %eax + movl __gc_stack_top, %eax + cmpl %eax, %ebp + jnz __post_gc2 + movl $0, __gc_stack_top +__post_gc2: + popl %eax + ret + + // Scan stack for roots + // strting from __gc_stack_top + // till __gc_stack_bottom +__gc_root_scan_stack: + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %edx + movl __gc_stack_top, %eax + jmp next + +loop: + movl (%eax), %ebx + + // check that it is not a pointer to code section + // i.e. the following is not true: + // __executable_start <= (%eax) <= __etext +check11: + leal __executable_start, %edx + cmpl %ebx, %edx + jna check12 + jmp check21 + +check12: + leal __etext, %edx + cmpl %ebx, %edx + jnb next + + // check that it is not a pointer into the program stack + // i.e. the following is not true: + // __gc_stack_bottom <= (%eax) <= __gc_stack_top +check21: + cmpl %ebx, __gc_stack_top + jna check22 + jmp loop2 + +check22: + cmpl %ebx, __gc_stack_bottom + jnb next + + // check if it a valid pointer + // i.e. the lastest bit is set to zero +loop2: + andl $0x00000001, %ebx + jnz next +gc_run_t: + pushl %eax + pushl %eax + call gc_test_and_copy_root + addl $4, %esp + popl %eax + +next: + addl $4, %eax + cmpl %eax, __gc_stack_bottom + jne loop +returnn: + movl $0, %eax + popl %edx + popl %ebx + movl %ebp, %esp + popl %ebp + ret diff --git a/runtime/runtime.c b/runtime/runtime.c index c4a110dad..7e379befe 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -2,18 +2,20 @@ # include # include -# include # include # include -# include # include +# include +# include -# define STRING_TAG 0x00000000 -# define ARRAY_TAG 0x01000000 -# define SEXP_TAG 0x02000000 +// # define DEBUG_PRINT 1 -# define LEN(x) (x & 0x00FFFFFF) -# define TAG(x) (x & 0xFF000000) +# define STRING_TAG 0x00000001 +# define ARRAY_TAG 0x00000003 +# define SEXP_TAG 0x00000005 + +# define LEN(x) ((x & 0xFFFFFFF8) >> 3) +# define TAG(x) (x & 0x00000007) # define TO_DATA(x) ((data*)((char*)(x)-sizeof(int))) # define TO_SEXP(x) ((sexp*)((char*)(x)-2*sizeof(int))) @@ -32,22 +34,31 @@ typedef struct { data contents; } sexp; +extern void* alloc (size_t); + extern int Blength (void *p) { - data *a = TO_DATA(p); + data *a = (char*) BOX (NULL); + a = TO_DATA(p); return BOX(LEN(a->tag)); } char* de_hash (int n) { - static char *chars = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNJPQRSTUVWXYZ"; - static char buf[6]; - char *p = &buf[5]; + static char *chars = (char*) BOX (NULL); + static char buf[6] = {0,0,0,0,0,0}; + char *p = (char*) BOX (NULL); + chars = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNJPQRSTUVWXYZ"; + p = &buf[5]; - /*printf ("tag: %d\n", n);*/ +#ifdef DEBUG_PRINT + printf ("de_hash: tag: %d\n", n); +#endif *p-- = 0; while (n != 0) { - /*printf ("char: %c\n", chars [n & 0x003F]);*/ +#ifdef DEBUG_PRINT + printf ("char: %c\n", chars [n & 0x003F]); +#endif *p-- = chars [n & 0x003F]; n = n >> 6; } @@ -83,9 +94,10 @@ static void extendStringBuf () { } static void printStringBuf (char *fmt, ...) { - va_list args; - int written, rest; - char *buf; + va_list args = (va_list) BOX(NULL); + int written = 0, + rest = 0; + char *buf = (char*) BOX(NULL); again: va_start (args, fmt); @@ -102,9 +114,11 @@ static void printStringBuf (char *fmt, ...) { } static void printValue (void *p) { + data *a = (data*) BOX(NULL); + int i = BOX(0); if (UNBOXED(p)) printStringBuf ("%d", UNBOX(p)); else { - data *a = TO_DATA(p); + a = TO_DATA(p); switch (TAG(a->tag)) { case STRING_TAG: @@ -113,7 +127,7 @@ static void printValue (void *p) { case ARRAY_TAG: printStringBuf ("["); - for (int i = 0; i < LEN(a->tag); i++) { + for (i = 0; i < LEN(a->tag); i++) { printValue ((void*)((int*) a->contents)[i]); if (i != LEN(a->tag) - 1) printStringBuf (", "); } @@ -124,7 +138,7 @@ static void printValue (void *p) { printStringBuf ("`%s", de_hash (TO_SEXP(p)->tag)); if (LEN(a->tag)) { printStringBuf (" ("); - for (int i = 0; i < LEN(a->tag); i++) { + for (i = 0; i < LEN(a->tag); i++) { printValue ((void*)((int*) a->contents)[i]); if (i != LEN(a->tag) - 1) printStringBuf (", "); } @@ -139,11 +153,10 @@ static void printValue (void *p) { } extern void* Belem (void *p, int i) { - data *a = TO_DATA(p); + data *a = (data *)BOX(NULL); + a = TO_DATA(p); i = UNBOX(i); - /* printf ("elem %d = %p\n", i, (void*) ((int*) a->contents)[i]); */ - if (TAG(a->tag) == STRING_TAG) { return (void*) BOX(a->contents[i]); } @@ -152,17 +165,26 @@ extern void* Belem (void *p, int i) { } extern void* Bstring (void *p) { - int n = strlen (p); - data *r = (data*) malloc (n + 1 + sizeof (int)); + int n = BOX(0); + data *r = NULL; - r->tag = n; + __pre_gc () ; + + n = strlen (p); + r = (data*) alloc (n + 1 + sizeof (int)); + + r->tag = STRING_TAG | (n << 3); strncpy (r->contents, p, n + 1); + + __post_gc(); return r->contents; } extern void* Bstringval (void *p) { - void *s; + void *s = BOX(NULL); + + __pre_gc () ; createStringBuf (); printValue (p); @@ -171,70 +193,98 @@ extern void* Bstringval (void *p) { deleteStringBuf (); + __post_gc (); + return s; } extern void* Barray (int n, ...) { - va_list args; - int i; - data *r = (data*) malloc (sizeof(int) * (n+1)); + va_list args = (va_list) BOX (NULL); + int i = BOX(0), + ai = BOX(0); + data *r = (data*) BOX (NULL); - r->tag = ARRAY_TAG | n; + __pre_gc (); + +#ifdef DEBUG_PRINT + printf ("Barray: create n = %d\n", n); + fflush(stdout); +#endif + r = (data*) alloc (sizeof(int) * (n+1)); + + r->tag = ARRAY_TAG | (n << 3); va_start(args, n); - for (i=0; icontents)[i] = ai; } va_end(args); + __post_gc(); + return r->contents; } extern void* Bsexp (int n, ...) { - va_list args; - int i; - sexp *r = (sexp*) malloc (sizeof(int) * (n+2)); - data *d = &(r->contents); + va_list args = (va_list) BOX (NULL); + int i = BOX(0); + int ai = BOX(0); + size_t * p = NULL; + sexp *r = (sexp*) BOX (NULL); + data *d = (sexp*) BOX (NULL); - d->tag = SEXP_TAG | (n-1); + __pre_gc () ; + +#ifdef DEBUG_PRINT + printf("Bsexp: allocate %zu!\n",sizeof(int) * (n+1)); +#endif + r = (sexp*) alloc (sizeof(int) * (n+1)); + d = &(r->contents); + r->tag = 0; + + d->tag = SEXP_TAG | ((n-1) << 3); va_start(args, n); for (i=0; icontents)[i] = ai; + ai = va_arg(args, int); + + p = (size_t*) ai; + ((int*)d->contents)[i] = ai; } r->tag = va_arg(args, int); va_end(args); - //printf ("tag %d\n", r->tag); - //printf ("returning %p\n", d->contents); - + __post_gc(); + return d->contents; } extern int Btag (void *d, int t, int n) { - data *r = TO_DATA(d); + data *r = (data*) BOX (NULL); + r = TO_DATA(d); return BOX(TAG(r->tag) == SEXP_TAG && TO_SEXP(d)->tag == t && LEN(r->tag) == n); } extern int Barray_patt (void *d, int n) { + data *r = BOX(NULL); if (UNBOXED(d)) return BOX(0); else { - data *r = TO_DATA(d); + r = TO_DATA(d); return BOX(TAG(r->tag) == ARRAY_TAG && LEN(r->tag) == n); } } extern int Bstring_patt (void *x, void *y) { + data *rx = (data *) BOX (NULL), + *ry = (data *) BOX (NULL); if (UNBOXED(x)) return BOX(0); else { - data *rx = TO_DATA(x), *ry = TO_DATA(y); + rx = TO_DATA(x); ry = TO_DATA(y); if (TAG(rx->tag) != STRING_TAG) return BOX(0); @@ -269,13 +319,13 @@ extern int Bsexp_tag_patt (void *x) { } extern void Bsta (int n, int v, void *s, ...) { - va_list args; - int i, k; - data *a; + va_list args = (va_list) BOX (NULL); + int i = 0, k = 0; + data *a = (data*) BOX (NULL); va_start(args, s); - for (i=0; i printf (char *, ...) @@ -300,21 +350,29 @@ extern void Lprintf (char *s, ...) { } extern void* Lstrcat (void *a, void *b) { - data *da = TO_DATA(a); - data *db = TO_DATA(b); + data *da = (data*) BOX (NULL); + data *db = (data*) BOX (NULL); + data *d = (data*) BOX (NULL); + + da = TO_DATA(a); + db = TO_DATA(b); + + __pre_gc () ; - data *d = (data *) malloc (sizeof(int) + LEN(da->tag) + LEN(db->tag) + 1); + d = (data *) alloc (sizeof(int) + LEN(da->tag) + LEN(db->tag) + 1); d->tag = LEN(da->tag) + LEN(db->tag); strcpy (d->contents, da->contents); strcat (d->contents, db->contents); + __post_gc(); + return d->contents; } extern void Lfprintf (FILE *f, char *s, ...) { - va_list args; + va_list args = (va_list) BOX (NULL); va_start (args, s); vfprintf (f, s, args); @@ -331,7 +389,7 @@ extern void Lfclose (FILE *f) { /* Lread is an implementation of the "read" construct */ extern int Lread () { - int result; + int result = BOX(0); printf ("> "); fflush (stdout); @@ -348,3 +406,290 @@ extern int Lwrite (int n) { return 0; } +/* GC starts here */ + +extern const size_t __gc_data_end, __gc_data_start; + +extern void L__gc_init (); +extern void __pre_gc (); +extern void __post_gc (); + +extern void __gc_root_scan_stack (); + +/* ======================================== */ +/* Mark-and-copy */ +/* ======================================== */ + +static size_t SPACE_SIZE = 128; +# define POOL_SIZE (2*SPACE_SIZE) + +typedef struct { + size_t * begin; + size_t * end; + size_t * current; + size_t size; +} pool; + +static pool from_space; +static pool to_space; +size_t * current; + +static void swap (size_t ** a, size_t ** b) { + size_t * t = *a; + *a = *b; + *b = t; +} + +static void gc_swap_spaces (void) { + swap (&from_space.begin, &to_space.begin); + swap (&from_space.end , &to_space.end ); + from_space.current = current; + to_space.current = to_space.begin; +} + +# define IS_VALID_HEAP_POINTER(p)\ + (!UNBOXED(p) && \ + from_space.begin <= p && \ + from_space.end > p) + +# define IN_PASSIVE_SPACE(p) \ + (to_space.begin <= p && \ + to_space.end > p) + +# define IS_FORWARD_PTR(p) \ + (!UNBOXED(p) && IN_PASSIVE_SPACE(p)) + +extern size_t * gc_copy (size_t *obj); + +static void copy_elements (size_t *where, size_t *from, int len) { + int i = 0; + void * p = NULL; + for (i = 0; i < len; i++) { + size_t elem = from[i]; + if (!IS_VALID_HEAP_POINTER(elem)) { + *where = elem; + where++; + } + else { + p = gc_copy ((size_t*) elem); + *where = p; +#ifdef DEBUG_PRINT + printf ("copy_elements: fix %x: %x\n", from, *where); +#endif + where ++; + } + } +} + +static void extend_spaces (void) { + void *p1 = mremap(from_space.begin, SPACE_SIZE, 2*SPACE_SIZE, 0); + void *p2 = mremap(to_space.begin , SPACE_SIZE, 2*SPACE_SIZE, 0); + if (p1 == MAP_FAILED || p2 == MAP_FAILED) { + perror("EROOR: extend_spaces: mmap failed\n"); + exit (1); + } +#ifdef DEBUG_PRINT + printf ("extend: %x %x %x %x\n", p1, p2, from_space.begin, to_space.begin); + printf ("extend: %x %x %x\n", from_space.end, to_space.end, current); +#endif + from_space.end += SPACE_SIZE; + to_space.end += SPACE_SIZE; + SPACE_SIZE += SPACE_SIZE; + from_space.size = SPACE_SIZE; + to_space.size = SPACE_SIZE; +} + +extern size_t * gc_copy (size_t *obj) { + data *d = TO_DATA(obj); + sexp *s = NULL; + size_t *copy = NULL; + int i = 0; +#ifdef DEBUG_PRINT + int len1, len2, len3; + void * objj; + void * newobjj = (void*)current; + printf("gc_copy: %x cur = %x starts\n", obj, current); +#endif + + if (!IS_VALID_HEAP_POINTER(obj)) { +#ifdef DEBUG_PRINT + printf ("gc_copy: invalid ptr: %x\n", obj); +#endif + return obj; + } + + if (!IN_PASSIVE_SPACE(current) && current != to_space.end) { +#ifdef DEBUG_PRINT + printf("ERROR: gc_copy: out-of-space %x %x %x\n", current, to_space.begin, to_space.end); + fflush(stdout); +#endif + perror("ERROR: gc_copy: out-of-space\n"); + exit (1); + } + + if (IS_FORWARD_PTR(d->tag)) { +#ifdef DEBUG_PRINT + printf ("gc_copy: IS_FORWARD_PTR: return! %x\n", (size_t *) d->tag); + fflush(stdout); +#endif + return (size_t *) d->tag; + } + + copy = current; +#ifdef DEBUG_PRINT + objj = d; +#endif + switch (TAG(d->tag)) { + case ARRAY_TAG: +#ifdef DEBUG_PRINT + printf ("gc_copy:array_tag; len = %zu\n", LEN(d->tag)); + fflush(stdout); +#endif + current += (LEN(d->tag) + 1) * sizeof (int); + *copy = d->tag; + copy++; + i = LEN(d->tag); + d->tag = (int) copy; + copy_elements (copy, obj, i); + break; + + case STRING_TAG: +#ifdef DEBUG_PRINT + printf ("gc_copy:string_tag; len = %d\n", LEN(d->tag) + 1); + fflush(stdout); +#endif + current += LEN(d->tag) * sizeof(char) + sizeof (int); + *copy = d->tag; + copy++; + d->tag = (int) copy; + strcpy (©[0], (char*) obj); + break; + + case SEXP_TAG : + s = TO_SEXP(obj); +#ifdef DEBUG_PRINT + objj = s; + len1 = LEN(s->contents.tag); + len2 = LEN(s->tag); + len3 = LEN(d->tag); + printf("len1 = %li, len2=%li, len3 = %li\n",len1,len2,len3); +#endif + current += (LEN(s->contents.tag) + 2) * sizeof (int); + *copy = s->tag; + copy++; + *copy = s->contents.tag; + copy++; + i = LEN(s->contents.tag); + d->tag = (int) copy; + copy_elements (copy, obj, i); + break; + + default: +#ifdef DEBUG_PRINT + printf ("ERROR: gc_copy: weird tag: %x", TAG(d->tag)); + fflush(stdout); +#endif + perror ("ERROR: gc_copy: weird tag"); + exit (1); + } +#ifdef DEBUG_PRINT + printf("gc_copy: %x (%x) -> %x (%x); new-current = %x\n", obj, objj, copy, newobjj, current); + fflush(stdout); +#endif + return copy; +} + +extern void gc_test_and_copy_root (size_t ** root) { + if (IS_VALID_HEAP_POINTER(*root)) { +#ifdef DEBUG_PRINT + printf ("gc_test_and_copy_root: root %x %x\n", root, *root); +#endif + *root = gc_copy (*root); + } +} + +extern void gc_root_scan_data (void) { + size_t * p = &__gc_data_start; + while (p != &__gc_data_end) { + gc_test_and_copy_root (p); + p++; + } +} + +extern void init_pool (void) { + from_space.begin = mmap(NULL, SPACE_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); + to_space.begin = mmap(NULL, SPACE_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); + if (to_space.begin == MAP_FAILED || + from_space.begin == MAP_FAILED) { + perror("EROOR: init_pool: mmap failed\n"); + exit (1); + } + from_space.current = from_space.begin; + from_space.end = from_space.begin + SPACE_SIZE; + from_space.size = SPACE_SIZE; + to_space.current = to_space.begin; + to_space.end = to_space.begin + SPACE_SIZE; + to_space.size = SPACE_SIZE; +} + +static int free_pool (pool * p) { + return munmap((void *)p->begin, p->size); +} + +static void * gc (size_t size) { + current = to_space.begin; +#ifdef DEBUG_PRINT + printf("\ngc: current: %x; to_space.b = %x; to_space.e = %x; f_space.b = %x; f_space.e = %x\n", + current, to_space.begin, to_space.end, from_space.begin, from_space.end); +#endif + gc_root_scan_data (); +#ifdef DEBUG_PRINT + printf("gc: data is scanned\n"); +#endif + __gc_root_scan_stack (); + if (!IN_PASSIVE_SPACE(current)) { + perror ("ASSERT: !IN_PASSIVE_SPACE(current)\n"); + exit (1); + } + + while (current + size >= to_space.end) { +#ifdef DEBUG_PRINT + printf ("gc pre-extend_spaces : %x %x %x \n", current, size, to_space.end); +#endif + extend_spaces (); +#ifdef DEBUG_PRINT + printf ("gc post-extend_spaces: %x %x %x \n", current, size, to_space.end); +#endif + } + assert (IN_PASSIVE_SPACE(current)); + assert (current + size < to_space.end); + + gc_swap_spaces (); + from_space.current = current + size; +#ifdef DEBUG_PRINT + printf ("gc: end: (allocate!) return %x; from_space.current %x; from_space.end \n\n", + current, from_space.current, from_space.end); +#endif + return (void *) current; +} + +extern void * alloc (size_t size) { + void * p = (void*)BOX(NULL); + if (from_space.current + size < from_space.end) { +#ifdef DEBUG_PRINT + printf("alloc: current: %x %zu", from_space.current, size); +#endif + p = (void*) from_space.current; + from_space.current += size; +#ifdef DEBUG_PRINT + printf(";new current: %x \n", from_space.current); +#endif + return p; + } +#ifdef DEBUG_PRINT + printf("alloc: call gc: %zu\n", size); +#endif + return gc (size); +} diff --git a/runtime/runtime.s b/runtime/runtime.s new file mode 100644 index 000000000..8181e2ecf --- /dev/null +++ b/runtime/runtime.s @@ -0,0 +1,1640 @@ + .file "runtime.c" + .text + .globl Blength + .type Blength, @function +Blength: +.LFB6: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + subl $4, %eax + movl %eax, -4(%ebp) + movl -4(%ebp), %eax + movl (%eax), %eax + addl %eax, %eax + andl $33554430, %eax + orl $1, %eax + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE6: + .size Blength, .-Blength + .globl de_hash + .type de_hash, @function +de_hash: +.LFB7: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $16, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + leal 5+buf.3077@GOTOFF(%eax), %edx + movl %edx, -8(%ebp) + movl -8(%ebp), %edx + leal -1(%edx), %ecx + movl %ecx, -8(%ebp) + movb $0, (%edx) + jmp .L4 +.L5: + movl chars.3076@GOTOFF(%eax), %edx + movl 8(%ebp), %ecx + andl $63, %ecx + leal (%edx,%ecx), %ebx + movl -8(%ebp), %edx + leal -1(%edx), %ecx + movl %ecx, -8(%ebp) + movzbl (%ebx), %ecx + movb %cl, (%edx) + sarl $6, 8(%ebp) +.L4: + cmpl $0, 8(%ebp) + jne .L5 + addl $1, -8(%ebp) + movl -8(%ebp), %eax + addl $16, %esp + popl %ebx + .cfi_restore 3 + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE7: + .size de_hash, .-de_hash + .local stringBuf + .comm stringBuf,12,4 + .type createStringBuf, @function +createStringBuf: +.LFB8: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $4, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + subl $12, %esp + pushl $128 + call malloc@PLT + addl $16, %esp + movl %eax, stringBuf@GOTOFF(%ebx) + movl $0, 4+stringBuf@GOTOFF(%ebx) + movl $128, 8+stringBuf@GOTOFF(%ebx) + nop + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE8: + .size createStringBuf, .-createStringBuf + .type deleteStringBuf, @function +deleteStringBuf: +.LFB9: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $4, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl stringBuf@GOTOFF(%eax), %edx + subl $12, %esp + pushl %edx + movl %eax, %ebx + call free@PLT + addl $16, %esp + nop + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE9: + .size deleteStringBuf, .-deleteStringBuf + .type extendStringBuf, @function +extendStringBuf: +.LFB10: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8+stringBuf@GOTOFF(%ebx), %eax + addl %eax, %eax + movl %eax, -12(%ebp) + movl -12(%ebp), %edx + movl stringBuf@GOTOFF(%ebx), %eax + subl $8, %esp + pushl %edx + pushl %eax + call realloc@PLT + addl $16, %esp + movl %eax, stringBuf@GOTOFF(%ebx) + movl -12(%ebp), %eax + movl %eax, 8+stringBuf@GOTOFF(%ebx) + nop + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE10: + .size extendStringBuf, .-extendStringBuf + .type printStringBuf, @function +printStringBuf: +.LFB11: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $52, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8(%ebp), %eax + movl %eax, -44(%ebp) + movl %gs:20, %eax + movl %eax, -12(%ebp) + xorl %eax, %eax +.L11: + leal 12(%ebp), %eax + movl %eax, -28(%ebp) + movl stringBuf@GOTOFF(%ebx), %eax + movl 4+stringBuf@GOTOFF(%ebx), %edx + addl %edx, %eax + movl %eax, -24(%ebp) + movl 8+stringBuf@GOTOFF(%ebx), %edx + movl 4+stringBuf@GOTOFF(%ebx), %eax + subl %eax, %edx + movl %edx, %eax + movl %eax, -20(%ebp) + movl -28(%ebp), %edx + movl -20(%ebp), %eax + pushl %edx + pushl -44(%ebp) + pushl %eax + pushl -24(%ebp) + call vsnprintf@PLT + addl $16, %esp + movl %eax, -16(%ebp) + movl -16(%ebp), %eax + cmpl -20(%ebp), %eax + jl .L12 + call extendStringBuf + jmp .L11 +.L12: + movl 4+stringBuf@GOTOFF(%ebx), %edx + movl -16(%ebp), %eax + addl %edx, %eax + movl %eax, 4+stringBuf@GOTOFF(%ebx) + nop + movl -12(%ebp), %eax + xorl %gs:20, %eax + je .L13 + call __stack_chk_fail_local +.L13: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE11: + .size printStringBuf, .-printStringBuf + .section .rodata +.LC0: + .string "%d" +.LC1: + .string "\"%s\"" +.LC2: + .string "[" +.LC3: + .string ", " +.LC4: + .string "]" +.LC5: + .string "`%s" +.LC6: + .string " (" +.LC7: + .string ")" +.LC8: + .string "*** invalid tag: %x ***" + .text + .type printValue, @function +printValue: +.LFB12: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8(%ebp), %eax + andl $1, %eax + testl %eax, %eax + je .L15 + movl 8(%ebp), %eax + sarl %eax + subl $8, %esp + pushl %eax + leal .LC0@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + jmp .L28 +.L15: + movl 8(%ebp), %eax + subl $4, %eax + movl %eax, -12(%ebp) + movl -12(%ebp), %eax + movl (%eax), %eax + andl $-16777216, %eax + cmpl $16777216, %eax + je .L17 + cmpl $33554432, %eax + je .L18 + testl %eax, %eax + jne .L19 + movl -12(%ebp), %eax + addl $4, %eax + subl $8, %esp + pushl %eax + leal .LC1@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + jmp .L16 +.L17: + subl $12, %esp + leal .LC2@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + movl $0, -20(%ebp) + jmp .L20 +.L22: + movl -12(%ebp), %eax + leal 4(%eax), %edx + movl -20(%ebp), %eax + sall $2, %eax + addl %edx, %eax + movl (%eax), %eax + subl $12, %esp + pushl %eax + call printValue + addl $16, %esp + movl -12(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + subl $1, %eax + cmpl %eax, -20(%ebp) + je .L21 + subl $12, %esp + leal .LC3@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp +.L21: + addl $1, -20(%ebp) +.L20: + movl -12(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + cmpl %eax, -20(%ebp) + jl .L22 + subl $12, %esp + leal .LC4@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + jmp .L16 +.L18: + movl 8(%ebp), %eax + subl $8, %eax + movl (%eax), %eax + subl $12, %esp + pushl %eax + call de_hash + addl $16, %esp + subl $8, %esp + pushl %eax + leal .LC5@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + movl -12(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + testl %eax, %eax + je .L27 + subl $12, %esp + leal .LC6@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + movl $0, -16(%ebp) + jmp .L24 +.L26: + movl -12(%ebp), %eax + leal 4(%eax), %edx + movl -16(%ebp), %eax + sall $2, %eax + addl %edx, %eax + movl (%eax), %eax + subl $12, %esp + pushl %eax + call printValue + addl $16, %esp + movl -12(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + subl $1, %eax + cmpl %eax, -16(%ebp) + je .L25 + subl $12, %esp + leal .LC3@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp +.L25: + addl $1, -16(%ebp) +.L24: + movl -12(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + cmpl %eax, -16(%ebp) + jl .L26 + subl $12, %esp + leal .LC7@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + jmp .L27 +.L19: + movl -12(%ebp), %eax + movl (%eax), %eax + andl $-16777216, %eax + subl $8, %esp + pushl %eax + leal .LC8@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + jmp .L28 +.L27: + nop +.L16: +.L28: + nop + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE12: + .size printValue, .-printValue + .globl Belem + .type Belem, @function +Belem: +.LFB13: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + subl $4, %eax + movl %eax, -4(%ebp) + sarl 12(%ebp) + movl -4(%ebp), %eax + movl (%eax), %eax + andl $-16777216, %eax + testl %eax, %eax + jne .L30 + movl -4(%ebp), %edx + movl 12(%ebp), %eax + addl %edx, %eax + addl $4, %eax + movzbl (%eax), %eax + movsbl %al, %eax + addl %eax, %eax + orl $1, %eax + jmp .L31 +.L30: + movl -4(%ebp), %eax + leal 4(%eax), %edx + movl 12(%ebp), %eax + sall $2, %eax + addl %edx, %eax + movl (%eax), %eax +.L31: + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE13: + .size Belem, .-Belem + .globl Bstring + .type Bstring, @function +Bstring: +.LFB14: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + subl $12, %esp + pushl 8(%ebp) + call strlen@PLT + addl $16, %esp + movl %eax, -16(%ebp) + movl -16(%ebp), %eax + addl $5, %eax + subl $12, %esp + pushl %eax + call malloc@PLT + addl $16, %esp + movl %eax, -12(%ebp) + movl -12(%ebp), %eax + movl -16(%ebp), %edx + movl %edx, (%eax) + movl -16(%ebp), %eax + addl $1, %eax + movl %eax, %edx + movl -12(%ebp), %eax + addl $4, %eax + subl $4, %esp + pushl %edx + pushl 8(%ebp) + pushl %eax + call strncpy@PLT + addl $16, %esp + movl -12(%ebp), %eax + addl $4, %eax + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE14: + .size Bstring, .-Bstring + .globl Bstringval + .type Bstringval, @function +Bstringval: +.LFB15: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + call createStringBuf + subl $12, %esp + pushl 8(%ebp) + call printValue + addl $16, %esp + movl stringBuf@GOTOFF(%ebx), %eax + subl $12, %esp + pushl %eax + call Bstring + addl $16, %esp + movl %eax, -12(%ebp) + call deleteStringBuf + movl -12(%ebp), %eax + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE15: + .size Bstringval, .-Bstringval + .globl Barray + .type Barray, @function +Barray: +.LFB16: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $36, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl %gs:20, %ecx + movl %ecx, -12(%ebp) + xorl %ecx, %ecx + movl 8(%ebp), %edx + addl $1, %edx + sall $2, %edx + subl $12, %esp + pushl %edx + movl %eax, %ebx + call malloc@PLT + addl $16, %esp + movl %eax, -20(%ebp) + movl 8(%ebp), %eax + orl $16777216, %eax + movl %eax, %edx + movl -20(%ebp), %eax + movl %edx, (%eax) + leal 12(%ebp), %eax + movl %eax, -28(%ebp) + movl $0, -24(%ebp) + jmp .L37 +.L38: + movl -28(%ebp), %eax + leal 4(%eax), %edx + movl %edx, -28(%ebp) + movl (%eax), %eax + movl %eax, -16(%ebp) + movl -20(%ebp), %eax + leal 4(%eax), %edx + movl -24(%ebp), %eax + sall $2, %eax + addl %eax, %edx + movl -16(%ebp), %eax + movl %eax, (%edx) + addl $1, -24(%ebp) +.L37: + movl -24(%ebp), %eax + cmpl 8(%ebp), %eax + jl .L38 + movl -20(%ebp), %eax + addl $4, %eax + movl -12(%ebp), %ecx + xorl %gs:20, %ecx + je .L40 + call __stack_chk_fail_local +.L40: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE16: + .size Barray, .-Barray + .globl Bsexp + .type Bsexp, @function +Bsexp: +.LFB17: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $36, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl %gs:20, %ecx + movl %ecx, -12(%ebp) + xorl %ecx, %ecx + movl 8(%ebp), %edx + addl $2, %edx + sall $2, %edx + subl $12, %esp + pushl %edx + movl %eax, %ebx + call malloc@PLT + addl $16, %esp + movl %eax, -24(%ebp) + movl -24(%ebp), %eax + addl $4, %eax + movl %eax, -20(%ebp) + movl 8(%ebp), %eax + subl $1, %eax + orl $33554432, %eax + movl %eax, %edx + movl -20(%ebp), %eax + movl %edx, (%eax) + leal 12(%ebp), %eax + movl %eax, -32(%ebp) + movl $0, -28(%ebp) + jmp .L42 +.L43: + movl -32(%ebp), %eax + leal 4(%eax), %edx + movl %edx, -32(%ebp) + movl (%eax), %eax + movl %eax, -16(%ebp) + movl -20(%ebp), %eax + leal 4(%eax), %edx + movl -28(%ebp), %eax + sall $2, %eax + addl %eax, %edx + movl -16(%ebp), %eax + movl %eax, (%edx) + addl $1, -28(%ebp) +.L42: + movl 8(%ebp), %eax + subl $1, %eax + cmpl %eax, -28(%ebp) + jl .L43 + movl -32(%ebp), %eax + leal 4(%eax), %edx + movl %edx, -32(%ebp) + movl (%eax), %edx + movl -24(%ebp), %eax + movl %edx, (%eax) + movl -20(%ebp), %eax + addl $4, %eax + movl -12(%ebp), %ecx + xorl %gs:20, %ecx + je .L45 + call __stack_chk_fail_local +.L45: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE17: + .size Bsexp, .-Bsexp + .globl Btag + .type Btag, @function +Btag: +.LFB18: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + subl $4, %eax + movl %eax, -4(%ebp) + movl -4(%ebp), %eax + movl (%eax), %eax + andl $-16777216, %eax + cmpl $33554432, %eax + jne .L47 + movl 8(%ebp), %eax + subl $8, %eax + movl (%eax), %eax + cmpl %eax, 12(%ebp) + jne .L47 + movl -4(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + cmpl %eax, 16(%ebp) + jne .L47 + movl $1, %eax + jmp .L48 +.L47: + movl $0, %eax +.L48: + addl %eax, %eax + orl $1, %eax + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE18: + .size Btag, .-Btag + .globl Barray_patt + .type Barray_patt, @function +Barray_patt: +.LFB19: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + andl $1, %eax + testl %eax, %eax + je .L51 + movl $1, %eax + jmp .L52 +.L51: + movl 8(%ebp), %eax + subl $4, %eax + movl %eax, -4(%ebp) + movl -4(%ebp), %eax + movl (%eax), %eax + andl $-16777216, %eax + cmpl $16777216, %eax + jne .L53 + movl -4(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + cmpl %eax, 12(%ebp) + jne .L53 + movl $1, %eax + jmp .L54 +.L53: + movl $0, %eax +.L54: + addl %eax, %eax + orl $1, %eax +.L52: + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE19: + .size Barray_patt, .-Barray_patt + .globl Bstring_patt + .type Bstring_patt, @function +Bstring_patt: +.LFB20: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %edx + andl $1, %edx + testl %edx, %edx + je .L56 + movl $1, %eax + jmp .L57 +.L56: + movl 8(%ebp), %edx + subl $4, %edx + movl %edx, -16(%ebp) + movl 12(%ebp), %edx + subl $4, %edx + movl %edx, -12(%ebp) + movl -16(%ebp), %edx + movl (%edx), %edx + andl $-16777216, %edx + testl %edx, %edx + je .L58 + movl $1, %eax + jmp .L57 +.L58: + movl -12(%ebp), %edx + leal 4(%edx), %ecx + movl -16(%ebp), %edx + addl $4, %edx + subl $8, %esp + pushl %ecx + pushl %edx + movl %eax, %ebx + call strcmp@PLT + addl $16, %esp + testl %eax, %eax + jne .L59 + movl $3, %eax + jmp .L57 +.L59: + movl $1, %eax +.L57: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE20: + .size Bstring_patt, .-Bstring_patt + .globl Bboxed_patt + .type Bboxed_patt, @function +Bboxed_patt: +.LFB21: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + andl $1, %eax + testl %eax, %eax + jne .L62 + movl $3, %eax + jmp .L64 +.L62: + movl $1, %eax +.L64: + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE21: + .size Bboxed_patt, .-Bboxed_patt + .globl Bunboxed_patt + .type Bunboxed_patt, @function +Bunboxed_patt: +.LFB22: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + addl %eax, %eax + andl $2, %eax + orl $1, %eax + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE22: + .size Bunboxed_patt, .-Bunboxed_patt + .globl Barray_tag_patt + .type Barray_tag_patt, @function +Barray_tag_patt: +.LFB23: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + andl $1, %eax + testl %eax, %eax + je .L68 + movl $1, %eax + jmp .L69 +.L68: + movl 8(%ebp), %eax + subl $4, %eax + movl (%eax), %eax + andl $-16777216, %eax + cmpl $16777216, %eax + jne .L70 + movl $3, %eax + jmp .L69 +.L70: + movl $1, %eax +.L69: + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE23: + .size Barray_tag_patt, .-Barray_tag_patt + .globl Bstring_tag_patt + .type Bstring_tag_patt, @function +Bstring_tag_patt: +.LFB24: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + andl $1, %eax + testl %eax, %eax + je .L73 + movl $1, %eax + jmp .L74 +.L73: + movl 8(%ebp), %eax + subl $4, %eax + movl (%eax), %eax + andl $-16777216, %eax + testl %eax, %eax + jne .L75 + movl $3, %eax + jmp .L74 +.L75: + movl $1, %eax +.L74: + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE24: + .size Bstring_tag_patt, .-Bstring_tag_patt + .globl Bsexp_tag_patt + .type Bsexp_tag_patt, @function +Bsexp_tag_patt: +.LFB25: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + andl $1, %eax + testl %eax, %eax + je .L78 + movl $1, %eax + jmp .L79 +.L78: + movl 8(%ebp), %eax + subl $4, %eax + movl (%eax), %eax + andl $-16777216, %eax + cmpl $33554432, %eax + jne .L80 + movl $3, %eax + jmp .L79 +.L80: + movl $1, %eax +.L79: + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE25: + .size Bsexp_tag_patt, .-Bsexp_tag_patt + .globl Bsta + .type Bsta, @function +Bsta: +.LFB26: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $56, %esp + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 16(%ebp), %eax + movl %eax, -44(%ebp) + movl %gs:20, %eax + movl %eax, -12(%ebp) + xorl %eax, %eax + leal 20(%ebp), %eax + movl %eax, -28(%ebp) + movl $0, -24(%ebp) + jmp .L83 +.L84: + movl -28(%ebp), %eax + leal 4(%eax), %edx + movl %edx, -28(%ebp) + movl (%eax), %eax + sarl %eax + movl %eax, -20(%ebp) + movl -20(%ebp), %eax + leal 0(,%eax,4), %edx + movl -44(%ebp), %eax + addl %edx, %eax + movl (%eax), %eax + movl %eax, -44(%ebp) + addl $1, -24(%ebp) +.L83: + movl 8(%ebp), %eax + subl $1, %eax + cmpl %eax, -24(%ebp) + jl .L84 + movl -28(%ebp), %eax + leal 4(%eax), %edx + movl %edx, -28(%ebp) + movl (%eax), %eax + sarl %eax + movl %eax, -20(%ebp) + movl -44(%ebp), %eax + subl $4, %eax + movl %eax, -16(%ebp) + movl -16(%ebp), %eax + movl (%eax), %eax + andl $-16777216, %eax + testl %eax, %eax + jne .L85 + movl 12(%ebp), %eax + sarl %eax + movl %eax, %ecx + movl -20(%ebp), %edx + movl -44(%ebp), %eax + addl %edx, %eax + movl %ecx, %edx + movb %dl, (%eax) + jmp .L88 +.L85: + movl -20(%ebp), %eax + leal 0(,%eax,4), %edx + movl -44(%ebp), %eax + addl %eax, %edx + movl 12(%ebp), %eax + movl %eax, (%edx) +.L88: + nop + movl -12(%ebp), %eax + xorl %gs:20, %eax + je .L87 + call __stack_chk_fail_local +.L87: + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE26: + .size Bsta, .-Bsta + .globl Lraw + .type Lraw, @function +Lraw: +.LFB27: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + sarl %eax + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE27: + .size Lraw, .-Lraw + .globl Lprintf + .type Lprintf, @function +Lprintf: +.LFB28: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $36, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %edx + movl %edx, -28(%ebp) + movl %gs:20, %ecx + movl %ecx, -12(%ebp) + xorl %ecx, %ecx + leal 12(%ebp), %edx + movl %edx, -16(%ebp) + movl -16(%ebp), %edx + subl $8, %esp + pushl %edx + pushl -28(%ebp) + movl %eax, %ebx + call vprintf@PLT + addl $16, %esp + nop + movl -12(%ebp), %eax + xorl %gs:20, %eax + je .L92 + call __stack_chk_fail_local +.L92: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE28: + .size Lprintf, .-Lprintf + .globl Lstrcat + .type Lstrcat, @function +Lstrcat: +.LFB29: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8(%ebp), %eax + subl $4, %eax + movl %eax, -20(%ebp) + movl 12(%ebp), %eax + subl $4, %eax + movl %eax, -16(%ebp) + movl -20(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + movl %eax, %edx + movl -16(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + addl %edx, %eax + addl $5, %eax + subl $12, %esp + pushl %eax + call malloc@PLT + addl $16, %esp + movl %eax, -12(%ebp) + movl -20(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + movl %eax, %edx + movl -16(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + addl %eax, %edx + movl -12(%ebp), %eax + movl %edx, (%eax) + movl -20(%ebp), %eax + leal 4(%eax), %edx + movl -12(%ebp), %eax + addl $4, %eax + subl $8, %esp + pushl %edx + pushl %eax + call strcpy@PLT + addl $16, %esp + movl -16(%ebp), %eax + leal 4(%eax), %edx + movl -12(%ebp), %eax + addl $4, %eax + subl $8, %esp + pushl %edx + pushl %eax + call strcat@PLT + addl $16, %esp + movl -12(%ebp), %eax + addl $4, %eax + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE29: + .size Lstrcat, .-Lstrcat + .globl Lfprintf + .type Lfprintf, @function +Lfprintf: +.LFB30: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $36, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %edx + movl %edx, -28(%ebp) + movl 12(%ebp), %edx + movl %edx, -32(%ebp) + movl %gs:20, %ecx + movl %ecx, -12(%ebp) + xorl %ecx, %ecx + leal 16(%ebp), %edx + movl %edx, -16(%ebp) + movl -16(%ebp), %edx + subl $4, %esp + pushl %edx + pushl -32(%ebp) + pushl -28(%ebp) + movl %eax, %ebx + call vfprintf@PLT + addl $16, %esp + nop + movl -12(%ebp), %eax + xorl %gs:20, %eax + je .L96 + call __stack_chk_fail_local +.L96: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE30: + .size Lfprintf, .-Lfprintf + .globl Lfopen + .type Lfopen, @function +Lfopen: +.LFB31: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $4, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + subl $8, %esp + pushl 12(%ebp) + pushl 8(%ebp) + movl %eax, %ebx + call fopen@PLT + addl $16, %esp + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE31: + .size Lfopen, .-Lfopen + .globl Lfclose + .type Lfclose, @function +Lfclose: +.LFB32: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $4, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + subl $12, %esp + pushl 8(%ebp) + movl %eax, %ebx + call fclose@PLT + addl $16, %esp + nop + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE32: + .size Lfclose, .-Lfclose + .section .rodata +.LC9: + .string "> " + .text + .globl Lread + .type Lread, @function +Lread: +.LFB33: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl %gs:20, %eax + movl %eax, -12(%ebp) + xorl %eax, %eax + subl $12, %esp + leal .LC9@GOTOFF(%ebx), %eax + pushl %eax + call printf@PLT + addl $16, %esp + movl stdout@GOT(%ebx), %eax + movl (%eax), %eax + subl $12, %esp + pushl %eax + call fflush@PLT + addl $16, %esp + subl $8, %esp + leal -16(%ebp), %eax + pushl %eax + leal .LC0@GOTOFF(%ebx), %eax + pushl %eax + call __isoc99_scanf@PLT + addl $16, %esp + movl -16(%ebp), %eax + addl %eax, %eax + orl $1, %eax + movl -12(%ebp), %edx + xorl %gs:20, %edx + je .L102 + call __stack_chk_fail_local +.L102: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE33: + .size Lread, .-Lread + .section .rodata +.LC10: + .string "%d\n" + .text + .globl Lwrite + .type Lwrite, @function +Lwrite: +.LFB34: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $4, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8(%ebp), %eax + sarl %eax + subl $8, %esp + pushl %eax + leal .LC10@GOTOFF(%ebx), %eax + pushl %eax + call printf@PLT + addl $16, %esp + movl stdout@GOT(%ebx), %eax + movl (%eax), %eax + subl $12, %esp + pushl %eax + call fflush@PLT + addl $16, %esp + movl $0, %eax + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE34: + .size Lwrite, .-Lwrite + .section .rodata +.LC11: + .string "Start, end: %lx, %lx\n" +.LC12: + .string "Root: %lx %lx %lx\n" + .text + .globl __gc_root_scan_data + .type __gc_root_scan_data, @function +__gc_root_scan_data: +.LFB35: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl %gs:20, %eax + movl %eax, -12(%ebp) + xorl %eax, %eax + movl __gc_data_start@GOT(%ebx), %eax + movl %eax, -16(%ebp) + subl $4, %esp + movl __gc_data_end@GOT(%ebx), %eax + pushl %eax + movl __gc_data_start@GOT(%ebx), %eax + pushl %eax + leal .LC11@GOTOFF(%ebx), %eax + pushl %eax + call printf@PLT + addl $16, %esp + jmp .L106 +.L108: + movl -16(%ebp), %eax + movl (%eax), %eax + andl $1, %eax + testl %eax, %eax + jne .L107 + movl -16(%ebp), %eax + movl (%eax), %edx + movl -16(%ebp), %eax + leal -16(%ebp), %ecx + pushl %ecx + pushl %edx + pushl %eax + leal .LC12@GOTOFF(%ebx), %eax + pushl %eax + call printf@PLT + addl $16, %esp +.L107: + movl -16(%ebp), %eax + addl $4, %eax + movl %eax, -16(%ebp) +.L106: + movl -16(%ebp), %eax + movl __gc_data_end@GOT(%ebx), %edx + cmpl %edx, %eax + jne .L108 + nop + movl -12(%ebp), %eax + xorl %gs:20, %eax + je .L109 + call __stack_chk_fail_local +.L109: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE35: + .size __gc_root_scan_data, .-__gc_root_scan_data + .section .rodata +.LC13: + .string "STA 0x%lx\n" + .text + .globl Ltest + .type Ltest, @function +Ltest: +.LFB36: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $4, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + subl $12, %esp + pushl $10 + call putchar@PLT + addl $16, %esp + movl __start_text@GOT(%ebx), %eax + subl $8, %esp + pushl %eax + leal .LC13@GOTOFF(%ebx), %eax + pushl %eax + call printf@PLT + addl $16, %esp + movl __stop_text@GOT(%ebx), %eax + subl $8, %esp + pushl %eax + leal .LC13@GOTOFF(%ebx), %eax + pushl %eax + call printf@PLT + addl $16, %esp + call __gc_root_scan_data + call __gc_root_scan_stack@PLT + nop + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE36: + .size Ltest, .-Ltest + .local buf.3077 + .comm buf.3077,6,4 + .section .rodata + .align 4 +.LC14: + .string "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNJPQRSTUVWXYZ" + .section .data.rel.local,"aw" + .align 4 + .type chars.3076, @object + .size chars.3076, 4 +chars.3076: + .long .LC14 + .section .text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat + .globl __x86.get_pc_thunk.ax + .hidden __x86.get_pc_thunk.ax + .type __x86.get_pc_thunk.ax, @function +__x86.get_pc_thunk.ax: +.LFB37: + .cfi_startproc + movl (%esp), %eax + ret + .cfi_endproc +.LFE37: + .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat + .globl __x86.get_pc_thunk.bx + .hidden __x86.get_pc_thunk.bx + .type __x86.get_pc_thunk.bx, @function +__x86.get_pc_thunk.bx: +.LFB38: + .cfi_startproc + movl (%esp), %ebx + ret + .cfi_endproc +.LFE38: + .hidden __stack_chk_fail_local + .ident "GCC: (GNU) 8.2.1 20180831" + .section .note.GNU-stack,"",@progbits diff --git a/runtime/testgc.expr b/runtime/testgc.expr new file mode 100644 index 000000000..e27c14c46 --- /dev/null +++ b/runtime/testgc.expr @@ -0,0 +1,9 @@ +fun print_list (l) { + case l of + `nil -> skip + | `cons (n, t) -> write (n); print_list (t) + esac +} + +x := `cons (4, `cons(3, `cons(2 , `cons (1, `cons (0, `cons (1, `cons (2, `cons (3, `cons (4, `cons (5, `nil)))))))))); +print_list (x) diff --git a/src/X86.ml b/src/X86.ml index 0dbf39b3e..ee0739036 100644 --- a/src/X86.ml +++ b/src/X86.ml @@ -19,6 +19,8 @@ let word_size = 4;; | L of int (* an immediate operand *) with show +let show_opnd = show(opnd) + (* For convenience we define the following synonyms for the registers: *) let ebx = R 0 let ecx = R 1 @@ -52,6 +54,7 @@ type instr = (* arithmetic correction: or 0x0001 *) | Or1 of opnd (* arithmetic correction: shl 1 *) | Sal1 of opnd (* arithmetic correction: shr 1 *) | Sar1 of opnd + | Repmovsl (* Instruction printer *) let show instr = @@ -91,6 +94,7 @@ let show instr = | Or1 s -> Printf.sprintf "\torl\t$0x0001,\t%s" (opnd s) | Sal1 s -> Printf.sprintf "\tsall\t%s" (opnd s) | Sar1 s -> Printf.sprintf "\tsarl\t%s" (opnd s) + | Repmovsl -> Printf.sprintf "\trep movsl\t" (* Opening stack machine to use instructions without fully qualified names *) open SM @@ -164,7 +168,7 @@ let compile env code = (env, Mov (M ("$" ^ s), l) :: call) | LD x -> - let s, env' = (env#global x)#allocate in + let s, env' = (env#variable x)#allocate in env', (match s with | S _ | M _ -> [Mov (env'#loc x, eax); Mov (eax, s)] @@ -172,7 +176,7 @@ let compile env code = ) | STA (x, n) -> - let s, env = (env#global x)#allocate in + let s, env = (env#variable x)#allocate in let push = match s with | S _ | M _ -> [Mov (env#loc x, eax); Mov (eax, s)] @@ -182,7 +186,7 @@ let compile env code = env, push @ code | ST x -> - let s, env' = (env#global x)#pop in + let s, env' = (env#variable x)#pop in env', (match s with | S _ | M _ -> [Mov (s, eax); Mov (eax, env'#loc x)] @@ -288,14 +292,20 @@ let compile env code = | BEGIN (f, a, l) -> let env = env#enter f a l in - env, [Push ebp; Mov (esp, ebp); Binop ("-", M ("$" ^ env#lsize), esp)] + env, [Push ebp; Mov (esp, ebp); Binop ("-", M ("$" ^ env#lsize), esp); + Mov (esp, edi); + Mov (M "$filler", esi); + Mov (M ("$" ^ (env#allocated_size)), ecx); + Repmovsl + ] | END -> - env, [Label env#epilogue; + env#endfunc, [Label env#epilogue; Mov (ebp, esp); Pop ebp; Ret; - Meta (Printf.sprintf "\t.set\t%s,\t%d" env#lsize (env#allocated * word_size)) + Meta (Printf.sprintf "\t.set\t%s,\t%d" env#lsize (env#allocated * word_size)); + Meta (Printf.sprintf "\t.set\t%s,\t%d" env#allocated_size env#allocated) ] | RET b -> @@ -386,6 +396,14 @@ class env = val fname = "" (* function name *) val stackmap = M.empty (* labels to stack map *) val barrier = false (* barrier condition *) + val max_locals_size = 0 + + method max_locals_size = max_locals_size + + method endfunc = + if stack_slots > max_locals_size + then {< max_locals_size = stack_slots >} + else self method show_stack = GT.show(list) (GT.show(opnd)) stack @@ -425,13 +443,13 @@ class env = (* allocates a fresh position on a symbolic stack *) method allocate = let x, n = - let rec allocate' = function - | [] -> ebx , 0 - | (S n)::_ -> S (n+1) , n+2 - | (R n)::_ when n < num_of_regs -> R (n+1) , stack_slots - | _ -> S static_size, static_size+1 - in - allocate' stack + let rec allocate' = function + | [] -> ebx , 0 + | (S n)::_ -> S (n+1) , n+2 + | (R n)::_ when n < num_of_regs -> R (n+1) , stack_slots + | _ -> S static_size, static_size+1 + in + allocate' stack in x, {< stack_slots = max n stack_slots; stack = x::stack >} @@ -458,8 +476,11 @@ class env = done; !h - (* registers a global variable in the environment *) - method global x = {< globals = S.add ("global_" ^ x) globals >} + (* registers a variable in the environment *) + method variable x = + match self#loc x with + | M name -> {< globals = S.add name globals >} + | _ -> self (* registers a string constant *) method string x = @@ -476,7 +497,9 @@ class env = method strings = M.bindings stringm (* gets a number of stack positions allocated *) - method allocated = stack_slots + method allocated = stack_slots + + method allocated_size = Printf.sprintf "LS%s_SIZE" fname (* enters a function *) method enter f a l = @@ -515,14 +538,26 @@ class env = the stack code, then generates x86 assember code, then prints the assembler file *) let genasm (ds, stmt) = - let stmt = Language.Stmt.Seq (stmt, Language.Stmt.Return (Some (Language.Expr.Call ("raw", [Language.Expr.Const 0])))) in + let stmt = + Language.Stmt.Seq ( + Language.Stmt.Call ("__gc_init", []), + Language.Stmt.Seq (stmt, Language.Stmt.Return (Some (Language.Expr.Call ("raw", [Language.Expr.Const 0])))) + ) + in let env, code = compile (new env) ((LABEL "main") :: (BEGIN ("main", [], [])) :: SM.compile (ds, stmt)) in - let data = Meta "\t.data" :: (List.map (fun s -> Meta (Printf.sprintf "%s:\t.int\t0" s )) env#globals) @ - (List.map (fun (s, v) -> Meta (Printf.sprintf "%s:\t.string\t\"%s\"" v s)) env#strings) in + let gc_start, gc_end = "__gc_data_start", "__gc_data_end" in + let data = [Meta "\t.data"; + Meta (Printf.sprintf "filler:\t.fill\t%d, 4, 1" env#max_locals_size); + Meta (Printf.sprintf "\t.globl\t%s" gc_start); Meta (Printf.sprintf "\t.globl\t%s" gc_end)] @ + [Meta (Printf.sprintf "%s:" gc_start)] @ + (List.map (fun s -> Meta (Printf.sprintf "%s:\t.int\t1" s )) env#globals) @ + [Meta (Printf.sprintf "%s:" gc_end)] @ + (List.map (fun (s, v) -> Meta (Printf.sprintf "%s:\t.string\t\"%s\"" v s)) env#strings) + in let asm = Buffer.create 1024 in List.iter (fun i -> Buffer.add_string asm (Printf.sprintf "%s\n" @@ show i)) @@ -535,5 +570,5 @@ let build prog name = Printf.fprintf outf "%s" (genasm prog); close_out outf; let inc = try Sys.getenv "RC_RUNTIME" with _ -> "../runtime" in - Sys.command (Printf.sprintf "gcc -m32 -o %s %s/runtime.o %s.s" name inc name) + Sys.command (Printf.sprintf "gcc -g -m32 -o %s %s/gc_runtime.o %s/runtime.o %s.s" name inc inc name) diff --git a/src/testgc.expr b/src/testgc.expr new file mode 100644 index 000000000..595eaf0a0 --- /dev/null +++ b/src/testgc.expr @@ -0,0 +1,22 @@ +fun f () local b { + b := 7; + test (); + b := y; + test (); + b := 9; + test (); + return 0 +} + +--x := 0; +--y := 0; +--z := 0; +--t := 0; +--test (); +y := "abc"; +test (); +t := []; +test (); +t := 0; +test (); +f ()