mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-06 06:48:48 +00:00
runtime fixes, byterun fixes
This commit is contained in:
parent
233fa95e14
commit
e456304eb3
11 changed files with 513 additions and 411 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue