From e17f1f70ed6c896f4eacb52ba0cd365e91a2305f Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Sat, 2 Nov 2024 01:19:54 +0300 Subject: [PATCH] part of operations, migration to 1.30 --- byterun/Makefile | 4 +- byterun/dune | 6 +- byterun/include/runtime_externs.h | 123 +++++++++++++++--------------- byterun/include/stack.h | 13 +--- byterun/include/types.h | 14 ++-- byterun/src/interpreter.c | 122 +++++++++++++++++------------ byterun/src/stack.c | 17 +++-- byterun/src/types.c | 4 +- 8 files changed, 166 insertions(+), 137 deletions(-) diff --git a/byterun/Makefile b/byterun/Makefile index 3958072d7..c87ff431f 100644 --- a/byterun/Makefile +++ b/byterun/Makefile @@ -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 diff --git a/byterun/dune b/byterun/dune index 21ba79084..24b025a52 100644 --- a/byterun/dune +++ b/byterun/dune @@ -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}))) diff --git a/byterun/include/runtime_externs.h b/byterun/include/runtime_externs.h index c9ef96b75..9d3cf7e3b 100644 --- a/byterun/include/runtime_externs.h +++ b/byterun/include/runtime_externs.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include @@ -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[]); diff --git a/byterun/include/stack.h b/byterun/include/stack.h index a3fde5a27..ccdae9b9a 100644 --- a/byterun/include/stack.h +++ b/byterun/include/stack.h @@ -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); diff --git a/byterun/include/types.h b/byterun/include/types.h index d0950d37c..33ba994c4 100644 --- a/byterun/include/types.h +++ b/byterun/include/types.h @@ -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); diff --git a/byterun/src/interpreter.c b/byterun/src/interpreter.c index 4caa5cd90..4ae206cac 100644 --- a/byterun/src/interpreter.c +++ b/byterun/src/interpreter.c @@ -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); diff --git a/byterun/src/stack.c b/byterun/src/stack.c index 834cb454a..b910f8b69 100644 --- a/byterun/src/stack.c +++ b/byterun/src/stack.c @@ -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 --- diff --git a/byterun/src/types.c b/byterun/src/types.c index 5d2f3d06a..944576478 100644 --- a/byterun/src/types.c +++ b/byterun/src/types.c @@ -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; }