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

View file

@ -8,4 +8,4 @@ const char *read_cmd(char *ip);
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;
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() {
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 false;
@ -26,39 +27,38 @@ static inline void **s_nth(aint n) {
if (n < 0) {
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");
}
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");
}
return s.sp + n;
return (void **)__gc_stack_top + n;
}
static inline void **s_peek() {
if (s.sp == s_top()) {
if ((void **)__gc_stack_top == s_top()) {
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");
}
return s.sp;
return (void **)__gc_stack_top;
}
static inline aint *s_peek_i() { return (aint *)s_peek(); }
static inline void s_push(void *val) {
if (s.sp == s.stack) {
if ((void **)__gc_stack_top == s.stack) {
s_failure(&s, "stack overflow");
}
#ifdef DEBUG_VERSION
printf("--> push\n");
#endif
--s.sp;
*s.sp = val;
__gc_stack_top = (size_t)(s.sp) - (size_t)(s.sp) & 0xF;
__gc_stack_top -= sizeof(void *);
*(void **)__gc_stack_top = 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() {
if (s.sp == s_top()) {
if ((void **)__gc_stack_top == s_top()) {
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");
}
#ifdef DEBUG_VERSION
printf("--> pop\n");
#endif
void *value = *s.sp;
*s.sp = NULL;
++s.sp;
__gc_stack_top = (size_t)(s.sp) - (size_t)(s.sp) & 0xF;
void *value = *(void **)__gc_stack_top;
// *(void **)__gc_stack_top = NULL;
__gc_stack_top += sizeof(void *);
return value;
}
@ -112,11 +111,13 @@ static inline void s_enter_f(char *rp, bool is_closure_call, auint args_sz,
#endif
// 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");
}
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");
}
@ -136,7 +137,7 @@ static inline void s_enter_f(char *rp, bool is_closure_call, auint args_sz,
};
// put frame on stack
s.fp = (struct Frame *)s.sp;
s.fp = (struct Frame *)__gc_stack_top;
(*s.fp) = frame;
s_pushn_nil(locals_sz);
@ -148,10 +149,9 @@ static inline void s_exit_f() {
}
struct Frame frame = *s.fp;
push_extra_root((void **)&frame.ret);
// 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);
#ifdef DEBUG_VERSION
printf("-> %zu to pop\n", to_pop);
@ -170,13 +170,11 @@ static inline void s_exit_f() {
}
s.ip = frame.rp;
pop_extra_root((void **)&frame.ret);
}
static inline void print_stack() {
printf("stack (%i) is\n[", s.stack + STACK_SIZE - s.sp);
for (void **x = s.stack + STACK_SIZE - 1; x >= s.sp; --x) {
printf("stack (%i) is\n[", s.stack + STACK_SIZE - (void **)__gc_stack_top);
for (void **x = s.stack + STACK_SIZE - 1; x >= (void **)__gc_stack_top; --x) {
printf("%li ", (long)UNBOX(*x));
}
printf("]\n");
@ -207,7 +205,8 @@ static inline void **var_by_category(enum VarCategory category, int id) {
// f_locals_sz(s.fp));
}
// 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);
break;
case VAR_ARGUMENT:

View file

@ -53,7 +53,7 @@ static inline void **f_args(struct Frame *fp) {
struct State {
void **stack;
void **sp; // stack pointer
// void **sp; // stack pointer
struct Frame *fp; // function frame pointer
bytefile *bf;
int current_line;
@ -90,3 +90,78 @@ static inline enum VarCategory to_var_category(uint8_t 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];
} 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,
const char *msg) {
failure("*** RUNTIME ERROR: %i(0x%.8x):%s error: %s\n", line, offset, cmd,
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];
}