mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-06 06:48:48 +00:00
part of operations, migration to 1.30
This commit is contained in:
parent
2c03654cca
commit
e17f1f70ed
8 changed files with 166 additions and 137 deletions
|
|
@ -1,7 +1,7 @@
|
|||
FLAGS=-m32 -g2 -fstack-protector-all
|
||||
|
||||
all: src/cli.c src/parser.c src/interpreter.c src/utils.c src/types.c src/virt_stack.c
|
||||
$(CC) $(FLAGS) -o byterun -Iinclude/ src/utils.c src/parser.c src/virt_stack.c src/interpreter.c src/cli.c ../runtime/runtime.a
|
||||
all: src/cli.c src/parser.c src/interpreter.c src/utils.c src/types.c src/stack.c
|
||||
$(CC) $(FLAGS) -o byterun -Iinclude/ src/cli.c src/parser.c src/interpreter.c src/utils.c src/types.c src/stack.c ../runtime/runtime.a
|
||||
|
||||
clean:
|
||||
$(RM) *.a *.o *~ byterun
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
(rule
|
||||
(target byterun.exe)
|
||||
(deps
|
||||
(:main byterun.c)
|
||||
(:main src/cli.c src/interpreter.c)
|
||||
(:parser src/parser.c)
|
||||
(:utils src/utils.c src/types.c src/stack.c)
|
||||
(:runtime ../runtime/runtime.a))
|
||||
(mode
|
||||
(promote (until-clean)))
|
||||
(action
|
||||
(run gcc -g %{main} %{runtime} -o %{target})))
|
||||
(run gcc -g -Iinclude/ %{main} %{runtime} -o %{target})))
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
|
@ -16,126 +18,123 @@
|
|||
|
||||
// ---
|
||||
|
||||
void *Bsexp(int n, ...);
|
||||
int LtagHash(char *);
|
||||
void Lassert(void *f, char *s, ...);
|
||||
|
||||
// Gets a raw data_header
|
||||
int LkindOf(void *p);
|
||||
aint LkindOf(void *p);
|
||||
|
||||
// Compare s-exprs tags
|
||||
int LcompareTags(void *p, void *q);
|
||||
aint LcompareTags(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator ":";
|
||||
void *Ls__Infix_58(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator "!!";
|
||||
int Ls__Infix_3333(void *p, void *q);
|
||||
aint Ls__Infix_3333(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator "&&";
|
||||
int Ls__Infix_3838(void *p, void *q);
|
||||
aint Ls__Infix_3838(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator "==";
|
||||
int Ls__Infix_6161(void *p, void *q);
|
||||
aint Ls__Infix_6161(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator "!=";
|
||||
int Ls__Infix_3361(void *p, void *q);
|
||||
aint Ls__Infix_3361(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator "<=";
|
||||
int Ls__Infix_6061(void *p, void *q);
|
||||
aint Ls__Infix_6061(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator "<";
|
||||
int Ls__Infix_60(void *p, void *q);
|
||||
aint Ls__Infix_60(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator ">=";
|
||||
int Ls__Infix_6261(void *p, void *q);
|
||||
aint Ls__Infix_6261(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator ">";
|
||||
int Ls__Infix_62(void *p, void *q);
|
||||
aint Ls__Infix_62(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator "+";
|
||||
int Ls__Infix_43(void *p, void *q);
|
||||
aint Ls__Infix_43(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator "-";
|
||||
int Ls__Infix_45(void *p, void *q);
|
||||
aint Ls__Infix_45(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator "*";
|
||||
int Ls__Infix_42(void *p, void *q);
|
||||
aint Ls__Infix_42(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator "/";
|
||||
int Ls__Infix_47(void *p, void *q);
|
||||
aint Ls__Infix_47(void *p, void *q);
|
||||
|
||||
// Functional synonym for built-in operator "%";
|
||||
int Ls__Infix_37(void *p, void *q);
|
||||
aint Ls__Infix_37(void *p, void *q);
|
||||
|
||||
int Llength(void *p);
|
||||
aint Llength(void *p);
|
||||
|
||||
int LtagHash(char *s);
|
||||
char *de_hash(int n);
|
||||
aint LtagHash(char *s);
|
||||
char *de_hash(aint n);
|
||||
|
||||
int Luppercase(void *v);
|
||||
aint Luppercase(void *v);
|
||||
|
||||
int Llowercase(void *v);
|
||||
aint Llowercase(void *v);
|
||||
|
||||
int LmatchSubString(char *subj, char *patt, int pos);
|
||||
aint LmatchSubString(char *subj, char *patt, aint pos);
|
||||
|
||||
void *Lsubstring(void *subj, int p, int l);
|
||||
void *Lsubstring(aint *args /*void *subj, aint p, aint l*/);
|
||||
|
||||
struct re_pattern_buffer *Lregexp(char *regexp);
|
||||
regex_t *Lregexp(char *regexp);
|
||||
|
||||
int LregexpMatch(struct re_pattern_buffer *b, char *s, int pos);
|
||||
|
||||
void *Bstring(void *p);
|
||||
aint LregexpMatch(struct re_pattern_buffer *b, char *s, aint pos);
|
||||
|
||||
void *Lclone(void *p);
|
||||
|
||||
int inner_hash(int depth, unsigned acc, void *p);
|
||||
aint inner_hash(aint depth, auint acc, void *p);
|
||||
|
||||
void *LstringInt(char *b);
|
||||
|
||||
int Lhash(void *p);
|
||||
aint Lhash(void *p);
|
||||
|
||||
int LflatCompare(void *p, void *q);
|
||||
int Lcompare(void *p, void *q);
|
||||
aint LflatCompare(void *p, void *q);
|
||||
aint Lcompare(void *p, void *q);
|
||||
|
||||
void *Belem(void *p, int i);
|
||||
void *Belem(void *p, aint i);
|
||||
|
||||
void *LmakeArray(int length);
|
||||
void *LmakeString(int length);
|
||||
void *LmakeArray(aint length);
|
||||
void *LmakeString(aint length);
|
||||
|
||||
void *Bstring(void *p);
|
||||
void *Lstringcat(void *p);
|
||||
void *Lstring(void *p);
|
||||
void *Bstring(aint *args /*void *p*/);
|
||||
void *Lstringcat(aint *args /* void* p */);
|
||||
void *Lstring(aint *args /* void *p */);
|
||||
|
||||
void *Bclosure(int bn, void *entry, ...);
|
||||
void *Barray(int bn, ...);
|
||||
void *Bsexp(int bn, ...);
|
||||
int Btag(void *d, int t, int n);
|
||||
void *Bclosure(aint *args, aint bn);
|
||||
void *Barray(aint *args, aint bn);
|
||||
void *Bsexp(aint *args, aint bn);
|
||||
aint Btag(void *d, aint t, aint n);
|
||||
|
||||
int get_tag(data *d);
|
||||
int get_len(data *d);
|
||||
aint get_tag(data *d);
|
||||
aint get_len(data *d);
|
||||
|
||||
int Barray_patt(void *d, int n);
|
||||
int Bstring_patt(void *x, void *y);
|
||||
int Bclosure_tag_patt(void *x);
|
||||
int Bboxed_patt(void *x);
|
||||
int Bunboxed_patt(void *x);
|
||||
int Barray_tag_patt(void *x);
|
||||
int Bstring_tag_patt(void *x);
|
||||
int Bsexp_tag_patt(void *x);
|
||||
aint Barray_patt(void *d, aint n);
|
||||
aint Bstring_patt(void *x, void *y);
|
||||
aint Bclosure_tag_patt(void *x);
|
||||
aint Bboxed_patt(void *x);
|
||||
aint Bunboxed_patt(void *x);
|
||||
aint Barray_tag_patt(void *x);
|
||||
aint Bstring_tag_patt(void *x);
|
||||
aint Bsexp_tag_patt(void *x);
|
||||
|
||||
void *Bsta(void *v, int i, void *x);
|
||||
void *Bsta(void *v, aint i, void *x);
|
||||
|
||||
void Lfailure(char *s, ...);
|
||||
void LprintfPerror(char *s, ...);
|
||||
|
||||
void Bmatch_failure(void *v, char *fname, int line, int col);
|
||||
void Bmatch_failure(void *v, char *fname, aint line, aint col);
|
||||
|
||||
void * /*Lstrcat*/ Li__Infix_4343(void *a, void *b);
|
||||
|
||||
void *Lsprintf(char *fmt, ...);
|
||||
void *LgetEnv(char *var);
|
||||
|
||||
int Lsystem(char *cmd);
|
||||
aint Lsystem(char *cmd);
|
||||
|
||||
void Lfprintf(FILE *f, char *s, ...);
|
||||
void Lprintf(char *s, ...);
|
||||
|
|
@ -152,17 +151,17 @@ void *Lhd(void *v);
|
|||
void *Ltl(void *v);
|
||||
|
||||
/* Lread is an implementation of the "read" construct */
|
||||
int Lread();
|
||||
aint Lread();
|
||||
|
||||
int Lbinoperror(void);
|
||||
aint Lbinoperror(void);
|
||||
|
||||
int Lbinoperror2(void);
|
||||
aint Lbinoperror2(void);
|
||||
|
||||
/* Lwrite is an implementation of the "write" construct */
|
||||
int Lwrite(int n);
|
||||
aint Lwrite(aint n);
|
||||
|
||||
int Lrandom(int n);
|
||||
aint Lrandom(aint n);
|
||||
|
||||
int Ltime();
|
||||
aint Ltime();
|
||||
|
||||
void set_args(int argc, char *argv[]);
|
||||
void set_args(aint argc, char *argv[]);
|
||||
|
|
|
|||
|
|
@ -8,13 +8,12 @@
|
|||
#include "stdlib.h"
|
||||
|
||||
void s_push(struct State *s, void *val);
|
||||
|
||||
void s_push_i(struct State *s, aint val);
|
||||
void s_push_nil(struct State *s);
|
||||
|
||||
void s_pushn_nil(struct State *s, size_t n);
|
||||
|
||||
void *s_pop(struct State *s);
|
||||
|
||||
aint s_pop_i(struct State *s);
|
||||
void s_popn(struct State *s, size_t n);
|
||||
|
||||
// ------ functions ------
|
||||
|
|
@ -25,13 +24,9 @@ void s_popn(struct State *s, size_t n);
|
|||
//
|
||||
// where |> defines corresponding frame pointer, | is stack pointer
|
||||
// location before / after new frame added
|
||||
void s_enter_f(struct State *s, char *func_ip, size_t params_sz,
|
||||
size_t locals_sz);
|
||||
void s_enter_f(struct State *s, char *func_ip, auint params_sz,
|
||||
auint locals_sz);
|
||||
|
||||
void s_exit_f(struct State *s);
|
||||
|
||||
void **var_by_category(struct State *s, enum VarCategory category, int id);
|
||||
|
||||
// --- changed runtime operations ---
|
||||
|
||||
void *s_Bsexp(struct State *state, int bn, int tag);
|
||||
|
|
|
|||
|
|
@ -16,23 +16,21 @@ enum Type {
|
|||
|
||||
static const size_t MAX_ARRAY_SIZE = 0x11111110;
|
||||
|
||||
static inline union VarT *to_var(struct NilT *var) { return (union VarT *)var; }
|
||||
|
||||
// ------ Frame ------
|
||||
|
||||
struct Frame {
|
||||
void *ret; // store returned value [gc pointer]
|
||||
char *rp; // ret instruction pointer [not gc pointer]
|
||||
size_t to_prev_fp_box; // ret function frame pointer [boxed value, not gc
|
||||
aint to_prev_fp_box; // ret function frame pointer [boxed value, not gc
|
||||
// pointer]
|
||||
size_t args_sz_box; // store arguments [boxed value, not gc pointer]
|
||||
size_t locals_sz_box; // store locals [boxed value, not gc pointer]
|
||||
aint args_sz_box; // store arguments [boxed value, not gc pointer]
|
||||
aint locals_sz_box; // store locals [boxed value, not gc pointer]
|
||||
};
|
||||
|
||||
size_t frame_sz();
|
||||
auint frame_sz();
|
||||
void **f_prev_fp(struct Frame *fp);
|
||||
uint64_t f_locals_sz(struct Frame *fp);
|
||||
uint64_t f_args_sz(struct Frame *fp);
|
||||
auint f_locals_sz(struct Frame *fp);
|
||||
auint f_args_sz(struct Frame *fp);
|
||||
void **f_locals(struct Frame *fp);
|
||||
void **f_args(struct Frame *fp);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#include "stack.h"
|
||||
#include "runtime_externs.h"
|
||||
|
||||
extern size_t STACK_SIZE;
|
||||
|
||||
int ip_read_int(char** ip) {
|
||||
*ip += sizeof(int);
|
||||
return *(int*)((*ip) - sizeof(int));
|
||||
|
|
@ -28,7 +30,7 @@ void run(bytefile *bf) {
|
|||
|
||||
const size_t OPS_SIZE = 13;
|
||||
const char *ops [] = {"+", "-", "*", "/", "%", "<", "<=", ">", ">=", "==", "!=", "&&", "!!"};
|
||||
int(*ops_func[])(void*, void*) = {
|
||||
aint(*ops_func[])(void*, void*) = {
|
||||
&Ls__Infix_43, // +
|
||||
&Ls__Infix_45, // -
|
||||
&Ls__Infix_42, // *
|
||||
|
|
@ -75,16 +77,19 @@ void run(bytefile *bf) {
|
|||
case 1:
|
||||
switch (l) {
|
||||
case 0: // CONST %d
|
||||
s_push(&s, (void*)BOX(ip_read_int(&s.ip)));
|
||||
s_push_i(&s, BOX(ip_read_int(&s.ip)));
|
||||
break;
|
||||
|
||||
case 1: // STRING %s
|
||||
s_push(&s, Bstring((void*)ip_read_string(&s.ip, bf)));
|
||||
case 1: { // STRING %s
|
||||
void* str = ip_read_string(&s.ip, bf);
|
||||
s_push(&s, Bstring((aint*)&str));
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: // SEXP %s %d // create sexpr with tag=%s and %d elements from stack
|
||||
// params read from stack
|
||||
s_put_sexp(&s, ip_read_string(&s.ip, bf), ip_read_int(&s.ip));
|
||||
s_push_i(&s, LtagHash(ip_read_string(&s.ip, bf)));
|
||||
Bsexp((aint*)s.sp, ip_read_int(&s.ip)); // TODO: check order
|
||||
break;
|
||||
|
||||
case 3: // STI
|
||||
|
|
@ -108,12 +113,12 @@ void run(bytefile *bf) {
|
|||
break;
|
||||
|
||||
case 8: // DROP
|
||||
s_drop_var(&s);
|
||||
s_pop(&s);
|
||||
break;
|
||||
|
||||
case 9: // DUP
|
||||
{ // guess
|
||||
if (s.sp == s.stack || (s.fp != NULL && s.sp == s.fp->end)) {
|
||||
{
|
||||
if (s.sp == s.stack + STACK_SIZE || (s.fp != NULL && s.sp == f_locals(s.fp))) {
|
||||
failure("can't DUP: no value on stack");
|
||||
}
|
||||
*s.sp = *(s.sp - 1);
|
||||
|
|
@ -123,32 +128,22 @@ void run(bytefile *bf) {
|
|||
|
||||
case 10: // SWAP
|
||||
{ // guess
|
||||
struct NilT* v = *s.sp;
|
||||
*s.sp = *(s.sp - 1);
|
||||
*(s.sp - 1) = v;
|
||||
if (s.sp + 1 >= s.stack + STACK_SIZE || (s.fp != NULL && s.sp + 1 >= f_locals(s.fp))) {
|
||||
failure("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;
|
||||
|
||||
case 11: // ELEM
|
||||
{
|
||||
union VarT* array = s_take_var(&s);
|
||||
union VarT* index = s_take_var(&s);
|
||||
if (dh_type(array->nil.data_header) != ARRAY_T) {
|
||||
failure("ELEM: elem, previous element is not array");
|
||||
}
|
||||
if (dh_type(index->nil.data_header) != INT_T) {
|
||||
failure("ELEM: elem, last element is not int");
|
||||
}
|
||||
if (index->int_t.value < 0) {
|
||||
failure("ELEM: can't access by index < 0");
|
||||
}
|
||||
if (index->int_t.value >= dh_param(array->array.data_header)) {
|
||||
failure("ELEM: array index is out of range");
|
||||
}
|
||||
s_put_var(&s, array->array.values[index->int_t.value]);
|
||||
|
||||
free_var_ptr(array);
|
||||
free_var_ptr(index);
|
||||
void* array = s_pop(&s);
|
||||
aint index = s_pop_i(&s);
|
||||
s_push(&s, Belem(array, index));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -159,34 +154,34 @@ void run(bytefile *bf) {
|
|||
|
||||
case 2: { // LD %d
|
||||
int8_t category = ip_read_byte(&s.ip);
|
||||
union VarT** var_ptr = var_by_category(&s, to_var_category(category), ip_read_int(&s.ip));
|
||||
s_put_var(&s, (struct NilT*)*var_ptr); // TODO: check
|
||||
void** var_ptr = var_by_category(&s, to_var_category(category), ip_read_int(&s.ip));
|
||||
s_push(&s, *var_ptr);
|
||||
break;
|
||||
}
|
||||
case 3: { // LDA %d
|
||||
int8_t category = ip_read_byte(&s.ip);
|
||||
union VarT** var_ptr = var_by_category(&s, to_var_category(category), ip_read_int(&s.ip));
|
||||
void** var_ptr = var_by_category(&s, to_var_category(category), ip_read_int(&s.ip));
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
case 4: { // ST %d
|
||||
int8_t category = ip_read_byte(&s.ip);
|
||||
union VarT** var_ptr = var_by_category(&s, to_var_category(category), ip_read_int(&s.ip));
|
||||
*var_ptr = s_take_var(&s); // TODO: check
|
||||
void** var_ptr = var_by_category(&s, to_var_category(category), ip_read_int(&s.ip));
|
||||
*var_ptr = s_pop(&s);
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
switch (l) {
|
||||
case 0: { // CJMPz 0x%.8x
|
||||
char* new_ip = (char*)(long)ip_read_int(&s.ip); // TODO: check
|
||||
if (s_take_i(&s) != 0) {
|
||||
if (s_pop_i(&s) != UNBOX(0)) {
|
||||
s.ip = new_ip;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: { // CJMPnz 0x%.8x
|
||||
char* new_ip = (char*)(long)ip_read_int(&s.ip); // TODO: check
|
||||
if (s_take_i(&s) == 0) {
|
||||
if (s_pop_i(&s) == UNBOX(0)) {
|
||||
s.ip = new_ip;
|
||||
}
|
||||
break;
|
||||
|
|
@ -200,6 +195,7 @@ void run(bytefile *bf) {
|
|||
break;
|
||||
|
||||
case 4: // CLOSURE 0x%.8x
|
||||
// TODO
|
||||
{
|
||||
int n = ip_read_int(&s.ip);
|
||||
for (int i = 0; i < n; i++) {
|
||||
|
|
@ -226,14 +222,14 @@ void run(bytefile *bf) {
|
|||
break;
|
||||
|
||||
case 7: // TAG %s
|
||||
// TODO: ??
|
||||
s_push_i(&s, LtagHash(ip_read_string(&s.ip, bf))); // TODO: check
|
||||
break;
|
||||
|
||||
case 8: // ARRAY %d
|
||||
s_put_array(&s, ip_read_int(&s.ip));
|
||||
Barray((aint*)s.sp, ip_read_int(&s.ip));
|
||||
break;
|
||||
|
||||
case 9: // FAIL %d %d
|
||||
case 9: // FAIL %d %d // TODO
|
||||
failure("[FAIL]: %d-%d\n", ip_read_int(&s.ip), ip_read_int(&s.ip));
|
||||
break;
|
||||
|
||||
|
|
@ -247,30 +243,62 @@ void run(bytefile *bf) {
|
|||
break;
|
||||
|
||||
case 6: // PATT pats[l]
|
||||
// TODO: JMP if same to pattern ??
|
||||
// {"=str", "#string", "#array", "#sexp", "#ref", "#val", "#fun"}
|
||||
switch (l) {
|
||||
case 0: // =str
|
||||
s_push_i(&s, Bstring_patt(s_pop(&s), s_pop(&s))); // TODO: order
|
||||
break;
|
||||
case 1: // #string
|
||||
s_push_i(&s, Bstring_tag_patt(s_pop(&s)));
|
||||
break;
|
||||
case 2: // #array
|
||||
s_push_i(&s, Barray_tag_patt(s_pop(&s)));
|
||||
break;
|
||||
case 3: // #sexp
|
||||
s_push_i(&s, Bsexp_tag_patt(s_pop(&s)));
|
||||
break;
|
||||
case 4: // #ref
|
||||
// TODO
|
||||
break;
|
||||
case 5: // #val
|
||||
// TODO
|
||||
break;
|
||||
case 6: // #fun
|
||||
s_push_i(&s, Bclosure_tag_patt(s_pop(&s)));
|
||||
break;
|
||||
default:
|
||||
failure("invalid opcode %d-%d\n", h, l);
|
||||
}
|
||||
break;
|
||||
|
||||
case 7: {
|
||||
switch (l) {
|
||||
case 0: // CALL Lread
|
||||
f_read(&s);
|
||||
s_push_i(&s, Lread());
|
||||
break;
|
||||
|
||||
case 1: // CALL Lwrite
|
||||
f_write(&s);
|
||||
Lwrite(s_pop_i(&s));
|
||||
break;
|
||||
|
||||
case 2: // CALL Llength
|
||||
f_length(&s);
|
||||
s_push_i(&s, Llength(s_pop(&s)));
|
||||
break;
|
||||
|
||||
case 3: // CALL Lstring
|
||||
f_string(&s);
|
||||
case 3: { // CALL Lstring
|
||||
void* str = Lstring((aint*)s.sp);
|
||||
s_pop(&s);
|
||||
s_push(&s, str);
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: // CALL Barray %d
|
||||
f_array(&s, ip_read_int(&s.ip));
|
||||
case 4: { // CALL Barray %d
|
||||
size_t n = ip_read_int(&s.ip);
|
||||
void* array = Barray((aint*)s.sp, n); // TODO: are elems added (?)
|
||||
s_popn(&s, n);
|
||||
s_push(&s, array);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
failure("invalid opcode %d-%d\n", h, l);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ extern size_t __gc_stack_top, __gc_stack_bottom;
|
|||
flag = __gc_stack_top == 0; \
|
||||
if (flag) { __gc_stack_top = (size_t)__builtin_frame_address(0); } \
|
||||
assert(__gc_stack_top != 0); \
|
||||
assert((__gc_stack_top & 0xF) == 0); \
|
||||
assert(__builtin_frame_address(0) <= (void *)__gc_stack_top);
|
||||
|
||||
#define POST_GC() \
|
||||
|
|
@ -27,6 +28,10 @@ void s_push(struct State *s, void *val) {
|
|||
*s->sp = val;
|
||||
}
|
||||
|
||||
void s_push_i(struct State *s, aint val) {
|
||||
s_push(s, (void*)val);
|
||||
}
|
||||
|
||||
void s_push_nil(struct State *s) {
|
||||
s_push(s, NULL);
|
||||
}
|
||||
|
|
@ -48,6 +53,10 @@ void* s_pop(struct State *s) {
|
|||
return value;
|
||||
}
|
||||
|
||||
aint s_pop_i(struct State *s) {
|
||||
return (aint)s_pop(s);
|
||||
}
|
||||
|
||||
void s_popn(struct State *s, size_t n) {
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
s_pop(s);
|
||||
|
|
@ -56,10 +65,10 @@ void s_popn(struct State *s, size_t n) {
|
|||
|
||||
// ------ functions ------
|
||||
|
||||
void s_enter_f(struct State *s, char *func_ip, size_t args_sz,
|
||||
size_t locals_sz) {
|
||||
void s_enter_f(struct State *s, char *func_ip, auint args_sz,
|
||||
auint locals_sz) {
|
||||
// check that params count is valid
|
||||
if (args_sz > s->sp + STACK_SIZE - s->stack ||
|
||||
if (s->sp + (aint)args_sz - 1 >= s->stack + STACK_SIZE ||
|
||||
(s->fp != NULL && args_sz > s->sp + STACK_SIZE - f_locals(s->fp))) {
|
||||
failure("not enough parameters in stack");
|
||||
}
|
||||
|
|
@ -147,5 +156,3 @@ void **var_by_category(struct State *s, enum VarCategory category,
|
|||
|
||||
return var;
|
||||
}
|
||||
|
||||
// --- changed runtime operations ---
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ size_t frame_sz() {
|
|||
void **f_prev_fp(struct Frame *fp) {
|
||||
return (void **)fp + UNBOX(fp->to_prev_fp_box);
|
||||
}
|
||||
uint64_t f_locals_sz(struct Frame *fp) { return UNBOX(fp->locals_sz_box); }
|
||||
uint64_t f_args_sz(struct Frame *fp) { return UNBOX(fp->args_sz_box); }
|
||||
auint f_locals_sz(struct Frame *fp) { return UNBOX(fp->locals_sz_box); }
|
||||
auint f_args_sz(struct Frame *fp) { return UNBOX(fp->args_sz_box); }
|
||||
void **f_locals(struct Frame *fp) { return (void **)fp - f_locals_sz(fp) - frame_sz(); }
|
||||
void **f_args(struct Frame *fp) { return (void **)fp + 1; }
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue