|
|
|
@ -1,9 +1,13 @@
|
|
|
|
|
#include <bits/stdint-intn.h> |
|
|
|
|
#include <stdint.h> |
|
|
|
|
#include <assert.h> |
|
|
|
|
#include <memory.h> |
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include "runtime.h" |
|
|
|
|
|
|
|
|
|
#define INT_MARKER (1l << 63) |
|
|
|
|
#define IS_INT(n) ((uint64_t) n & INT_MARKER) |
|
|
|
|
|
|
|
|
|
struct node_base* alloc_node() { |
|
|
|
|
struct node_base* new_node = malloc(sizeof(struct node_app)); |
|
|
|
|
new_node->gc_next = NULL; |
|
|
|
@ -21,10 +25,7 @@ struct node_app* alloc_app(struct node_base* l, struct node_base* r) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct node_num* alloc_num(int32_t n) { |
|
|
|
|
struct node_num* node = (struct node_num*) alloc_node(); |
|
|
|
|
node->base.tag = NODE_NUM; |
|
|
|
|
node->value = n; |
|
|
|
|
return node; |
|
|
|
|
return (struct node_num*) (INT_MARKER | n); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct node_global* alloc_global(void (*f)(struct gmachine*), int32_t a) { |
|
|
|
@ -49,7 +50,7 @@ void free_node_direct(struct node_base* n) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void gc_visit_node(struct node_base* n) { |
|
|
|
|
if(n->gc_reachable) return; |
|
|
|
|
if(IS_INT(n) || n->gc_reachable) return; |
|
|
|
|
n->gc_reachable = 1; |
|
|
|
|
|
|
|
|
|
if(n->tag == NODE_APP) { |
|
|
|
@ -169,6 +170,7 @@ void gmachine_split(struct gmachine* g, size_t n) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct node_base* gmachine_track(struct gmachine* g, struct node_base* b) { |
|
|
|
|
if(IS_INT(b)) return b; |
|
|
|
|
g->gc_node_count++; |
|
|
|
|
b->gc_next = g->gc_nodes; |
|
|
|
|
g->gc_nodes = b; |
|
|
|
@ -208,7 +210,9 @@ void unwind(struct gmachine* g) {
|
|
|
|
|
|
|
|
|
|
while(1) { |
|
|
|
|
struct node_base* peek = stack_peek(s, 0); |
|
|
|
|
if(peek->tag == NODE_APP) { |
|
|
|
|
if(IS_INT(peek)) { |
|
|
|
|
break; |
|
|
|
|
} else if(peek->tag == NODE_APP) { |
|
|
|
|
struct node_app* n = (struct node_app*) peek; |
|
|
|
|
stack_push(s, n->left); |
|
|
|
|
} else if(peek->tag == NODE_GLOBAL) { |
|
|
|
@ -234,7 +238,9 @@ void unwind(struct gmachine* g) {
|
|
|
|
|
extern void f_main(struct gmachine* s); |
|
|
|
|
|
|
|
|
|
void print_node(struct node_base* n) { |
|
|
|
|
if(n->tag == NODE_APP) { |
|
|
|
|
if(IS_INT(n)) { |
|
|
|
|
printf("%d", (int32_t) n); |
|
|
|
|
} else if(n->tag == NODE_APP) { |
|
|
|
|
struct node_app* app = (struct node_app*) n; |
|
|
|
|
print_node(app->left); |
|
|
|
|
putchar(' '); |
|
|
|
@ -246,9 +252,6 @@ void print_node(struct node_base* n) {
|
|
|
|
|
printf("(Global: %p)", global->function); |
|
|
|
|
} else if(n->tag == NODE_IND) { |
|
|
|
|
print_node(((struct node_ind*) n)->next); |
|
|
|
|
} else if(n->tag == NODE_NUM) { |
|
|
|
|
struct node_num* num = (struct node_num*) n; |
|
|
|
|
printf("%d", num->value); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|