From: Jérémie Astor Date: Sun, 9 Jan 2022 13:40:48 +0000 (+0100) Subject: Prepare (#236) X-Git-Tag: nightly~390 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=65ff77c7139484a1d151f67d5025d378aa2300b8;p=gwion.git Prepare (#236) * :art: Use prepared bytecode * :art: Use prepared bytecode * :bug: Fix object destructor * :art: :bomb: :bug: Fix object_dtor and clean a few things * Fix repl (compilation at least) * Fix repl (add wait time) * :art: unbork Makefile * :bug: Fix 1 channel dac * :art: add ability to force load plugins * :art: add ability to force load plugins (fix) * :art: add ability to force load plugins (fix) * :book: start Repl doc * :art: Darling clean the pool --- diff --git a/Makefile b/Makefile index 1424f0ba..b89cc7a9 100644 --- a/Makefile +++ b/Makefile @@ -83,13 +83,13 @@ util/include/generated.h: util/libtermcolor/libtermcolor.a: @+${MAKE} BUILD_ON_WINDOWS=${BUILD_ON_WINDOWS} -s -C util/libtermcolor static -util/libgwion_util.a: +util/libgwion_util.a: util/include/generated.h @+GWION_PACKAGE= ${MAKE} -s -C util util: util/libgwion_util.a @(info build util) -ast/libgwion_ast.a: +ast/libgwion_ast.a: util/libgwion_util.a @+GWION_PACKAGE= ${MAKE} -s -C ast libcmdapp/libcmdapp.a: diff --git a/include/instr.h b/include/instr.h index e6192120..03a10109 100644 --- a/include/instr.h +++ b/include/instr.h @@ -33,8 +33,7 @@ struct Instr_ { }; void (*execute)(const VM_Shred shred, const Instr instr); }; -#define BYTECODE_SZ \ - ((2 * sizeof(unsigned)) + sizeof(struct Instr_) - SZ_INT * 2) +#define BYTECODE_SZ (SZ_INT * 4) ANN void free_instr(const Gwion, const Instr); INSTR(EOC); diff --git a/include/vm.h b/include/vm.h index c5ff5ac6..869559ec 100644 --- a/include/vm.h +++ b/include/vm.h @@ -26,6 +26,7 @@ struct VM_Code_ { struct M_Vector_ live_values; uint16_t stack_depth; uint16_t ref; + bool is_prepared; bool builtin; bool callback; bool is_memoize; @@ -122,7 +123,10 @@ vm_shred_exit(const VM_Shred shred) { } void free_vm_shred(const VM_Shred shred) __attribute__((hot, nonnull)); -ANN void vm_run(const VM *vm) __attribute__((hot)); +void vm_prepare(const VM *vm, m_bit*) __attribute__((hot)); +ANN static inline void vm_run(const VM *vm) { + vm_prepare(vm, NULL); +} ANEW VM * new_vm(MemPool, const bool); ANN void vm_lock(VM const *); ANN void vm_unlock(VM const *); diff --git a/plug b/plug index e53662db..4387f4fe 160000 --- a/plug +++ b/plug @@ -1 +1 @@ -Subproject commit e53662dbeacd2f02e7c8507323a21d659c2dbc70 +Subproject commit 4387f4fe3ac0326476225fa6190dc428e3303f41 diff --git a/src/arg.c b/src/arg.c index cce495db..46d1c5d4 100644 --- a/src/arg.c +++ b/src/arg.c @@ -14,6 +14,7 @@ enum { CONFIG, PLUGIN, + LOAD_PLUGIN, MODULE, LOOP, PASS, @@ -57,6 +58,7 @@ ANN static m_str plug_dir(void) { enum arg_type { ARG_FILE, ARG_STDIN, + ARG_LOAD_PLUGIN, ARG_DEFINE, ARG_UNDEF, ARG_INCLUDE, @@ -114,6 +116,13 @@ ANN void arg_compile(const Gwion gwion, Arg *arg) { case ARG_STDIN: compile_file(gwion, "stdin", stdin); break; + case ARG_LOAD_PLUGIN: +{ + char c[1024]; + sprintf(c, "#import %s\n", (m_str)VPTR(v, ++i)); + compile_string(gwion, "", c); + break; +} case ARG_DEFINE: pparg_add(gwion->ppa, (m_str)VPTR(v, ++i)); break; @@ -174,6 +183,8 @@ static void setup_options(cmdapp_t *app, cmdopt_t *opt) { "number of input channel", &opt[NINPUT]); cmdapp_set(app, 'o', "output", CMDOPT_TAKESARG, NULL, "number of output channel", &opt[NOUTPUT]); + cmdapp_set(app, 'P', "plugin", CMDOPT_TAKESARG, NULL, "(force-)load a plugin", + &opt[LOAD_PLUGIN]); cmdapp_set(app, 'D', "define", CMDOPT_TAKESARG, NULL, "define a macro", &opt[DEFINE]); cmdapp_set(app, 'U', "undef", CMDOPT_TAKESARG, NULL, "undefine a macro", @@ -271,6 +282,10 @@ static void myproc(void *data, cmdopt_t *option, const char *arg) { case '\0': vector_add(&_arg->add, (vtype)ARG_STDIN); break; + case 'P': + vector_add(&_arg->add, (vtype)ARG_LOAD_PLUGIN); + vector_add(&_arg->add, (vtype)option->value); + break; case 'c': if (!strcmp(option->value, "never")) _arg->color = COLOR_NEVER; diff --git a/src/emit/emit.c b/src/emit/emit.c index ea2ea831..22c2ff2a 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -2843,7 +2843,8 @@ ANN static void me_ret(MemoizeEmitter *me) { const Instr instr = emit_regpushmem(me->emit, me->fdef->base->ret_type->size, false); instr->m_val = (me->offset + SZ_INT) * 2; - emit_add_instr(me->emit, FuncReturn); +// emit_add_instr(me->emit, FuncReturn); +vector_add(&me->emit->code->stack_return, (vtype)emit_add_instr(me->emit, Goto)); } ANN static m_bool me_run(MemoizeEmitter *me, const m_uint pc) { diff --git a/src/lib/array.c b/src/lib/array.c index b26d4a27..2c5a9a89 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -373,27 +373,27 @@ static OP_EMIT(opem_array_access) { return exp ? emit_array_access(emit, info) : GW_ERROR; } -static m_bit map_byte[BYTECODE_SZ * 4]; +static m_bit map_byte[BYTECODE_SZ * 5]; static const struct VM_Code_ map_run_code = {.name = "map_run_code", .bytecode = map_byte}; -static m_bit compactmap_byte[BYTECODE_SZ * 4]; +static m_bit compactmap_byte[BYTECODE_SZ * 5]; static const struct VM_Code_ compactmap_run_code = { .name = "compactmap_run_code", .bytecode = compactmap_byte}; -static m_bit filter_byte[BYTECODE_SZ * 4]; +static m_bit filter_byte[BYTECODE_SZ * 5]; static const struct VM_Code_ filter_run_code = {.name = "filter_run_code", .bytecode = filter_byte}; -static m_bit count_byte[BYTECODE_SZ * 4]; +static m_bit count_byte[BYTECODE_SZ * 5]; static const struct VM_Code_ count_run_code = {.name = "count_run_code", .bytecode = count_byte}; -static m_bit foldl_byte[BYTECODE_SZ * 4]; +static m_bit foldl_byte[BYTECODE_SZ * 5]; static const struct VM_Code_ foldl_run_code = {.name = "foldl_run_code", .bytecode = foldl_byte}; -static m_bit foldr_byte[BYTECODE_SZ * 4]; +static m_bit foldr_byte[BYTECODE_SZ * 5]; static const struct VM_Code_ foldr_run_code = {.name = "foldr_run_code", .bytecode = foldr_byte}; @@ -779,14 +779,17 @@ ANN static void prepare_run(m_bit *const byte, const f_instr ini, *(unsigned *)(byte + BYTECODE_SZ * 2) = eOverflow; *(unsigned *)(byte + BYTECODE_SZ * 3) = eOP_MAX; *(f_instr *)(byte + BYTECODE_SZ * 3 + SZ_INT * 2) = end; + *(unsigned *)(byte + BYTECODE_SZ * 4) = eEOC; } ANN static void prepare_map_run(m_bit *const byte, const f_instr end) { prepare_run(byte, map_run_ini, end); + vm_prepare(NULL, byte); } ANN static void prepare_fold_run(m_bit *const byte, const f_instr ini) { prepare_run(byte, ini, fold_run_end); + vm_prepare(NULL, byte); } GWION_IMPORT(array) { diff --git a/src/lib/instr.c b/src/lib/instr.c index 7d32b2dd..0a138a06 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -122,17 +122,21 @@ INSTR(DotTmpl) { #define FVAL (*(m_float *)(byte + SZ_INT)) #define VAL2 (*(m_uint *)(byte + SZ_INT * 2)) #define BYTE(a) \ - m_bit *byte = shred->code->bytecode + (shred->pc - 1) * SZ_INT * 3; \ - *(m_bit *)byte = a; + m_bit *byte = shred->code->bytecode + (shred->pc - 1) * BYTECODE_SZ; \ + *(m_uint *)byte = a; INSTR(SetFunc) { - BYTE(eRegPushImm) +// BYTE(eRegPushImm) + m_bit *byte = shred->code->bytecode + (shred->pc - 1) * BYTECODE_SZ; \ + *(m_uint *)byte = instr->opcode; + instr->opcode = eRegPushImm; const Func f = (Func)instr->m_val; VAL = *(m_uint *)(shred->reg) = (m_uint)f->code; shred->reg += SZ_INT; } INSTR(SetRecurs) { +exit(4); BYTE(eRegPushImm) VAL = *(m_uint *)(shred->reg) = (m_uint)shred->code; shred->reg += SZ_INT; @@ -147,7 +151,10 @@ INSTR(SetCtor) { INSTR(fast_except) { if(*(m_uint*)REG((m_int)instr->m_val)) { - BYTE(eNoOp) +// BYTE(eNoOp) + m_bit *byte = shred->code->bytecode + (shred->pc - 1) * BYTECODE_SZ; \ + *(m_uint *)byte = instr->opcode; + instr->opcode = eNoOp; } else handle(shred, "NullPtrException"); } diff --git a/src/lib/object.c b/src/lib/object.c index 8a9aad08..6db3f060 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -1,5 +1,3 @@ -#include -#include #include "gwion_util.h" #include "gwion_ast.h" #include "gwion_env.h" @@ -44,16 +42,6 @@ ANN static void user_dtor(const M_Object o, const VM_Shred shred, const Type t) ++sh->info->me->ref; } -static DTOR(object_dtor) { - free_object(shred->info->mp, o); -} - -ANN static inline Type next_type(Type t) { - do if(t->nspc) return t; - while((t = t->info->parent)); - return NULL; -} - ANN static inline void release_not_union(const m_bit *data, const VM_Shred shred, const Scope s) { const Map m = &s->map; for(m_uint i = map_size(m) + 1; --i;) { @@ -65,9 +53,10 @@ ANN static inline void release_not_union(const m_bit *data, const VM_Shred shred ANN static void do_release(const M_Object o, const VM_Shred shred, const Type t) { - const Type next = next_type(t); - if(!next) + if(!t->nspc->offset) { + free_object(shred->info->mp, o); return; + } if (!tflag(t, tflag_union)) release_not_union(o->data, shred, t->nspc->info->value); if (tflag(t, tflag_dtor)) { @@ -93,7 +82,7 @@ ANN void __release(const M_Object o, const VM_Shred shred) { } ANN void free_object(MemPool p, const M_Object o) { - mp_free2(p, o->type_ref->nspc->offset, o); + mp_free2(p, sizeof(struct M_Object_) + o->type_ref->nspc->offset, o); } static ID_CHECK(opck_this) { @@ -127,9 +116,6 @@ GWION_IMPORT(object) { const Type t_object = gwi_mk_type(gwi, "Object", SZ_INT, "@Compound"); gwi_set_global_type(gwi, t_object, et_object); t_object->nspc = new_nspc(gwi->gwion->mp, "Object"); - t_object->nspc->dtor = new_vmcode(gwi->gwion->mp, NULL, NULL, "Object", SZ_INT, true, false); - t_object->nspc->dtor->native_func = (m_uint)object_dtor; - t_object->tflag |= tflag_dtor; struct SpecialId_ spid = {.ck = opck_this, .em = opem_this, .is_const = 1}; gwi_specialid(gwi, "this", &spid); return GW_OK; diff --git a/src/lib/ugen.c b/src/lib/ugen.c index 75933625..d0e1f425 100644 --- a/src/lib/ugen.c +++ b/src/lib/ugen.c @@ -377,10 +377,24 @@ static GWION_IMPORT(global_ugens) { struct ugen_importer imp_hole = {vm, compute_mono, "blackhole", 1}; const UGen hole = add_ugen(gwi, &imp_hole); struct ugen_importer imp_dac = {vm, dac_tick, "dac", vm->bbq->si->out}; - const UGen dac = add_ugen(gwi, &imp_dac); + + // dac needs to have *multi* + const M_Object dac = new_M_UGen(gwi->gwion); + const UGen u = UGEN(dac); + u->connect.multi = mp_calloc(gwi->gwion->mp, ugen_multi); + u->connect.multi->n_in = vm->bbq->si->out; + u->connect.multi->n_out = vm->bbq->si->out; + u->connect.multi->n_chan = vm->bbq->si->out; + assign_channel(gwi->gwion, u); + ugen_gen(vm->gwion, u, dac_tick, (void *)vm, 0); + vector_add(&vm->ugen, (vtype)u); + gwi_item_ini(gwi, "UGen", "dac"); + gwi_item_end(gwi, ae_flag_const, obj, dac); + ugen_connect(u, hole); + + struct ugen_importer imp_adc = {vm, adc_tick, "adc", vm->bbq->si->in}; (void)add_ugen(gwi, &imp_adc); - ugen_connect(dac, hole); SET_FLAG(gwi->gwion->type[et_ugen], abstract); return GW_OK; } diff --git a/src/vm/vm.c b/src/vm/vm.c index 507dfab0..26605895 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -81,7 +81,6 @@ ANN static inline bool find_handle(const VM_Shred shred, const Symbol effect, co if (start > shred->pc) return true; const uint16_t pc = find_pc(shred, effect, size); if (!pc) // outside of a try statement -// return true; return false; // we should clean values here shred->reg = // restore reg @@ -90,7 +89,6 @@ ANN static inline bool find_handle(const VM_Shred shred, const Symbol effect, co shred->pc = pc; // VKEY(m, i); vector_pop(&shred->info->frame); vector_pop(&shred->info->frame); -// return false; return true; } @@ -276,14 +274,15 @@ ANN static VM_Shred init_fork_shred(const VM_Shred shred, const VM_Code code, #define handle(a, b) VM_OUT handle(a, b); #define TEST0(t, pos) \ if (!*(t *)(reg - pos)) { \ -/* shred->pc = PC;*/ \ handle(shred, "ZeroDivideException"); \ break; \ } -#define ADVANCE() byte += BYTECODE_SZ; +//#define ADVANCE() { byte += BYTECODE_SZ; shred->pc++;} +#define ADVANCE() byte += BYTECODE_SZ -#define SDISPATCH() goto *dispatch[*(m_bit *)byte]; +//#define SDISPATCH() goto *dispatch[*(m_bit *)byte]; +#define SDISPATCH() goto **(void***)byte; #define IDISPATCH() \ { \ VM_INFO; \ @@ -292,23 +291,23 @@ ANN static VM_Shred init_fork_shred(const VM_Shred shred, const VM_Code code, #define SET_BYTE(pc) (byte = bytecode + (pc)*BYTECODE_SZ) -#define PC_DISPATCH(pc) \ - SET_BYTE((pc)); \ +#define PC_DISPATCH(_pc) \ + SET_BYTE((_pc)); \ +/* shred->pc = _pc + 1;*/\ IDISPATCH(); #define DISPATCH() \ ADVANCE(); \ IDISPATCH(); -#define ADVANCE() byte += BYTECODE_SZ; - #define ADISPATCH() \ { \ ADVANCE(); \ SDISPATCH(); \ } -#define PC (*(unsigned *)(byte + 1)) +#define PC (*(m_uint *)(byte + SZ_INT*3)) +//#define PC (shred->pc) #define OP(t, sz, op, ...) \ reg -= sz; \ @@ -415,20 +414,19 @@ _Pragma(STRINGIFY(COMPILER diagnostic push)) \ _Pragma(STRINGIFY(COMPILER diagnostic ignored UNINITIALIZED) #define PRAGMA_POP() _Pragma(STRINGIFY(COMPILER diagnostic pop)) -#define VMSZ (SZ_INT > SZ_FLOAT ? SZ_INT : SZ_FLOAT) - -#define VAL (*(m_uint *)(byte + VMSZ)) -#define IVAL (*(m_int *)(byte + VMSZ)) -#define FVAL (*(m_float *)(byte + VMSZ)) +#define VAL (*(m_uint *)(byte + SZ_INT)) +#define IVAL (*(m_int *)(byte + SZ_INT)) +#define FVAL (*(m_float *)(byte + SZ_INT)) #define VAL2 (*(m_uint *)(byte + SZ_INT + SZ_INT)) #define IVAL2 (*(m_int *)(byte + SZ_INT + SZ_INT)) #define SVAL (*(uint16_t *)(byte + SZ_INT + SZ_INT)) #define SVAL2 (*(uint16_t *)(byte + SZ_INT + SZ_INT + sizeof(uint16_t))) #define BRANCH_DISPATCH(check) \ - if (check) \ + if (check) { \ SET_BYTE(VAL); \ - else \ + shred->pc = VAL + 1;\ + } else \ ADVANCE(); \ IDISPATCH(); @@ -438,8 +436,8 @@ _Pragma(STRINGIFY(COMPILER diagnostic ignored UNINITIALIZED) shred->mem = mem; \ shred->pc = PC; -__attribute__((hot)) ANN void -vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] +__attribute__((hot)) void +vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto] static const void *dispatch[] = { &®setimm, &®pushimm, &®pushfloat, &®pushother, &®pushaddr, &®pushmem, &®pushmemfloat, &®pushmemother, &®pushmemaddr, @@ -488,24 +486,23 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] &&try_end, &&handleeffect, &&performeffect, &&noop, &&debugline, &&debugvalue, &&debugpush, &&debugpop, &&eoc, &&unroll2, &&other, &®pushimm}; - const Shreduler s = vm->shreduler; - register VM_Shred shred; - register m_bit next; + if(!prepare_code) { + PRAGMA_PUSH() + const Shreduler s = vm->shreduler; + VM_Shred shred; while ((shred = shreduler_get(s))) { - register VM_Code code = shred->code; - register m_bit * bytecode = code->bytecode; - register m_bit * byte = bytecode + shred->pc * BYTECODE_SZ; - register m_bit * reg = shred->reg; - register m_bit * mem = shred->mem; - register union { + VM_Code code = shred->code; + m_bit * bytecode = code->bytecode; + m_bit * byte = bytecode + shred->pc * BYTECODE_SZ; + m_bit * reg = shred->reg; + m_bit * mem = shred->mem; + m_bit next; + union { M_Object obj; VM_Code code; } a; - PRAGMA_PUSH() - register VM_Shred child; - PRAGMA_POP() -// MUTEX_LOCK(s->mutex); + VM_Shred child; do { SDISPATCH(); regsetimm: @@ -918,7 +915,6 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] } DISPATCH(); setcode: - PRAGMA_PUSH() a.code = *(VM_Code *)(reg - SZ_INT); if (!a.code->builtin) { register const uint push = @@ -931,7 +927,6 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] mem += *(m_uint *)reg; next = eFuncMemberEnd; } - PRAGMA_POP() regmove: reg += IVAL; DISPATCH(); @@ -943,17 +938,12 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] DISPATCH() overflow: if (overflow_(mem + VAL2, shred)) { -// shred->pc = PC; handle(shred, "StackOverflow"); continue; } - PRAGMA_PUSH() goto *dispatch[next]; - PRAGMA_POP() funcusrend: - PRAGMA_PUSH() byte = bytecode = (code = a.code)->bytecode; - PRAGMA_POP() SDISPATCH(); funcusrend2: byte = bytecode; @@ -975,13 +965,11 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] child = init_fork_shred(shred, (VM_Code)VAL, (Type)VAL2); DISPATCH() sporkfunc: - PRAGMA_PUSH() // LOOP_OPTIM for (m_uint i = 0; i < VAL; i += SZ_INT) *(m_uint *)(child->reg + i) = *(m_uint *)(reg + i + IVAL2); child->reg += VAL; DISPATCH() - PRAGMA_POP() sporkmemberfptr: for (m_uint i = SZ_INT; i < VAL; i += SZ_INT) *(m_uint *)(child->reg + i) = *(m_uint *)(reg - VAL + i); @@ -997,9 +985,7 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] DISPATCH() sporkend: assert(!VAL); // spork are not mutable - PRAGMA_PUSH() *(M_Object *)(reg - SZ_INT) = child->info->me; - PRAGMA_POP() DISPATCH() brancheqint: reg -= SZ_INT; @@ -1057,15 +1043,11 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] DISPATCH() } arrayget: - PRAGMA_PUSH() m_vector_get(ARRAY(a.obj), *(m_int *)(reg + VAL), (reg + IVAL2)); - PRAGMA_POP() DISPATCH() arrayaddr: - PRAGMA_PUSH() *(m_bit **)(reg + IVAL2) = m_vector_addr(ARRAY(a.obj), *(m_int *)(reg + VAL)); - PRAGMA_POP() DISPATCH() newobj: *(M_Object *)reg = new_object(vm->gwion->mp, (Type)VAL2); @@ -1132,11 +1114,9 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] DISPATCH() dotother: // LOOP_OPTIM - PRAGMA_PUSH() for (m_uint i = 0; i <= VAL2; i += SZ_INT) *(m_uint *)(reg + i - SZ_INT) = *(m_uint *)(((*(M_Object *)(reg - SZ_INT))->data + VAL) + i); - PRAGMA_POP() reg += VAL2 - SZ_INT; DISPATCH() dotaddr: @@ -1170,10 +1150,8 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] } unionother : { UNION_CHECK - PRAGMA_PUSH() for (m_uint i = 0; i <= VAL2; i += SZ_INT) *(m_uint *)(reg + i - SZ_INT) = *(m_uint *)(data + SZ_INT + i); - PRAGMA_POP() reg += VAL2 - SZ_INT; DISPATCH() } @@ -1287,8 +1265,321 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] VM_OUT vm_shred_exit(shred); } while (s->curr); -// MUTEX_UNLOCK(s->mutex); } + PRAGMA_POP() +} else { +//exit(3); +//return; +static void *_dispatch[] = { + &&_regsetimm, &&_regpushimm, &&_regpushfloat, &&_regpushother, &&_regpushaddr, + &&_regpushmem, &&_regpushmemfloat, &&_regpushmemother, &&_regpushmemaddr, + &&_regpushmemderef, &&_pushnow, &&_baseint, &&_basefloat, &&_baseother, + &&_baseaddr, &&_regtoreg, &&_regtoregother, &&_regtoregother2, &&_regtoregaddr, &&_regtoregderef, + &&_structmember, &&_structmemberfloat, &&_structmemberother, + &&_structmemberaddr, &&_memsetimm, &&_memaddimm, &&_repeatidx, &&_repeat, + &&_regpushme, &&_regpushmaybe, &&_funcreturn, &&__goto, &&_allocint, + &&_allocfloat, &&_allocother, + &&_intplus, &&_intminus, &&_intmul, &&_intdiv, &&_intmod, + &&_intplusimm, &&_intminusimm, &&_intmulimm, &&_intdivimm, &&_intmodimm, + // int relationnal + &&_inteq, &&_intne, &&_intand, &&_intor, + &&_intgt, &&_intge, &&_intlt, &&_intle, + &&_intgtimm, &&_intgeimm, &&_intltimm, &&_intleimm, + &&_intsl, &&_intsr, &&_intsand, &&_intsor, &&_intxor, &&_intnegate, &&_intnot, + &&_intcmp, &&_intrassign, &&_intradd, &&_intrsub, &&_intrmul, &&_intrdiv, + &&_intrmod, &&_intrsl, &&_intrsr, &&_intrsand, &&_intrsor, &&_intrxor, &&_preinc, + &&_predec, &&_postinc, &&_postdec, + &&_floatadd, &&_floatsub, &&_floatmul, &&_floatdiv, + &&_floataddimm, &&_floatsubimm, &&_floatmulimm, &&_floatdivimm, + // logical + &&_floatand, &&_floator, &&_floateq, &&_floatne, + &&_floatgt, &&_floatge, &&_floatlt, &&_floatle, + &&_floatgtimm, &&_floatgeimm, &&_floatltimm, &&_floatleimm, + &&_floatneg, &&_floatnot, &&_floatrassign, &&_floatradd, + &&_floatrsub, &&_floatrmul, &&_floatrdiv, &&_ifadd, &&_ifsub, &&_ifmul, &&_ifdiv, + &&_ifand, &&_ifor, &&_ifeq, &&_ifne, &&_ifgt, &&_ifge, &&_iflt, &&_ifle, + &&_ifrassign, &&_ifradd, &&_ifrsub, &&_ifrmul, &&_ifrdiv, &&_fiadd, &&_fisub, + &&_fimul, &&_fidiv, &&_fiand, &&_fior, &&_fieq, &&_fine, &&_figt, &&_fige, &&_filt, + &&_file, &&_firassign, &&_firadd, &&_firsub, &&_firmul, &&_firdiv, &&_itof, + &&_ftoi, &&_timeadv, &&_recurs, &&_setcode, &&_regmove, + &&_regtomem, &&_regtomemother, + &&_overflow, + &&_funcusrend, &&_funcusrend2, &&_funcmemberend, + &&_sporkini, &&_forkini, &&_sporkfunc, &&_sporkmemberfptr, &&_sporkexp, + &&_sporkend, &&_brancheqint, &&_branchneint, &&_brancheqfloat, + &&_branchnefloat, &&_unroll, &&_arrayappend, &&_autounrollinit, &&_autoloop, + &&_arraytop, &&_arrayaccess, &&_arrayget, &&_arrayaddr, &&_newobj, &&_addref, + &&_addrefaddr, &&_structaddref, &&_structaddrefaddr, &&_objassign, &&_assign, + &&_remref, &&_remref2, &&_except, &&_allocmemberaddr, &&_dotmember, &&_dotfloat, + &&_dotother, &&_dotaddr, &&_unioncheck, &&_unionint, &&_unionfloat, + &&_unionother, &&_unionaddr, &&_staticint, &&_staticfloat, &&_staticother, + &&_upvalueint, &&_upvaluefloat, &&_upvalueother, &&_upvalueaddr, &&_dotfunc, + &&_gacktype, &&_gackend, &&_gack, &&_try_ini, + &&_try_end, &&_handleeffect, &&_performeffect, &&_noop, &&_debugline, + &&_debugvalue, &&_debugpush, &&_debugpop, &&_eoc, &&_unroll2, &&_other, + &&_regpushimm}; + +#define PREPARE(a) \ +_##a: \ + *(void**)prepare_code = &&a;\ +prepare_code += BYTECODE_SZ;\ +goto *_dispatch[*(m_bit*)prepare_code]; + +goto *_dispatch[*(m_bit*)prepare_code]; + PREPARE(regsetimm); + PREPARE(regpushimm); + PREPARE(regpushfloat); + PREPARE(regpushother); + PREPARE(regpushaddr); + PREPARE(regpushmem); + PREPARE(regpushmemfloat); + PREPARE(regpushmemother); + PREPARE(regpushmemaddr); + PREPARE(regpushmemderef); + PREPARE(pushnow); + PREPARE(baseint); + PREPARE(basefloat); + PREPARE(baseother); + PREPARE(baseaddr); + PREPARE(regtoreg); + PREPARE(regtoregother); + PREPARE(regtoregother2); + PREPARE(regtoregaddr); + PREPARE(regtoregderef); + PREPARE(structmember); + PREPARE(structmemberfloat); + PREPARE(structmemberother); + PREPARE(structmemberaddr) + PREPARE(memsetimm); + PREPARE(memaddimm); + PREPARE(repeatidx); + PREPARE(repeat); + PREPARE(regpushme); + PREPARE(regpushmaybe); +// PREPARE(funcreturn); +_funcreturn: + *(void**)prepare_code = &&funcreturn; +return; + + PREPARE(_goto); + PREPARE(allocint); + PREPARE(allocfloat); + PREPARE(allocother) + PREPARE(intplus); + PREPARE(intminus); + PREPARE(intmul); + PREPARE(intdiv); + PREPARE(intmod); + PREPARE(intplusimm); + PREPARE(intminusimm); + PREPARE(intmulimm); + PREPARE(intdivimm); + PREPARE(intmodimm); + + PREPARE(inteq); + PREPARE(intne); + PREPARE(intand); + PREPARE(intor); + PREPARE(intgt); + PREPARE(intge); + PREPARE(intlt); + PREPARE(intle); + PREPARE(intgtimm); + PREPARE(intgeimm); + PREPARE(intltimm); + PREPARE(intleimm); + PREPARE(intsl); + PREPARE(intsr); + PREPARE(intsand); + PREPARE(intsor); + PREPARE(intxor); + + PREPARE(intnegate); + PREPARE(intnot); + PREPARE(intcmp); + + PREPARE(intrassign); + + PREPARE(intradd); + PREPARE(intrsub); + PREPARE(intrmul); + PREPARE(intrdiv); + PREPARE(intrmod); + PREPARE(intrsl); + PREPARE(intrsr); + PREPARE(intrsand); + PREPARE(intrsor); + PREPARE(intrxor) + + PREPARE(preinc); + PREPARE(predec); + PREPARE(postinc); + PREPARE(postdec); + + PREPARE(floatadd); + PREPARE(floatsub); + PREPARE(floatmul); + PREPARE(floatdiv); + PREPARE(floataddimm); + PREPARE(floatsubimm); + PREPARE(floatmulimm); + PREPARE(floatdivimm); + + PREPARE(floatand); + PREPARE(floator); + PREPARE(floateq); + PREPARE(floatne); + PREPARE(floatgt); + PREPARE(floatge); + PREPARE(floatlt); + PREPARE(floatle); + PREPARE(floatgtimm); + PREPARE(floatgeimm); + PREPARE(floatltimm); + PREPARE(floatleimm); + + PREPARE(floatneg); + PREPARE(floatnot); + + PREPARE(floatrassign); + + PREPARE(floatradd); + PREPARE(floatrsub); + PREPARE(floatrmul); + PREPARE(floatrdiv); + + PREPARE(ifadd); + PREPARE(ifsub); + PREPARE(ifmul); + PREPARE(ifdiv); + + PREPARE(ifand); + PREPARE(ifor); + PREPARE(ifeq); + PREPARE(ifne); + PREPARE(ifgt); + PREPARE(ifge); + PREPARE(iflt); + PREPARE(ifle); + + PREPARE(ifrassign); + PREPARE(ifradd); + PREPARE(ifrsub); + PREPARE(ifrmul); + PREPARE(ifrdiv); + + PREPARE(fiadd); + PREPARE(fisub); + PREPARE(fimul); + PREPARE(fidiv); + + PREPARE(fiand); + PREPARE(fior); + PREPARE(fieq); + PREPARE(fine); + PREPARE(figt); + PREPARE(fige); + PREPARE(filt); + PREPARE(file); + + PREPARE(firassign); + + PREPARE(firadd); + PREPARE(firsub); + PREPARE(firmul); + PREPARE(firdiv); + + PREPARE(itof); + PREPARE(ftoi); + + PREPARE(timeadv); + + PREPARE(recurs); + + PREPARE(setcode); + PREPARE(regmove); + PREPARE(regtomem); + PREPARE(regtomemother); + PREPARE(overflow); + PREPARE(funcusrend); + PREPARE(funcusrend2); + PREPARE(funcmemberend); + PREPARE(sporkini); + PREPARE(forkini); + PREPARE(sporkfunc); + PREPARE(sporkmemberfptr); + PREPARE(sporkexp); + PREPARE(sporkend); + PREPARE(brancheqint); + PREPARE(branchneint); + PREPARE(brancheqfloat); + PREPARE(branchnefloat); + PREPARE(unroll); + PREPARE(arrayappend); + PREPARE(autounrollinit); + PREPARE(autoloop); + PREPARE(arraytop); + PREPARE(arrayaccess); + PREPARE(arrayget); + PREPARE(arrayaddr); + PREPARE(newobj); + PREPARE(addref); + PREPARE(addrefaddr); + PREPARE(structaddref); + PREPARE(structaddrefaddr); + PREPARE(objassign); + PREPARE(assign); + PREPARE(remref); + PREPARE(remref2); + PREPARE(except); + PREPARE(allocmemberaddr); + PREPARE(dotmember); + PREPARE(dotfloat); + PREPARE(dotother); + PREPARE(dotaddr); + PREPARE(unioncheck); + PREPARE(unionint); + PREPARE(unionfloat); + PREPARE(unionother); + PREPARE(unionaddr); + PREPARE(staticint); + PREPARE(staticfloat); + PREPARE(staticother); + PREPARE(upvalueint); + PREPARE(upvaluefloat); + PREPARE(upvalueother); + PREPARE(upvalueaddr); + PREPARE(dotfunc); + PREPARE(gacktype); + PREPARE(gackend); + PREPARE(gack); + PREPARE(try_ini); + PREPARE(try_end); + PREPARE(handleeffect); + PREPARE(performeffect); + PREPARE(noop); +_other: +{ + *(void**)prepare_code = &&other; + const f_instr exec = *(f_instr*)(prepare_code + SZ_INT *2); + if(exec == DTOR_EOC)return; + const Instr instr = *(Instr*)(prepare_code + SZ_INT); + if(exec == fast_except) + instr->opcode = (m_uint)&&noop; + else if(exec == SetFunc) + instr->opcode = (m_uint)&®pushimm; + prepare_code += BYTECODE_SZ;\ + goto *_dispatch[*(m_bit*)prepare_code]; +} + PREPARE(unroll2); + PREPARE(debugline); + PREPARE(debugvalue); + PREPARE(debugpush); + PREPARE(debugpop); +_eoc: + *(void**)prepare_code = &&eoc; +return; +} } // remove me diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index 1f8906b6..ae8a41ed 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -53,7 +53,7 @@ static inline uint isgoto(const unsigned opcode) { } ANN static inline void setpc(const m_bit *data, const m_uint i) { - *(unsigned *)(data + 1) = i + 1; + *(m_uint *)(data + SZ_INT*3) = i + 1; } ANN static m_bit *tobytecode(MemPool p, const VM_Code code) { @@ -78,7 +78,11 @@ ANN static m_bit *tobytecode(MemPool p, const VM_Code code) { next->opcode = eNoOp; } if ((instr->m_val = move)) { +// *(m_uint*)data = instr->opcode; +// memcpy(data, instr, SZ_INT); +// memcpy(data + SZ_INT*2, instr + SZ_INT, SZ_INT*2); memcpy(data, instr, BYTECODE_SZ); + setpc(data, i); } else { vector_add(&nop, i); @@ -108,9 +112,9 @@ ANN static m_bit *tobytecode(MemPool p, const VM_Code code) { if (instr->opcode == eGoto && instr->m_val == i + 1) { instr->opcode = eNoOp; vector_add(&nop, i); - } else if (instr->opcode != eNoOp) + } else if (instr->opcode != eNoOp) { memcpy(data, instr, BYTECODE_SZ); - else + } else vector_add(&nop, i); } else { *(m_bit *)(data) = instr->opcode; @@ -121,6 +125,7 @@ ANN static m_bit *tobytecode(MemPool p, const VM_Code code) { } if (!vector_size(&nop)) { vector_release(&nop); + vm_prepare(NULL, ptr); return ptr; } m_bit *const final = @@ -154,6 +159,7 @@ ANN static m_bit *tobytecode(MemPool p, const VM_Code code) { } vector_release(&nop); mp_free2(p, sz * BYTECODE_SZ, ptr); + vm_prepare(NULL, final); return final; } diff --git a/util b/util index 7b668adb..9b1b16a7 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit 7b668adba0cd3d9e6af45e9c30456b5a6f171d74 +Subproject commit 9b1b16a7f3c8583afaa7d68e1395fc70315e4f0f