runtime fixes, byterun fixes

This commit is contained in:
ProgramSnail 2024-11-14 00:50:43 +03:00
parent 233fa95e14
commit e456304eb3
11 changed files with 513 additions and 411 deletions

BIN
byterun/Sort.bc Normal file

Binary file not shown.

View file

@ -8,4 +8,4 @@ const char *read_cmd(char *ip);
bytefile *read_file(char *fname); bytefile *read_file(char *fname);
void dump_file(FILE *f, bytefile *bf); // void dump_file(FILE *f, bytefile *bf);

View file

@ -12,11 +12,12 @@ extern struct State s;
extern size_t __gc_stack_top, __gc_stack_bottom; extern size_t __gc_stack_top, __gc_stack_bottom;
static inline void **s_top() { static inline void **s_top() {
return s.stack + STACK_SIZE - s.bf->global_area_size; return (void **)__gc_stack_bottom - s.bf->global_area_size;
} }
static inline bool s_is_empty() { static inline bool s_is_empty() {
if (s.sp == s_top() || (s.fp != NULL && s.sp == f_locals(s.fp))) { if ((void **)__gc_stack_top == s_top() ||
(s.fp != NULL && (void **)__gc_stack_top == f_locals(s.fp))) {
return true; return true;
} }
return false; return false;
@ -26,39 +27,38 @@ static inline void **s_nth(aint n) {
if (n < 0) { if (n < 0) {
s_failure(&s, "can't access stack by negative index"); s_failure(&s, "can't access stack by negative index");
} }
if (s.sp + n >= s_top()) { if ((void **)__gc_stack_top + n >= s_top()) {
s_failure(&s, "not enough elements in stack"); s_failure(&s, "not enough elements in stack");
} }
if (s.fp != NULL && s.sp + n >= f_locals(s.fp)) { if (s.fp != NULL && (void **)__gc_stack_top + n >= f_locals(s.fp)) {
s_failure(&s, "not enough elements in function stack"); s_failure(&s, "not enough elements in function stack");
} }
return s.sp + n; return (void **)__gc_stack_top + n;
} }
static inline void **s_peek() { static inline void **s_peek() {
if (s.sp == s_top()) { if ((void **)__gc_stack_top == s_top()) {
s_failure(&s, "empty stack"); s_failure(&s, "empty stack");
} }
if (s.fp != NULL && s.sp == f_locals(s.fp)) { if (s.fp != NULL && (void **)__gc_stack_top == f_locals(s.fp)) {
s_failure(&s, "empty function stack"); s_failure(&s, "empty function stack");
} }
return s.sp; return (void **)__gc_stack_top;
} }
static inline aint *s_peek_i() { return (aint *)s_peek(); } static inline aint *s_peek_i() { return (aint *)s_peek(); }
static inline void s_push(void *val) { static inline void s_push(void *val) {
if (s.sp == s.stack) { if ((void **)__gc_stack_top == s.stack) {
s_failure(&s, "stack overflow"); s_failure(&s, "stack overflow");
} }
#ifdef DEBUG_VERSION #ifdef DEBUG_VERSION
printf("--> push\n"); printf("--> push\n");
#endif #endif
--s.sp; __gc_stack_top -= sizeof(void *);
*s.sp = val; *(void **)__gc_stack_top = val;
__gc_stack_top = (size_t)(s.sp) - (size_t)(s.sp) & 0xF;
} }
static inline void s_push_i(aint val) { s_push((void *)val); } static inline void s_push_i(aint val) { s_push((void *)val); }
@ -72,19 +72,18 @@ static inline void s_pushn_nil(size_t n) {
} }
static inline void *s_pop() { static inline void *s_pop() {
if (s.sp == s_top()) { if ((void **)__gc_stack_top == s_top()) {
s_failure(&s, "empty stack"); s_failure(&s, "empty stack");
} }
if (s.fp != NULL && s.sp == f_locals(s.fp)) { if (s.fp != NULL && (void **)__gc_stack_top == f_locals(s.fp)) {
s_failure(&s, "empty function stack"); s_failure(&s, "empty function stack");
} }
#ifdef DEBUG_VERSION #ifdef DEBUG_VERSION
printf("--> pop\n"); printf("--> pop\n");
#endif #endif
void *value = *s.sp; void *value = *(void **)__gc_stack_top;
*s.sp = NULL; // *(void **)__gc_stack_top = NULL;
++s.sp; __gc_stack_top += sizeof(void *);
__gc_stack_top = (size_t)(s.sp) - (size_t)(s.sp) & 0xF;
return value; return value;
} }
@ -112,11 +111,13 @@ static inline void s_enter_f(char *rp, bool is_closure_call, auint args_sz,
#endif #endif
// check that params count is valid // check that params count is valid
if (s.sp + (aint)args_sz - (is_closure_call ? 0 : 1) >= s_top()) { if ((void **)__gc_stack_top + (aint)args_sz - (is_closure_call ? 0 : 1) >=
s_top()) {
s_failure(&s, "not enough parameters in stack"); s_failure(&s, "not enough parameters in stack");
} }
if (s.fp != NULL && if (s.fp != NULL &&
s.sp + (aint)args_sz - (is_closure_call ? 0 : 1) >= f_locals(s.fp)) { (void **)__gc_stack_top + (aint)args_sz - (is_closure_call ? 0 : 1) >=
f_locals(s.fp)) {
s_failure(&s, "not enough parameters in function stack"); s_failure(&s, "not enough parameters in function stack");
} }
@ -136,7 +137,7 @@ static inline void s_enter_f(char *rp, bool is_closure_call, auint args_sz,
}; };
// put frame on stack // put frame on stack
s.fp = (struct Frame *)s.sp; s.fp = (struct Frame *)__gc_stack_top;
(*s.fp) = frame; (*s.fp) = frame;
s_pushn_nil(locals_sz); s_pushn_nil(locals_sz);
@ -148,10 +149,9 @@ static inline void s_exit_f() {
} }
struct Frame frame = *s.fp; struct Frame frame = *s.fp;
push_extra_root((void **)&frame.ret);
// drop stack entities, locals, frame // drop stack entities, locals, frame
size_t to_pop = f_args(s.fp) - s.sp; size_t to_pop = f_args(s.fp) - (void **)__gc_stack_top;
s.fp = (struct Frame *)f_prev_fp(&frame); s.fp = (struct Frame *)f_prev_fp(&frame);
#ifdef DEBUG_VERSION #ifdef DEBUG_VERSION
printf("-> %zu to pop\n", to_pop); printf("-> %zu to pop\n", to_pop);
@ -170,13 +170,11 @@ static inline void s_exit_f() {
} }
s.ip = frame.rp; s.ip = frame.rp;
pop_extra_root((void **)&frame.ret);
} }
static inline void print_stack() { static inline void print_stack() {
printf("stack (%i) is\n[", s.stack + STACK_SIZE - s.sp); printf("stack (%i) is\n[", s.stack + STACK_SIZE - (void **)__gc_stack_top);
for (void **x = s.stack + STACK_SIZE - 1; x >= s.sp; --x) { for (void **x = s.stack + STACK_SIZE - 1; x >= (void **)__gc_stack_top; --x) {
printf("%li ", (long)UNBOX(*x)); printf("%li ", (long)UNBOX(*x));
} }
printf("]\n"); printf("]\n");
@ -207,7 +205,8 @@ static inline void **var_by_category(enum VarCategory category, int id) {
// f_locals_sz(s.fp)); // f_locals_sz(s.fp));
} }
// printf("id is %i, local is %i, %i\n", id, // printf("id is %i, local is %i, %i\n", id,
// UNBOX((auint)*((void**)f_locals(s.fp) + id)), f_locals(s.fp) - s.sp); // UNBOX((auint)*((void**)f_locals(s.fp) + id)), f_locals(s.fp) - (void
// **)__gc_stack_top);
var = f_locals(s.fp) + (f_locals_sz(s.fp) - id - 1); var = f_locals(s.fp) + (f_locals_sz(s.fp) - id - 1);
break; break;
case VAR_ARGUMENT: case VAR_ARGUMENT:

View file

@ -53,7 +53,7 @@ static inline void **f_args(struct Frame *fp) {
struct State { struct State {
void **stack; void **stack;
void **sp; // stack pointer // void **sp; // stack pointer
struct Frame *fp; // function frame pointer struct Frame *fp; // function frame pointer
bytefile *bf; bytefile *bf;
int current_line; int current_line;
@ -90,3 +90,78 @@ static inline enum VarCategory to_var_category(uint8_t category) {
} }
return (enum VarCategory)category; return (enum VarCategory)category;
} }
enum CMD {
CMD_BINOP = 0,
CMD_BASIC,
CMD_LD,
CMD_LDA,
CMD_ST,
CMD_CTRL,
CMD_PATT,
CMD_BUILTIN,
CMD_EXIT = 15,
};
enum CMD_BINOPS {
CMD_BINOP_ADD = 1, // +
CMD_BINOP_SUB, // -
CMD_BINOP_MULT, // *
CMD_BINOP_DIV, // /
CMD_BINOP_MOD, // %
CMD_BINOP_LEQ, // <
CMD_BINOP_LT, // <=
CMD_BINOP_GT, // >
CMD_BINOP_GEQ, // >=
CMD_BINOP_EQ, // ==
CMD_BINOP_NEQ, // !=
CMD_BINOP_AND, // &&
CMD_BINOP_OR, // !!
};
enum CMD_BASICS {
CMD_BASIC_CONST = 0,
CMD_BASIC_STRING,
CMD_BASIC_SEXP,
CMD_BASIC_STI,
CMD_BASIC_STA,
CMD_BASIC_JMP,
CMD_BASIC_END,
CMD_BASIC_RET,
CMD_BASIC_DROP,
CMD_BASIC_DUP,
CMD_BASIC_SWAP,
CMD_BASIC_ELEM,
};
enum CMD_CTRLS {
CMD_CTRL_CJMPz = 0,
CMD_CTRL_CJMPnz,
CMD_CTRL_BEGIN,
CMD_CTRL_CBEGIN,
CMD_CTRL_CLOSURE,
CMD_CTRL_CALLC,
CMD_CTRL_CALL,
CMD_CTRL_TAG,
CMD_CTRL_ARRAY,
CMD_CTRL_FAIL,
CMD_CTRL_LINE,
};
enum CMD_PATTS {
CMD_PATT_STR = 0,
CMD_PATT_STR_TAG,
CMD_PATT_ARRAY_TAG,
CMD_PATT_SEXP_TAG,
CMD_PATT_REF_TAG,
CMD_PATT_VAL_TAG,
CMD_PATT_FUN_TAG,
};
enum CMD_BUILTINS {
CMD_BUILTIN_Lread = 0,
CMD_BUILTIN_Lwrite,
CMD_BUILTIN_Llength,
CMD_BUILTIN_Lstring,
CMD_BUILTIN_Barray,
};

View file

@ -20,25 +20,34 @@ typedef struct {
char buffer[0]; char buffer[0];
} bytefile; } bytefile;
/* Gets a string from a string table by an index */
static inline char *get_string(bytefile *f, size_t pos) {
return &f->string_ptr[pos];
}
/* Gets a name for a public symbol */
static inline char *get_public_name(bytefile *f, size_t i) {
return get_string(f, f->public_ptr[i * 2]);
}
/* Gets an offset for a publie symbol */
static inline size_t get_public_offset(bytefile *f, size_t i) {
return f->public_ptr[i * 2 + 1];
}
static inline void exec_failure(const char *cmd, int line, aint offset, static inline void exec_failure(const char *cmd, int line, aint offset,
const char *msg) { const char *msg) {
failure("*** RUNTIME ERROR: %i(0x%.8x):%s error: %s\n", line, offset, cmd, failure("*** RUNTIME ERROR: %i(0x%.8x):%s error: %s\n", line, offset, cmd,
msg); msg);
} }
// --- /* Gets a string from a string table by an index */
static inline const char *get_string(const bytefile *f, size_t pos) {
if (pos >= f->stringtab_size) {
failure("strinpg pos is out of range: %zu >= %i\n", pos, f->stringtab_size);
}
return &f->string_ptr[pos];
}
/* Gets a name for a public symbol */
static inline const char *get_public_name(const bytefile *f, size_t i) {
if (i * 2 >= f->public_symbols_number) {
failure("public number is out of range: %zu >= %i\n", i * 2,
f->public_symbols_number);
}
return get_string(f, f->public_ptr[i * 2]);
}
/* Gets an offset for a publie symbol */
static inline size_t get_public_offset(const bytefile *f, size_t i) {
if (i * 2 + 1 >= f->public_symbols_number) {
failure("public number is out of range: %zu >= %i\n", i * 2 + 1,
f->public_symbols_number);
}
return f->public_ptr[i * 2 + 1];
}

View file

@ -10,9 +10,9 @@ int main(int argc, char** argv) {
// printf("size of aint is %i\n", sizeof(aint)); // printf("size of aint is %i\n", sizeof(aint));
bytefile *f = read_file(argv[1]); bytefile *f = read_file(argv[1]);
#ifdef DEBUG_VERSION // #ifdef DEBUG_VERSION
dump_file (stdout, f); // dump_file (stdout, f);
#endif // #endif
run(f, argc - 1, argv + 1); run(f, argc - 1, argv + 1);
free(f->global_ptr); free(f->global_ptr);

View file

@ -11,14 +11,22 @@
struct State s; struct State s;
static inline int ip_read_int(char **ip) { static inline int ip_read_int(char **ip) {
if (*ip + sizeof(int) > s.bf->code_ptr + s.bf->code_size) {
failure("last command is invalid, int parameter can not be read\n");
}
*ip += sizeof(int); *ip += sizeof(int);
return *(int *)((*ip) - sizeof(int)); return *(int *)((*ip) - sizeof(int));
} }
static inline char ip_read_byte(char **ip) { return *(*ip)++; } static inline uint8_t ip_read_byte(char **ip) {
if (*ip + sizeof(char) > s.bf->code_ptr + s.bf->code_size) {
failure("last command is invalid, byte parameter can not be read\n");
}
return *(*ip)++;
}
static inline char *ip_read_string(char **ip, bytefile *bf) { static inline const char *ip_read_string(char **ip) {
return get_string(bf, ip_read_int(ip)); return get_string(s.bf, ip_read_int(ip));
} }
const size_t BUFFER_SIZE = 1000; const size_t BUFFER_SIZE = 1000;
@ -32,38 +40,37 @@ void run(bytefile *bf, int argc, char **argv) {
printf("--- interpreter run ---\n"); printf("--- interpreter run ---\n");
#endif #endif
const size_t OPS_SIZE = 13; // const char *ops[] = {
const char *ops[] = { // "+", "-", "*", "/", "%", "<", "<=", ">", ">=", "==", "!=", "&&", "!!"};
"+", "-", "*", "/", "%", "<", "<=", ">", ">=", "==", "!=", "&&", "!!"}; // aint (*ops_func[])(void *, void *) = {
aint (*ops_func[])(void *, void *) = { // &Ls__Infix_43, // +
&Ls__Infix_43, // + // &Ls__Infix_45, // -
&Ls__Infix_45, // - // &Ls__Infix_42, // *
&Ls__Infix_42, // * // &Ls__Infix_47, // /
&Ls__Infix_47, // / // &Ls__Infix_37, // %
&Ls__Infix_37, // % // &Ls__Infix_60, // <
&Ls__Infix_60, // < // &Ls__Infix_6061, // <=
&Ls__Infix_6061, // <= // &Ls__Infix_62, // >
&Ls__Infix_62, // > // &Ls__Infix_6261, // >=
&Ls__Infix_6261, // >= // &Ls__Infix_6161, // ==
&Ls__Infix_6161, // == // &Ls__Infix_3361, // !=
&Ls__Infix_3361, // != // &Ls__Infix_3838, // &&
&Ls__Infix_3838, // && // &Ls__Infix_3333, // !!
&Ls__Infix_3333, // !! // };
};
const size_t PATS_SIZE = 7; // const char *pats[] = {"=str", "#string", "#array", "#sexp",
const char *pats[] = {"=str", "#string", "#array", "#sexp", // "#ref", "#val", "#fun"};
"#ref", "#val", "#fun"};
// argc, argv // argc, argv
{ {
s_push_i(BOX(argc)); s_push_i(BOX(argc));
void **argv_strs = calloc(argc, sizeof(void *));
for (size_t i = 0; i < argc; ++i) { for (size_t i = 0; i < argc; ++i) {
argv_strs[i] = Bstring((aint *)&argv[i]); s_push(Bstring((aint *)&argv[argc - i - 1]));
} }
s_push(Barray((aint *)&argv_strs, argc)); s_push(Barray((aint *)s_peek(), argc));
free(argv_strs); void *argv_elem = s_pop();
s_popn(argc);
s_push(argv_elem);
} }
#ifdef DEBUG_VERSION #ifdef DEBUG_VERSION
@ -83,55 +90,93 @@ void run(bytefile *bf, int argc, char **argv) {
} }
s.instr_ip = s.ip; s.instr_ip = s.ip;
char x = ip_read_byte(&s.ip), h = (x & 0xF0) >> 4, l = x & 0x0F; uint8_t x = ip_read_byte(&s.ip), h = (x & 0xF0) >> 4, l = x & 0x0F;
#ifdef DEBUG_VERSION #ifdef DEBUG_VERSION
printf("0x%.8x\n", s.ip - bf->code_ptr - 1); printf("0x%.8x\n", s.ip - bf->code_ptr - 1);
#endif #endif
switch (h) { switch (h) {
case 15: case CMD_EXIT:
goto stop; goto stop;
/* BINOP */ /* BINOP */
case 0: // BINOP ops[l-1] case CMD_BINOP: { // BINOP ops[l-1]
if (l > OPS_SIZE) {
s_failure(&s, "undefined binop type index");
}
if (l < 1) {
s_failure(&s, "negative binop type index");
}
void *left = s_pop(); void *left = s_pop();
void *right = s_pop(); void *right = s_pop();
s_push((void *)ops_func[l - 1](right, left)); switch ((int)l) {
case CMD_BINOP_ADD: // +
s_push_i(Ls__Infix_43(right, left));
break; break;
case CMD_BINOP_SUB: // -
s_push_i(Ls__Infix_45(right, left));
break;
case CMD_BINOP_MULT: // *
s_push_i(Ls__Infix_42(right, left));
break;
case CMD_BINOP_DIV: // /
s_push_i(Ls__Infix_47(right, left));
break;
case CMD_BINOP_MOD: // %
s_push_i(Ls__Infix_37(right, left));
break;
case CMD_BINOP_LEQ: // <
s_push_i(Ls__Infix_60(right, left));
break;
case CMD_BINOP_LT: // <=
s_push_i(Ls__Infix_6061(right, left));
break;
case CMD_BINOP_GT: // >
s_push_i(Ls__Infix_62(right, left));
break;
case CMD_BINOP_GEQ: // >=
s_push_i(Ls__Infix_6261(right, left));
break;
case CMD_BINOP_EQ: // ==
s_push_i(Ls__Infix_6161(right, left));
break;
case CMD_BINOP_NEQ: // !=
s_push_i(Ls__Infix_3361(right, left));
break;
case CMD_BINOP_AND: // &&
s_push_i(Ls__Infix_3838(right, left));
break;
case CMD_BINOP_OR: // !!
s_push_i(Ls__Infix_3333(right, left));
break;
default:
s_failure(&s, "invalid opcode"); // %d-%d\n", h, l);
break;
}
break;
}
case 1: case CMD_BASIC:
switch (l) { switch (l) {
case 0: // CONST %d case CMD_BASIC_CONST: // CONST %d
s_push_i(BOX(ip_read_int(&s.ip))); s_push_i(BOX(ip_read_int(&s.ip)));
break; break;
case 1: { // STRING %s case CMD_BASIC_STRING: { // STRING %s
void *str = ip_read_string(&s.ip, bf); void *str = (void *)ip_read_string(&s.ip);
s_push(Bstring((aint *)&str)); s_push(Bstring((aint *)&str));
break; break;
} }
case 2: { // SEXP %s %d // create sexpr with tag=%s and %d elements from case CMD_BASIC_SEXP: { // SEXP %s %d // create sexpr with tag=%s and %d
// elements from
// stack // stack
// params read from stack // params read from stack
const char *name = ip_read_string(&s.ip, bf); const char *name = ip_read_string(&s.ip);
aint args_count = ip_read_int(&s.ip); size_t args_count = ip_read_int(&s.ip);
#ifdef DEBUG_VERSION #ifdef DEBUG_VERSION
printf("tag hash is %i, n is %i\n", UNBOX(LtagHash((char *)name)), printf("tag hash is %i, n is %i\n", UNBOX(LtagHash((char *)name)),
args_count); args_count);
#endif #endif
if (args_count < 0) { void **opr_buffer = args_count >= BUFFER_SIZE
s_failure(&s, "args count should be >= 0"); ? alloc((args_count + 1) * sizeof(void *))
} : buffer;
void **opr_buffer = args_count >= BUFFER_SIZE ? calloc(args_count + 1, sizeof(void *)) : buffer;
for (size_t i = 1; i <= args_count; ++i) { for (size_t i = 1; i <= args_count; ++i) {
opr_buffer[args_count - i] = s_pop(); opr_buffer[args_count - i] = s_pop();
@ -140,17 +185,11 @@ void run(bytefile *bf, int argc, char **argv) {
void *sexp = Bsexp((aint *)opr_buffer, BOX(args_count + 1)); void *sexp = Bsexp((aint *)opr_buffer, BOX(args_count + 1));
push_extra_root(sexp);
s_push(sexp); s_push(sexp);
pop_extra_root(sexp);
if (args_count >= BUFFER_SIZE) {
free(opr_buffer);
}
break; break;
} }
case 3: { // STI - write by ref (?) case CMD_BASIC_STI: { // STI - write by ref (?)
// NOTE: example not found, no checks done // NOTE: example not found, no checks done
void *elem = s_pop(); void *elem = s_pop();
void **addr = (void **)s_pop(); void **addr = (void **)s_pop();
@ -159,7 +198,7 @@ void run(bytefile *bf, int argc, char **argv) {
break; break;
} }
case 4: { // STA - write to array elem case CMD_BASIC_STA: { // STA - write to array elem
void *elem = s_pop(); void *elem = s_pop();
aint index = s_pop_i(); aint index = s_pop_i();
void *data = s_pop(); void *data = s_pop();
@ -167,17 +206,17 @@ void run(bytefile *bf, int argc, char **argv) {
break; break;
} }
case 5: { // JMP 0x%.8x case CMD_BASIC_JMP: { // JMP 0x%.8x
int jmp_p = ip_read_int(&s.ip); uint jmp_p = ip_read_int(&s.ip);
if (jmp_p < 0) { if (jmp_p >= bf->code_size) {
s_failure(&s, "negative file offset jumps are not allowed"); s_failure(&s, "jump out of file");
} }
s.ip = bf->code_ptr + jmp_p; s.ip = bf->code_ptr + jmp_p;
break; break;
} }
case 6: // END case CMD_BASIC_END: // END
if (!s_is_empty() && s.fp->prev_fp != 0) { if (!s_is_empty() && s.fp->prev_fp != 0) {
s.fp->ret = *s_peek(); s.fp->ret = *s_peek();
s_pop(); s_pop();
@ -185,7 +224,7 @@ void run(bytefile *bf, int argc, char **argv) {
s_exit_f(); s_exit_f();
break; break;
case 7: // RET case CMD_BASIC_RET: // RET
if (!s_is_empty() && s.fp->prev_fp != 0) { if (!s_is_empty() && s.fp->prev_fp != 0) {
s.fp->ret = *s_peek(); s.fp->ret = *s_peek();
s_pop(); s_pop();
@ -193,35 +232,25 @@ void run(bytefile *bf, int argc, char **argv) {
s_exit_f(); s_exit_f();
break; break;
case 8: // DROP case CMD_BASIC_DROP: // DROP
s_pop(); s_pop();
break; break;
case 9: // DUP case CMD_BASIC_DUP: // DUP
{ {
s_push(*s_peek()); s_push(*s_peek());
break; break;
} }
case 10: // SWAP case CMD_BASIC_SWAP: // SWAP
{ {
void *x = s_pop(); void *x = s_pop();
void *y = s_pop(); void *y = s_pop();
s_push(y); s_push(y);
s_push(x); s_push(x);
// if (s.sp + 1 >= s.stack + STACK_SIZE ||
// (s.fp != NULL && s.sp + 1 >= f_locals(s.fp))) {
// s_failure(&s, "can't SWAP: < 2 values on stack");
// }
// void *v = *s.sp;
// push_extra_root(v);
// *s.sp = *(s.sp + 1);
// *(s.sp + 1) = v;
// pop_extra_root(v);
} break; } break;
case 11: // ELEM case CMD_BASIC_ELEM: // ELEM
{ {
aint index = s_pop_i(); aint index = s_pop_i();
void *data = s_pop(); void *data = s_pop();
@ -233,33 +262,30 @@ void run(bytefile *bf, int argc, char **argv) {
} }
break; break;
case 2: { // LD %d case CMD_LD: { // LD %d
void **var_ptr = void **var_ptr = var_by_category(to_var_category(l), ip_read_int(&s.ip));
var_by_category(to_var_category(l), ip_read_int(&s.ip));
s_push(*var_ptr); s_push(*var_ptr);
break; break;
} }
case 3: { // LDA %d case CMD_LDA: { // LDA %d
void **var_ptr = void **var_ptr = var_by_category(to_var_category(l), ip_read_int(&s.ip));
var_by_category(to_var_category(l), ip_read_int(&s.ip));
s_push(*var_ptr); s_push(*var_ptr);
break; break;
} }
case 4: { // ST %d case CMD_ST: { // ST %d
void **var_ptr = void **var_ptr = var_by_category(to_var_category(l), ip_read_int(&s.ip));
var_by_category(to_var_category(l), ip_read_int(&s.ip));
*var_ptr = *s_peek(); *var_ptr = *s_peek();
break; break;
} }
case 5: case CMD_CTRL:
switch (l) { switch (l) {
case 0: { // CJMPz 0x%.8x case CMD_CTRL_CJMPz: { // CJMPz 0x%.8x
int jmp_p = ip_read_int(&s.ip); uint jmp_p = ip_read_int(&s.ip);
if (jmp_p < 0) { if (jmp_p >= bf->code_size) {
s_failure(&s, "negative file offset jumps are not allowed"); s_failure(&s, "jump out of file");
} }
if (UNBOX(s_pop_i()) == 0) { if (UNBOX(s_pop_i()) == 0) {
s.ip = bf->code_ptr + jmp_p; s.ip = bf->code_ptr + jmp_p;
@ -267,11 +293,11 @@ void run(bytefile *bf, int argc, char **argv) {
break; break;
} }
case 1: { // CJMPnz 0x%.8x case CMD_CTRL_CJMPnz: { // CJMPnz 0x%.8x
int jmp_p = ip_read_int(&s.ip); uint jmp_p = ip_read_int(&s.ip);
if (jmp_p < 0) { if (jmp_p >= bf->code_size) {
s_failure(&s, "negative file offset jumps are not allowed"); s_failure(&s, "jump out of file");
} }
if (UNBOX(s_pop_i()) != 0) { if (UNBOX(s_pop_i()) != 0) {
s.ip = bf->code_ptr + jmp_p; s.ip = bf->code_ptr + jmp_p;
@ -279,7 +305,7 @@ void run(bytefile *bf, int argc, char **argv) {
break; break;
} }
case 2: { // BEGIN %d %d // function begin case CMD_CTRL_BEGIN: { // BEGIN %d %d // function begin
int args_sz = ip_read_int(&s.ip); int args_sz = ip_read_int(&s.ip);
int locals_sz = ip_read_int(&s.ip); int locals_sz = ip_read_int(&s.ip);
if (s.fp != NULL && s.call_ip == NULL) { if (s.fp != NULL && s.call_ip == NULL) {
@ -290,7 +316,7 @@ void run(bytefile *bf, int argc, char **argv) {
break; break;
} }
case 3: { // CBEGIN %d %d case CMD_CTRL_CBEGIN: { // CBEGIN %d %d
// NOTE: example not found, no checks done // NOTE: example not found, no checks done
int args_sz = ip_read_int(&s.ip); int args_sz = ip_read_int(&s.ip);
int locals_sz = ip_read_int(&s.ip); int locals_sz = ip_read_int(&s.ip);
@ -302,7 +328,7 @@ void run(bytefile *bf, int argc, char **argv) {
break; break;
} }
case 4: // CLOSURE 0x%.8x case CMD_CTRL_CLOSURE: // CLOSURE 0x%.8x
{ {
aint call_offset = ip_read_int(&s.ip); aint call_offset = ip_read_int(&s.ip);
aint args_count = ip_read_int(&s.ip); aint args_count = ip_read_int(&s.ip);
@ -316,16 +342,14 @@ void run(bytefile *bf, int argc, char **argv) {
} }
s_push(bf->code_ptr + call_offset); s_push(bf->code_ptr + call_offset);
void *closure = Bclosure((aint *)s.sp, args_count); void *closure = Bclosure((aint *)__gc_stack_top, args_count);
push_extra_root(closure);
s_popn(args_count + 1); s_popn(args_count + 1);
s_push(closure); s_push(closure);
pop_extra_root(closure);
break; break;
} }
case 5: { // CALLC %d // call clojure case CMD_CTRL_CALLC: { // CALLC %d // call clojure
aint args_count = ip_read_int(&s.ip); // args count aint args_count = ip_read_int(&s.ip); // args count
call_happened = true; call_happened = true;
@ -336,23 +360,23 @@ void run(bytefile *bf, int argc, char **argv) {
break; break;
} }
case 6: { // CALL 0x%.8x %d // call function case CMD_CTRL_CALL: { // CALL 0x%.8x %d // call function
int call_p = ip_read_int(&s.ip); uint call_p = ip_read_int(&s.ip);
ip_read_int(&s.ip); // args count ip_read_int(&s.ip); // args count
call_happened = true; call_happened = true;
s.is_closure_call = false; s.is_closure_call = false;
s.call_ip = s.ip; s.call_ip = s.ip;
if (call_p < 0) { if (call_p >= bf->code_size) {
s_failure(&s, "negative file offset jumps are not allowed"); s_failure(&s, "jump out of file");
} }
s.ip = bf->code_ptr + call_p; s.ip = bf->code_ptr + call_p;
break; break;
} }
case 7: { // TAG %s %d case CMD_CTRL_TAG: { // TAG %s %d
const char *name = ip_read_string(&s.ip, bf); const char *name = ip_read_string(&s.ip);
aint args_count = ip_read_int(&s.ip); aint args_count = ip_read_int(&s.ip);
#ifdef DEBUG_VERSION #ifdef DEBUG_VERSION
@ -364,18 +388,18 @@ void run(bytefile *bf, int argc, char **argv) {
break; break;
} }
case 8: // ARRAY %d case CMD_CTRL_ARRAY: // ARRAY %d
s_push_i(Barray_patt(s_pop(), BOX(ip_read_int(&s.ip)))); s_push_i(Barray_patt(s_pop(), BOX(ip_read_int(&s.ip))));
break; break;
case 9: { // FAIL %d %d case CMD_CTRL_FAIL: { // FAIL %d %d
int line = ip_read_int(&s.ip); // ?? int line = ip_read_int(&s.ip);
int col = ip_read_int(&s.ip); // ?? int col = ip_read_int(&s.ip);
Bmatch_failure(s_pop(), argv[0], BOX(line), BOX(col)); Bmatch_failure(s_pop(), argv[0], BOX(line), BOX(col));
break; break;
} }
case 10: // LINE %d case CMD_CTRL_LINE: // LINE %d
s.current_line = ip_read_int(&s.ip); s.current_line = ip_read_int(&s.ip);
// maybe some metainfo should be collected // maybe some metainfo should be collected
break; break;
@ -385,28 +409,28 @@ void run(bytefile *bf, int argc, char **argv) {
} }
break; break;
case 6: // PATT pats[l] case CMD_PATT: // PATT pats[l]
// {"=str", "#string", "#array", "#sexp", "#ref", "#val", "#fun"} // {"=str", "#string", "#array", "#sexp", "#ref", "#val", "#fun"}
switch (l) { switch (l) {
case 0: // =str case CMD_PATT_STR: // =str
s_push_i(Bstring_patt(s_pop(), s_pop())); s_push_i(Bstring_patt(s_pop(), s_pop()));
break; break;
case 1: // #string case CMD_PATT_STR_TAG: // #string
s_push_i(Bstring_tag_patt(s_pop())); s_push_i(Bstring_tag_patt(s_pop()));
break; break;
case 2: // #array case CMD_PATT_ARRAY_TAG: // #array
s_push_i(Barray_tag_patt(s_pop())); s_push_i(Barray_tag_patt(s_pop()));
break; break;
case 3: // #sexp case CMD_PATT_SEXP_TAG: // #sexp
s_push_i(Bsexp_tag_patt(s_pop())); s_push_i(Bsexp_tag_patt(s_pop()));
break; break;
case 4: // #ref case CMD_PATT_REF_TAG: // #ref
s_push_i(Bunboxed_patt(s_pop())); s_push_i(Bunboxed_patt(s_pop()));
break; break;
case 5: // #val case CMD_PATT_VAL_TAG: // #val
s_push_i(Bboxed_patt(s_pop())); s_push_i(Bboxed_patt(s_pop()));
break; break;
case 6: // #fun case CMD_PATT_FUN_TAG: // #fun
s_push_i(Bclosure_tag_patt(s_pop())); s_push_i(Bclosure_tag_patt(s_pop()));
break; break;
default: default:
@ -414,45 +438,41 @@ void run(bytefile *bf, int argc, char **argv) {
} }
break; break;
case 7: { case CMD_BUILTIN: {
switch (l) { switch (l) {
case 0: // CALL Lread case CMD_BUILTIN_Lread: // CALL Lread
s_push_i(Lread()); s_push_i(Lread());
break; break;
case 1: // CALL Lwrite case CMD_BUILTIN_Lwrite: // CALL Lwrite
Lwrite(*s_peek_i()); Lwrite(*s_peek_i());
break; break;
case 2: // CALL Llength case CMD_BUILTIN_Llength: // CALL Llength
s_push_i(Llength(s_pop())); s_push_i(Llength(s_pop()));
break; break;
case 3: { // CALL Lstring case CMD_BUILTIN_Lstring: { // CALL Lstring
void *val = s_pop(); void *val = s_pop();
void *str = Lstring((aint *)&val); void *str = Lstring((aint *)&val);
s_push(str); s_push(str);
break; break;
} }
case 4: { // CALL Barray %d case CMD_BUILTIN_Barray: { // CALL Barray %d
size_t elem_count = ip_read_int(&s.ip); size_t elem_count = ip_read_int(&s.ip);
if (elem_count < 0) {
s_failure(&s, "elements count should be >= 0");
}
void **opr_buffer = elem_count > BUFFER_SIZE ? calloc(elem_count, sizeof(void *)) : buffer; void **opr_buffer = elem_count > BUFFER_SIZE
? alloc(elem_count * sizeof(void *))
: buffer;
for (size_t i = 0; i < elem_count; ++i) { for (size_t i = 0; i < elem_count; ++i) {
opr_buffer[elem_count - i - 1] = s_pop(); opr_buffer[elem_count - i - 1] = s_pop();
} }
void *array = void *array =
Barray((aint *)opr_buffer, BOX(elem_count)); // NOTE: not shure if elems should be added Barray((aint *)opr_buffer,
BOX(elem_count)); // NOTE: not shure if elems should be added
s_push(array); s_push(array);
if (elem_count > BUFFER_SIZE) {
free(opr_buffer);
}
break; break;
} }

View file

@ -6,6 +6,7 @@
#include "../../runtime/runtime.h" #include "../../runtime/runtime.h"
#include "types.h"
#include "utils.h" #include "utils.h"
#include "parser.h" #include "parser.h"
@ -66,90 +67,90 @@ bytefile* read_file (char *fname) {
} }
const char *read_cmd(char *ip) { const char *read_cmd(char *ip) {
char x = (*ip++), h = (x & 0xF0) >> 4, l = x & 0x0F; uint8_t x = (*ip++), h = (x & 0xF0) >> 4, l = x & 0x0F;
switch (h) { switch (h) {
case 15: case CMD_EXIT:
return "END"; return "END";
case 0: case CMD_BINOP:
return "BINOP"; return "BINOP";
case 1: case CMD_BASIC:
switch (l) { switch (l) {
case 0: case CMD_BASIC_CONST:
return "CONST"; return "CONST";
case 1: case CMD_BASIC_STRING:
return "STRING"; return "STRING";
case 2: case CMD_BASIC_SEXP:
return "SEXP "; return "SEXP ";
case 3: case CMD_BASIC_STI:
return "STI"; return "STI";
case 4: case CMD_BASIC_STA:
return "STA"; return "STA";
case 5: case CMD_BASIC_JMP:
return "JMP"; return "JMP";
case 6: case CMD_BASIC_END:
return "END"; return "END";
case 7: case CMD_BASIC_RET:
return "RET"; return "RET";
case 8: case CMD_BASIC_DROP:
return "DROP"; return "DROP";
case 9: case CMD_BASIC_DUP:
return "DUP"; return "DUP";
case 10: case CMD_BASIC_SWAP:
return "SWAP"; return "SWAP";
case 11: case CMD_BASIC_ELEM:
return "ELEM"; return "ELEM";
default: default:
return "_UNDEF_CMD1_"; return "_UNDEF_CMD1_";
} }
break; break;
case 2: case CMD_LD:
return "LD"; return "LD";
case 3: case CMD_LDA:
return "LDA"; return "LDA";
case 4: case CMD_ST:
return "ST"; return "ST";
case 5: case CMD_CTRL:
switch (l) { switch (l) {
case 0: case CMD_CTRL_CJMPz:
return "CJMPz"; return "CJMPz";
case 1: case CMD_CTRL_CJMPnz:
return "CJMPnz"; return "CJMPnz";
case 2: case CMD_CTRL_BEGIN:
return "BEGIN"; return "BEGIN";
case 3: case CMD_CTRL_CBEGIN:
return "CBEGIN"; return "CBEGIN";
case 4: case CMD_CTRL_CLOSURE:
return "CLOSURE"; return "CLOSURE";
case 5: case CMD_CTRL_CALLC:
return "CALLC"; return "CALLC";
case 6: case CMD_CTRL_CALL:
return "CALL"; return "CALL";
case 7: case CMD_CTRL_TAG:
return "TAG"; return "TAG";
case 8: case CMD_CTRL_ARRAY:
return "ARRAY"; return "ARRAY";
case 9: case CMD_CTRL_FAIL:
return "FAIL"; return "FAIL";
case 10: case CMD_CTRL_LINE:
return "LINE"; return "LINE";
default: default:
return "_UNDEF_CMD5_"; return "_UNDEF_CMD5_";
} }
case 6: case CMD_PATT:
return "PATT"; return "PATT";
case 7: { case CMD_BUILTIN: {
switch (l) { switch (l) {
case 0: case CMD_BUILTIN_Lread:
return "CALL\tLread"; return "CALL\tLread";
case 1: case CMD_BUILTIN_Lwrite:
return "CALL\tLwrite"; return "CALL\tLwrite";
case 2: case CMD_BUILTIN_Llength:
return "CALL\tLlength"; return "CALL\tLlength";
case 3: case CMD_BUILTIN_Lstring:
return "CALL\tLstring"; return "CALL\tLstring";
case 4: case CMD_BUILTIN_Barray:
return "CALL\tBarray\t%d"; return "CALL\tBarray\t%d";
default: default:
return "_UNDEF_CALL_"; return "_UNDEF_CALL_";
@ -160,225 +161,225 @@ const char *read_cmd(char *ip) {
} }
} }
/* Disassembles the bytecode pool */ // /* Disassembles the bytecode pool */
void disassemble (FILE *f, bytefile *bf) { // void disassemble (FILE *f, bytefile *bf) {
# define INT (ip += sizeof (int), *(int*)(ip - sizeof (int))) // # define INT (ip += sizeof (int), *(int*)(ip - sizeof (int)))
# define BYTE *ip++ // # define BYTE *ip++
# define STRING get_string (bf, INT) // # define STRING get_string (bf, INT)
# define FAIL failure ("ERROR: invalid opcode %d-%d\n", h, l) // # define FAIL failure ("ERROR: invalid opcode %d-%d\n", h, l)
char *ip = bf->code_ptr; // char *ip = bf->code_ptr;
char *ops [] = {"+", "-", "*", "/", "%", "<", "<=", ">", ">=", "==", "!=", "&&", "!!"}; // char *ops [] = {"+", "-", "*", "/", "%", "<", "<=", ">", ">=", "==", "!=", "&&", "!!"};
char *pats[] = {"=str", "#string", "#array", "#sexp", "#ref", "#val", "#fun"}; // char *pats[] = {"=str", "#string", "#array", "#sexp", "#ref", "#val", "#fun"};
char *lds [] = {"LD", "LDA", "ST"}; // char *lds [] = {"LD", "LDA", "ST"};
do { // do {
char x = BYTE, // uint8_t x = BYTE,
h = (x & 0xF0) >> 4, // h = (x & 0xF0) >> 4,
l = x & 0x0F; // l = x & 0x0F;
fprintf (f, "0x%.8x:\t", ip-bf->code_ptr-1); // fprintf (f, "0x%.8x:\t", ip-bf->code_ptr-1);
switch (h) { // switch (h) {
case 15: // case 15:
goto stop; // goto stop;
/* BINOP */ // /* BINOP */
case 0: // case 0:
fprintf (f, "BINOP\t%s", ops[l-1]); // fprintf (f, "BINOP\t%s", ops[l-1]);
break; // break;
case 1: // case 1:
switch (l) { // switch (l) {
case 0: // case 0:
fprintf (f, "CONST\t%d", INT); // fprintf (f, "CONST\t%d", INT);
break; // break;
case 1: // case 1:
fprintf (f, "STRING\t%s", STRING); // fprintf (f, "STRING\t%s", STRING);
break; // break;
case 2: // case 2:
fprintf (f, "SEXP\t%s ", STRING); // fprintf (f, "SEXP\t%s ", STRING);
fprintf (f, "%d", INT); // fprintf (f, "%d", INT);
break; // break;
case 3: // case 3:
fprintf (f, "STI"); // fprintf (f, "STI");
break; // break;
case 4: // case 4:
fprintf (f, "STA"); // fprintf (f, "STA");
break; // break;
case 5: // case 5:
fprintf (f, "JMP\t0x%.8x", INT); // fprintf (f, "JMP\t0x%.8x", INT);
break; // break;
case 6: // case 6:
fprintf (f, "END"); // fprintf (f, "END");
break; // break;
case 7: // case 7:
fprintf (f, "RET"); // fprintf (f, "RET");
break; // break;
case 8: // case 8:
fprintf (f, "DROP"); // fprintf (f, "DROP");
break; // break;
case 9: // case 9:
fprintf (f, "DUP"); // fprintf (f, "DUP");
break; // break;
case 10: // case 10:
fprintf (f, "SWAP"); // fprintf (f, "SWAP");
break; // break;
case 11: // case 11:
fprintf (f, "ELEM"); // fprintf (f, "ELEM");
break; // break;
default: // default:
FAIL; // FAIL;
} // }
break; // break;
case 2: // case 2:
case 3: // case 3:
case 4: // case 4:
fprintf (f, "%s\t", lds[h-2]); // fprintf (f, "%s\t", lds[h-2]);
switch (l) { // switch (l) {
case 0: fprintf (f, "G(%d)", INT); break; // case 0: fprintf (f, "G(%d)", INT); break;
case 1: fprintf (f, "L(%d)", INT); break; // case 1: fprintf (f, "L(%d)", INT); break;
case 2: fprintf (f, "A(%d)", INT); break; // case 2: fprintf (f, "A(%d)", INT); break;
case 3: fprintf (f, "C(%d)", INT); break; // case 3: fprintf (f, "C(%d)", INT); break;
default: FAIL; // default: FAIL;
} // }
break; // break;
case 5: // case 5:
switch (l) { // switch (l) {
case 0: // case 0:
fprintf (f, "CJMPz\t0x%.8x", INT); // fprintf (f, "CJMPz\t0x%.8x", INT);
break; // break;
case 1: // case 1:
fprintf (f, "CJMPnz\t0x%.8x", INT); // fprintf (f, "CJMPnz\t0x%.8x", INT);
break; // break;
case 2: // case 2:
fprintf (f, "BEGIN\t%d ", INT); // fprintf (f, "BEGIN\t%d ", INT);
fprintf (f, "%d", INT); // fprintf (f, "%d", INT);
break; // break;
case 3: // case 3:
fprintf (f, "CBEGIN\t%d ", INT); // fprintf (f, "CBEGIN\t%d ", INT);
fprintf (f, "%d", INT); // fprintf (f, "%d", INT);
break; // break;
case 4: // case 4:
fprintf (f, "CLOSURE\t0x%.8x", INT); // fprintf (f, "CLOSURE\t0x%.8x", INT);
{int n = INT; // {int n = INT;
for (int i = 0; i<n; i++) { // for (int i = 0; i<n; i++) {
switch (BYTE) { // switch (BYTE) {
case 0: fprintf (f, "G(%d)", INT); break; // case 0: fprintf (f, "G(%d)", INT); break;
case 1: fprintf (f, "L(%d)", INT); break; // case 1: fprintf (f, "L(%d)", INT); break;
case 2: fprintf (f, "A(%d)", INT); break; // case 2: fprintf (f, "A(%d)", INT); break;
case 3: fprintf (f, "C(%d)", INT); break; // case 3: fprintf (f, "C(%d)", INT); break;
default: FAIL; // default: FAIL;
} // }
} // }
}; // };
break; // break;
case 5: // case 5:
fprintf (f, "CALLC\t%d", INT); // fprintf (f, "CALLC\t%d", INT);
break; // break;
case 6: // case 6:
fprintf (f, "CALL\t0x%.8x ", INT); // fprintf (f, "CALL\t0x%.8x ", INT);
fprintf (f, "%d", INT); // fprintf (f, "%d", INT);
break; // break;
case 7: // case 7:
fprintf (f, "TAG\t%s ", STRING); // fprintf (f, "TAG\t%s ", STRING);
fprintf (f, "%d", INT); // fprintf (f, "%d", INT);
break; // break;
case 8: // case 8:
fprintf (f, "ARRAY\t%d", INT); // fprintf (f, "ARRAY\t%d", INT);
break; // break;
case 9: // case 9:
fprintf (f, "FAIL\t%d", INT); // fprintf (f, "FAIL\t%d", INT);
fprintf (f, "%d", INT); // fprintf (f, "%d", INT);
break; // break;
case 10: // case 10:
fprintf (f, "LINE\t%d", INT); // fprintf (f, "LINE\t%d", INT);
break; // break;
default: // default:
FAIL; // FAIL;
} // }
break; // break;
case 6: // case 6:
fprintf (f, "PATT\t%s", pats[l]); // fprintf (f, "PATT\t%s", pats[l]);
break; // break;
case 7: { // case 7: {
switch (l) { // switch (l) {
case 0: // case 0:
fprintf (f, "CALL\tLread"); // fprintf (f, "CALL\tLread");
break; // break;
case 1: // case 1:
fprintf (f, "CALL\tLwrite"); // fprintf (f, "CALL\tLwrite");
break; // break;
case 2: // case 2:
fprintf (f, "CALL\tLlength"); // fprintf (f, "CALL\tLlength");
break; // break;
case 3: // case 3:
fprintf (f, "CALL\tLstring"); // fprintf (f, "CALL\tLstring");
break; // break;
case 4: // case 4:
fprintf (f, "CALL\tBarray\t%d", INT); // fprintf (f, "CALL\tBarray\t%d", INT);
break; // break;
default: // default:
FAIL; // FAIL;
} // }
} // }
break; // break;
default: // default:
FAIL; // FAIL;
} // }
fprintf (f, "\n"); // fprintf (f, "\n");
} // }
while (1); // while (1);
stop: fprintf (f, "<end>\n"); // stop: fprintf (f, "<end>\n");
} // }
/* Dumps the contents of the file */ // /* Dumps the contents of the file */
void dump_file (FILE *f, bytefile *bf) { // void dump_file (FILE *f, bytefile *bf) {
size_t i; // size_t i;
fprintf (f, "String table size : %d\n", bf->stringtab_size); // fprintf (f, "String table size : %d\n", bf->stringtab_size);
fprintf (f, "Global area size : %d\n", bf->global_area_size); // fprintf (f, "Global area size : %d\n", bf->global_area_size);
fprintf (f, "Number of public symbols: %d\n", bf->public_symbols_number); // fprintf (f, "Number of public symbols: %d\n", bf->public_symbols_number);
fprintf (f, "Public symbols :\n"); // fprintf (f, "Public symbols :\n");
for (i=0; i < bf->public_symbols_number; i++) // for (i=0; i < bf->public_symbols_number; i++)
fprintf (f, " 0x%.8x: %s\n", get_public_offset (bf, i), get_public_name (bf, i)); // fprintf (f, " 0x%.8x: %s\n", get_public_offset (bf, i), get_public_name (bf, i));
fprintf (f, "Code:\n"); // fprintf (f, "Code:\n");
disassemble (f, bf); // disassemble (f, bf);
} // }

View file

@ -26,14 +26,14 @@ static void init_state(bytefile *bf, struct State* s, void** stack) {
// printf("%p:%zu - %zu", s->stack, (size_t)s->stack, (size_t)s->stack & 0xF); // printf("%p:%zu - %zu", s->stack, (size_t)s->stack, (size_t)s->stack & 0xF);
s->sp = s->stack + STACK_SIZE; // [top -> bottom] stack // s->sp = s->stack + STACK_SIZE; // [top -> bottom] stack
s->fp = NULL; s->fp = NULL;
} }
void construct_state(bytefile *bf, struct State* s, void** stack) { void construct_state(bytefile *bf, struct State* s, void** stack) {
__init(); __init();
init_state(bf, s, stack); init_state(bf, s, stack);
__gc_stack_bottom = (size_t)s->sp; __gc_stack_bottom = (size_t)(s->stack + STACK_SIZE);
__gc_stack_top = __gc_stack_bottom; __gc_stack_top = __gc_stack_bottom;
s_pushn_nil(bf->global_area_size); s_pushn_nil(bf->global_area_size);
@ -47,7 +47,7 @@ void construct_state(bytefile *bf, struct State* s, void** stack) {
static void destruct_state(struct State* state) { static void destruct_state(struct State* state) {
// free(state->stack); // free(state->stack);
state->sp = NULL; // state->sp = NULL;
state->fp = NULL; state->fp = NULL;
state->ip = NULL; state->ip = NULL;
state->call_ip = NULL; state->call_ip = NULL;

View file

@ -63,7 +63,7 @@ void *alloc (size_t size) {
size = BYTES_TO_WORDS(size); size = BYTES_TO_WORDS(size);
size_t padding = size * sizeof(size_t) - obj_size; size_t padding = size * sizeof(size_t) - obj_size;
#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) #if defined(DEBUG_VERSION) && defined(DEBUG_PRINT)
fprintf(stderr, "allocation of size %zu words (%zu bytes): ", size, bytes_sz); fprintf(stderr, "allocation of size %zu words (%zu bytes): ", size, padding);
#endif #endif
void *p = gc_alloc_on_existing_heap(size); void *p = gc_alloc_on_existing_heap(size);
if (!p) { if (!p) {

View file

@ -15,11 +15,9 @@ extern size_t __gc_stack_top, __gc_stack_bottom;
flag = __gc_stack_top == 0; \ flag = __gc_stack_top == 0; \
if (flag) { __gc_stack_top = (size_t)__builtin_frame_address(0); } \ if (flag) { __gc_stack_top = (size_t)__builtin_frame_address(0); } \
assert(__gc_stack_top != 0); \ assert(__gc_stack_top != 0); \
assert((__gc_stack_top & 0xF) == 0); \ assert((__gc_stack_top & 0x7) == 0);
assert(__builtin_frame_address(0) <= (void *)__gc_stack_top);
#define POST_GC() \ #define POST_GC() \
assert(__builtin_frame_address(0) <= (void *)__gc_stack_top); \
if (flag) { __gc_stack_top = 0; } if (flag) { __gc_stack_top = 0; }
_Noreturn static void vfailure (char *s, va_list args) { _Noreturn static void vfailure (char *s, va_list args) {