diff --git a/Makefile b/Makefile index e8989d6bf..4d9a9f31b 100644 --- a/Makefile +++ b/Makefile @@ -88,6 +88,9 @@ endif ifeq (${USE_JIT}, 1) include jit/config.mk endif +ifeq (${USE_NOMEMOIZE}, 1) +CFLAGS += -DNOMEMOIZE +endif ifeq (${USE_VMBENCH}, 1) CFLAGS += -DVMBENCH diff --git a/config.mk.orig b/config.mk.orig index 50bac7dd0..170933541 100644 --- a/config.mk.orig +++ b/config.mk.orig @@ -17,18 +17,18 @@ CFLAGS += -mtune=native #CFLAGS += -fPIC # handle boolean options -USE_DOUBLE = 0 -USE_COVERAGE ?= 0 -USE_MEMCHECK ?= 0 -USE_GWREPL ?= 0 -USE_GWUDP ?= 0 -USE_OPTIMIZE ?= 0 -USE_OBSTACK ?= 0 -USE_COLOR ?= 0 -USE_JIT ?= 0 -USE_LTO ?= 0 -USE_VMBENCH ?= 0 - +USE_DOUBLE = 0 +USE_COVERAGE ?= 0 +USE_MEMCHECK ?= 0 +USE_GWREPL ?= 0 +USE_GWUDP ?= 0 +USE_OPTIMIZE ?= 0 +USE_OBSTACK ?= 0 +USE_COLOR ?= 0 +USE_JIT ?= 0 +USE_LTO ?= 0 +USE_VMBENCH ?= 0 +USE_NOMEMOIZE ?= 0 # handle definitions D_FUNC ?= dummy_driver diff --git a/include/instr.h b/include/instr.h index 33e85a704..9bdbc5cd1 100644 --- a/include/instr.h +++ b/include/instr.h @@ -35,6 +35,7 @@ INSTR(RegPushMaybe); /* staking */ INSTR(RegPop); +INSTR(RegPushImm0); INSTR(RegPushImm); INSTR(RegPushImm2); INSTR(RegPushImm3); @@ -46,8 +47,11 @@ INSTR(RegPushMem); INSTR(RegPushMem2); INSTR(RegPushMem3); INSTR(RegPushMem4); +INSTR(RegPushBase); +INSTR(RegPushBase2); +INSTR(RegPushBase3); +INSTR(RegPushBase4); INSTR(RegPushPtr); -INSTR(RegPushCode); INSTR(RegDup); INSTR(RegAddRef); diff --git a/include/memoize.h b/include/memoize.h index 22fc68794..ab52d618e 100644 --- a/include/memoize.h +++ b/include/memoize.h @@ -1,9 +1,18 @@ #ifndef __MEMOIZE #define __MEMOIZE + +#ifndef NOMEMOIZE +#define MEMOIZE_CALL if(GET_FLAG(f, pure)) emit_add_instr(emit, MemoizeCall); +#define MEMOIZE_STORE if(GET_FLAG(emit->env->func, pure)) emit_add_instr(emit, MemoizeStore); +#define MEMOIZE_INI if(GET_FLAG(func, pure)) func->code->memoize = memoize_ini(func, kindof(func->def->ret_type->size, !func->def->ret_type->size)); typedef struct Memoize_ * Memoize; -//m_bool memoize_get(VM_Shred shred); Memoize memoize_ini(const Func f, const enum Kind); void memoize_end(Memoize m); INSTR(MemoizeCall); INSTR(MemoizeStore); +#else +#define MEMOIZE_CALL +#define MEMOIZE_STORE +#define MEMOIZE_INI +#endif #endif diff --git a/include/vm.h b/include/vm.h index b0f92b5fe..628414b27 100644 --- a/include/vm.h +++ b/include/vm.h @@ -38,6 +38,7 @@ typedef struct VM_ { typedef struct VM_Shred_* VM_Shred; struct VM_Shred_ { + Vector instr; VM_Code code; VM_Shred parent; m_bit* reg; diff --git a/src/emit/emit.c b/src/emit/emit.c index 7c90651c9..bbd7b511e 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -194,9 +194,9 @@ ANN ArrayInfo* emit_array_extend_inner(const Emitter emit, const Type t, const E ANN void emit_ext_ctor(const Emitter emit, const VM_Code code) { GWDEBUG_EXE emit_add_instr(emit, RegDup); const Instr push_f = emit_add_instr(emit, RegPushImm); - *(VM_Code*)push_f->ptr = code; + push_f->m_val = (m_uint)code; const Instr offset = emit_add_instr(emit, RegPushImm); - *(m_uint*)offset->ptr = emit_code_offset(emit); + offset->m_val = emit_code_offset(emit); emit_add_instr(emit, FuncMember); } @@ -237,6 +237,7 @@ ANN static Instr emit_kind(Emitter emit, const m_uint size, const uint addr, con static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushDeref }; // caution last static const f_instr regpushderef[] = { RegPushDeref, RegPushDeref2, RegPushDeref3, RegPushDeref }; // caution last static const f_instr regpushmem[] = { RegPushMem, RegPushMem2, RegPushMem3, RegPushMem4 }; +static const f_instr regpushbase[] = { RegPushBase, RegPushBase2, RegPushBase3, RegPushBase4 }; static const f_instr dotstatic[] = { DotStatic, DotStatic2, DotStatic3, DotStatic4 }; static const f_instr dotimport[] = { DotImport, DotImport2, DotImport3, DotImport4 }; static const f_instr dotmember[] = { DotMember, DotMember2, DotMember3, DotMember4 }; @@ -260,7 +261,7 @@ ANN static m_bool emit_symbol_builtin(const Emitter emit, const Exp_Primary* pri const Value v = prim->value; if(GET_FLAG(v, func)) { const Instr instr = emit_add_instr(emit, RegPushImm); - *(Func*)instr->ptr = v->d.func_ref; + instr->m_val = (m_uint)v->d.func_ref; return GW_OK; } if(GET_FLAG(v, union)) { @@ -270,10 +271,12 @@ ANN static m_bool emit_symbol_builtin(const Emitter emit, const Exp_Primary* pri } else { const m_uint size = v->type->size; const Instr instr = emit_kind(emit, size, prim->self->emit_var, regpushimm); - if(isa(v->type, t_object) < 0) { - if(v->d.ptr) + if(size == SZ_INT) { + instr->execute = RegPushImm; + instr->m_val = (m_uint)v->d.ptr; + } else if(v->d.ptr) memcpy(instr->ptr, v->d.ptr, v->type->size); - } else + else *(m_uint**)instr->ptr = v->d.ptr; } return GW_OK; @@ -287,9 +290,8 @@ ANN static m_bool emit_symbol(const Emitter emit, const Exp_Primary* prim) { GWD GET_FLAG(v, union)) return emit_symbol_builtin(emit, prim); const m_uint size = v->type->size; - const Instr instr = emit_kind(emit, size, prim->self->emit_var, regpushmem); + const Instr instr = emit_kind(emit, size, prim->self->emit_var, !GET_FLAG(v, global) ? regpushmem : regpushbase); instr->m_val = v->offset; - *(m_uint*)instr->ptr = GET_FLAG(v, global); return GW_OK; } @@ -381,7 +383,7 @@ ANN static m_bool prim_id(const Emitter emit, const Exp_Primary* prim) { ANN static m_bool prim_num(const Emitter emit, const Exp_Primary * primary) { const Instr instr = emit_add_instr(emit, RegPushImm); - *(m_uint*)instr->ptr = primary->d.num; + instr->m_val = primary->d.num; return GW_OK; } @@ -395,7 +397,7 @@ ANN static m_bool prim_char(const Emitter emit, const Exp_Primary* prim) { const m_int c = str2char(prim->d.chr, prim->self->pos); CHECK_BB(c); const Instr instr = emit_add_instr(emit, RegPushImm); - *(m_int*)instr->ptr = c; + instr->m_val = (m_uint)c; return GW_OK; } @@ -454,7 +456,7 @@ ANN static m_bool emit_exp_primary(const Emitter emit, const Exp_Primary* prim) ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v, const uint emit_var) { GWDEBUG_EXE const Instr push = emit_add_instr(emit, RegPushImm); - *(Type*)push->ptr = v->owner_class; + push->m_val = (m_uint)v->owner_class; const m_uint size = v->type->size; const Instr instr = emit_kind(emit, size, emit_var, dotstatic); instr->m_val = v->offset; @@ -647,6 +649,12 @@ ANN static m_bool emit_exp_dur(const Emitter emit, const Exp_Dur* dur) { GWDEBUG } static inline m_bool push_func_code(const Emitter emit, const Func f) { + const Instr back = (Instr)vector_back(&emit->code->instr); + if(back->execute == RegPushBase) { + back->execute = RegPushImm; + back->m_val = (m_uint)f->code; + return GW_OK; + } const Instr instr = emit_add_instr(emit, RegPushPtr); return !!(instr->m_val = (m_uint)f->code); } @@ -658,31 +666,24 @@ static m_bool emit_template_code(const Emitter emit, const Func f) { return push_func_code(emit, f); } -ANN static m_bool emit_exp_call1_code(const Emitter emit, const Func f) { - if(GET_FLAG(f, template) && emit->env->func != f) - return emit_template_code(emit, f); - emit_add_instr(emit, RegPushCode); - return 1; -} - ANN static Instr emit_call(const Emitter emit, const Func f) { - if(GET_FLAG(f, pure)) - emit_add_instr(emit, MemoizeCall); + MEMOIZE_CALL const Type t = actual_type(f->value_ref->type); const f_instr exec = isa(t, t_fptr) < 0 ? GET_FLAG(f->def, builtin) ? GET_FLAG(f, member) ? FuncMember : FuncStatic : FuncUsr : FuncPtr; return emit_add_instr(emit, exec); } -ANN m_bool emit_exp_call1(const Emitter emit, const Func func) { GWDEBUG_EXE - if(!func->code || (GET_FLAG(func, ref) && !GET_FLAG(func, builtin))) - CHECK_BB(emit_exp_call1_code(emit, func)) - else - push_func_code(emit, func); +ANN m_bool emit_exp_call1(const Emitter emit, const Func f) { GWDEBUG_EXE + if(!f->code || (GET_FLAG(f, ref) && !GET_FLAG(f, builtin))) { + if(GET_FLAG(f, template) && emit->env->func != f) + CHECK_BB(emit_template_code(emit, f)) + } else + push_func_code(emit, f); const Instr offset = emit_add_instr(emit, RegPushImm); - *(m_uint*)offset->ptr = emit_code_offset(emit); - const Instr instr = emit_call(emit, func); - const m_uint size = instr->m_val = func->def->ret_type->size; + offset->m_val = emit_code_offset(emit); + const Instr instr = emit_call(emit, f); + const m_uint size = instr->m_val = f->def->ret_type->size; return (m_bool)(instr->m_val2 = kindof(size, !size)); } @@ -707,9 +708,12 @@ static inline void stack_alloc_this(const Emitter emit) { static m_bool scoped_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) { ++emit->env->scope; emit_push_scope(emit); - emit_add_instr(emit, GcIni); + const m_bool pure = SAFE_FLAG(emit->env->func, pure); + if(!pure) + emit_add_instr(emit, GcIni); CHECK_BB(emit_stmt(emit, stmt, pop)) - emit_add_instr(emit, GcEnd); + if(!pure) + emit_add_instr(emit, GcEnd); emit_pop_scope(emit); --emit->env->scope; return GW_OK; @@ -1259,7 +1263,7 @@ ANN static m_bool emit_dot_static_import_data(const Emitter emit, const Value v, if(v->d.ptr && GET_FLAG(v, builtin)) { // from C if(GET_FLAG(v, enum)) { const Instr func_i = emit_add_instr(emit, RegPushImm); - *(m_uint*)func_i->ptr = (m_uint)v->d.ptr; + func_i->m_val = (m_uint)v->d.ptr; } else { const m_uint size = v->type->size; const Instr instr = emit_kind(emit, size, emit_addr, dotimport); @@ -1268,7 +1272,7 @@ ANN static m_bool emit_dot_static_import_data(const Emitter emit, const Value v, } } else { // from code const Instr push_i = emit_add_instr(emit, RegPushImm); - *(Type*)push_i->ptr = v->owner_class; + push_i->m_val = (m_uint)v->owner_class; const m_uint size = v->type->size; const Instr instr = emit_kind(emit, size, emit_addr, dotstatic); instr->m_val = v->offset; @@ -1292,7 +1296,7 @@ ANN static m_bool emit_complex_member(const Emitter emit, const Exp_Dot* member) ANN static inline void emit_vec_func(const Emitter emit, const Value v) { const Instr instr = emit_add_instr(emit, RegPushImm); - *(m_uint*)instr->ptr = (m_uint)((Func)vector_at(&v->owner_class->nspc->vtable, v->d.func_ref->vt_index))->code; + instr->m_val = (m_uint)((Func)vector_at(&v->owner_class->nspc->vtable, v->d.func_ref->vt_index))->code; } ANN static m_bool emit_VecMember(const Emitter emit, const Exp_Dot* member) { @@ -1358,7 +1362,7 @@ ANN static m_bool emit_exp_dot_special(const Emitter emit, const Exp_Dot* member ANN static m_bool emit_dot_static_func(const Emitter emit, const Func func) { GWDEBUG_EXE const Instr func_i = emit_add_instr(emit, RegPushImm); - *(Func*)func_i->ptr = func; + func_i->m_val = (m_uint)func->code; return GW_OK; } @@ -1428,8 +1432,8 @@ ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot* member) { GWDE ANN static inline void emit_func_def_global(const Emitter emit, const Value value) { GWDEBUG_EXE const Instr set_mem = emit_add_instr(emit, MemSetImm); - set_mem->m_val = value->offset = emit_local(emit, value->type->size, 0); - set_mem->m_val2 = (m_uint)value->d.func_ref; + set_mem->m_val = value->offset = emit_local(emit, value->type->size, 0); // size -> SZ_INT ? + set_mem->m_val2 = (m_uint)value->d.func_ref->code; } ANN static void emit_func_def_init(const Emitter emit, const Func func) { GWDEBUG_EXE @@ -1451,8 +1455,12 @@ ANN static void emit_func_def_args(const Emitter emit, Arg_List a) { GWDEBUG_EXE ANN static void emit_func_def_ensure(const Emitter emit, const Func_Def func_def) { GWDEBUG_EXE const m_uint size = func_def->ret_type->size; - if(size) - emit_kind(emit, size, 0, regpushimm); + if(size) { + if(size == SZ_INT) + emit_add_instr(emit, RegPushImm); + else + emit_kind(emit, size, 0, regpushimm); + } vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto)); } @@ -1465,8 +1473,7 @@ ANN static void emit_func_def_return(const Emitter emit) { GWDEBUG_EXE } vector_clear(&emit->code->stack_return); emit_pop_scope(emit); - if(GET_FLAG(emit->env->func, pure)) - emit_add_instr(emit, MemoizeStore); + MEMOIZE_STORE emit_add_instr(emit, FuncReturn); } @@ -1498,9 +1505,7 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def) { G UNSET_FLAG(func_def, template);; return GW_OK; } - if(!emit->env->class_def) - emit_func_def_global(emit, func->value_ref); - else if(GET_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template)) + if(SAFE_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template)) return GW_OK; emit_func_def_init(emit, func); if(GET_FLAG(func, member)) @@ -1516,8 +1521,9 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def) { G emit_func_def_code(emit, func); emit->env->func = former; emit_pop_code(emit); - if(GET_FLAG(func, pure)) - func->code->memoize = memoize_ini(func, kindof(func->def->ret_type->size, !func->def->ret_type->size)); + if(!emit->env->class_def) + emit_func_def_global(emit, func->value_ref); + MEMOIZE_INI return GW_OK; } diff --git a/src/emit/memoize.c b/src/emit/memoize.c index 91cee3dc8..dee3664f4 100644 --- a/src/emit/memoize.c +++ b/src/emit/memoize.c @@ -1,3 +1,4 @@ +#ifndef NOMEMOIZE #include #include "gwion_util.h" #include "gwion_ast.h" @@ -102,3 +103,4 @@ INSTR(MemoizeStore) { return; } } +#endif diff --git a/src/lib/gack.c b/src/lib/gack.c index 2b08fa37d..0e53bdc93 100644 --- a/src/lib/gack.c +++ b/src/lib/gack.c @@ -7,10 +7,11 @@ #include "vm.h" #include "env.h" #include "type.h" +#include "func.h" #include "object.h" #include "instr.h" -/* static */ void print_type(const Type type) { +static void print_type(const Type type) { const m_bool is_func = isa(type, t_function) > 0 && isa(type, t_fptr) < 0; const m_str name = is_func ? strdup("@function") : strdup(type->name); gw_out("(%s) ", name); @@ -21,15 +22,15 @@ } } -/* static inline */ void print_int(const m_int i) { +static inline void print_int(const m_int i) { gw_out("%" INT_F "", i); } -/* static inline */void print_float(const m_float f) { +static inline void print_float(const m_float f) { gw_out("%.4f", f); } -/* static inline */void print_complex(const m_complex c) { +static inline void print_complex(const m_complex c) { gw_out("#("); print_float(creal(c)); gw_out(", "); @@ -37,7 +38,7 @@ gw_out(")"); } -/*static inline */void print_polar(const m_complex c) { +static inline void print_polar(const m_complex c) { gw_out("%%("); print_float(creal(c)); gw_out(", "); @@ -45,7 +46,7 @@ gw_out("*pi)"); } -/* static inline */ void print_vec(const m_bit* f, const m_uint size) { +static inline void print_vec(const m_bit* f, const m_uint size) { gw_out("@("); for(m_uint i = 0; i < size; i++) { print_float(creal(*(m_float*)(f + i * SZ_FLOAT))); @@ -55,28 +56,28 @@ gw_out(")"); } -/* static inline */void print_string1(const m_str str) { +static inline void print_string1(const m_str str) { gw_out("%s", str); } -/*static inline */void print_string(const M_Object obj) { +static inline void print_string(const M_Object obj) { print_string1(obj ? STRING(obj) : "(null string)"); } -/*static inline */void print_object(const Type type, const M_Object obj) { +static inline void print_object(const Type type, const M_Object obj) { if(isa(type, t_string) > 0) print_string(obj); else gw_out("%p", (void*)obj); } -/* static inline */ void print_func(const Type type, const m_bit* stack) { - const Func func = isa(type, t_fptr) > 0 ? - *(Func*)stack : type->d.func; - gw_out("%s %p", type->name, (void*)func); +static inline void print_func(const Type type, const m_bit* stack) { + const VM_Code code = isa(type, t_fptr) > 0 ? + *(VM_Code*)stack : type->d.func->code; + gw_out("%s %p", type->name, (void*)code); } -/*static */void print_prim(const Type type, const m_bit* stack) { +static void print_prim(const Type type, const m_bit* stack) { if(isa(type, t_int) > 0) print_int(*(m_int*)stack); else if(isa(type, t_complex) > 0) diff --git a/src/lib/instr.c b/src/lib/instr.c index f70ffbb32..9e689c161 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -59,13 +59,16 @@ INSTR(RegPop) { GWDEBUG_EXE POP_REG(shred, instr->m_val); } +INSTR(RegPushImm) { GWDEBUG_EXE + *(m_uint*)shred->reg = instr->m_val; + shred->reg += SZ_INT; +} #define describe_regpushimmxxx(name, type, size) \ INSTR(RegPush##name) { GWDEBUG_EXE \ *(type*)REG(0) = *(type*)instr->ptr; \ PUSH_REG(shred, size); \ } -describe_regpushimmxxx(Imm, m_int, SZ_INT) describe_regpushimmxxx(Imm2, m_float, SZ_FLOAT) INSTR(RegPushImm3) { GWDEBUG_EXE memcpy(REG(0), instr->ptr, instr->m_val2); @@ -83,34 +86,40 @@ INSTR(MemSetImm) { GWDEBUG_EXE #define describe_regpushxxx(name, type, size) \ INSTR(RegPush##name) { GWDEBUG_EXE \ - const m_bit* data = *(m_uint*)instr->ptr ? shred->base : shred->mem; \ - *(type*)REG(0) = *(type*)(data + instr->m_val); \ + *(type*)REG(0) = *(type*)(shred->mem + instr->m_val); \ PUSH_REG(shred, size); \ } describe_regpushxxx(Mem, m_int, SZ_INT) describe_regpushxxx(Mem2, m_float, SZ_FLOAT) INSTR(RegPushMem3) { GWDEBUG_EXE - const m_bit* data = *(m_uint*)instr->ptr ? shred->base : shred->mem; - memcpy(REG(0), (data + instr->m_val), instr->m_val2); + memcpy(REG(0), (shred->mem + instr->m_val), instr->m_val2); PUSH_REG(shred, instr->m_val2); } INSTR(RegPushMem4) { GWDEBUG_EXE - const m_bit* data = *(m_uint*)instr->ptr ? shred->base : shred->mem; - *(m_bit**)REG(0) = (m_bit*)(data + instr->m_val); + *(m_bit**)REG(0) = (m_bit*)(shred->mem + instr->m_val); PUSH_REG(shred, SZ_INT); } +#define describe_regpushbase(name, type, size) \ +INSTR(RegPush##name) { GWDEBUG_EXE \ + *(type*)REG(0) = *(type*)(shred->base + instr->m_val); \ + PUSH_REG(shred, size); \ +} -INSTR(RegPushPtr) { GWDEBUG_EXE - *(m_uint*)REG(-SZ_INT) = instr->m_val; +describe_regpushbase(Base, m_int, SZ_INT) +describe_regpushbase(Base2, m_float, SZ_FLOAT) +INSTR(RegPushBase3) { GWDEBUG_EXE + memcpy(REG(0), (shred->base + instr->m_val), instr->m_val2); + PUSH_REG(shred, instr->m_val2); +} +INSTR(RegPushBase4) { GWDEBUG_EXE + *(m_bit**)REG(0) = (m_bit*)(shred->base + instr->m_val); + PUSH_REG(shred, SZ_INT); } -INSTR(RegPushCode) { GWDEBUG_EXE - const Func f = *(Func*)REG(-SZ_INT); - if(!f) - Except(shred, "NullFuncPtrException"); - *(VM_Code*)REG(-SZ_INT) = f->code; +INSTR(RegPushPtr) { GWDEBUG_EXE + *(m_uint*)REG(-SZ_INT) = instr->m_val; } INSTR(RegDup) { GWDEBUG_EXE @@ -182,7 +191,6 @@ INSTR(BranchSwitch) { GWDEBUG_EXE shred->pc = map_get(map, (vtype)*(m_int*)REG(offset)); if(!shred->pc) shred->pc = instr->m_val; -// if(offset)free_map(map); } #define branch(name, type, sz, op) \ @@ -270,19 +278,15 @@ INSTR(SporkExp) { GWDEBUG_EXE ANN static void shred_func_prepare(const VM_Shred shred) { POP_REG(shred, SZ_INT * 2); - const VM_Code code = *(VM_Code*)REG(0); - - const m_uint local_depth = *(m_uint*)REG(SZ_INT); - const m_uint prev_stack = *(m_uint*)MEM(-SZ_INT); - const m_uint push = prev_stack + local_depth; - - PUSH_MEM(shred, push + SZ_INT*4); - *(m_uint*) MEM(-SZ_INT*4) = push; - *(VM_Code*) MEM(-SZ_INT*3) = shred->code; - *(m_uint*) MEM(-SZ_INT*2) = shred->pc; - *(m_uint*) MEM(-SZ_INT) = (m_uint)code->stack_depth; + // local depth + previous stack + const m_uint push = *(m_uint*)REG(SZ_INT) + *(m_uint*)MEM(-SZ_INT); + PUSH_MEM(shred, push + SZ_INT*3); + *(m_uint*) MEM(-SZ_INT*3) = push; + *(VM_Code*) MEM(-SZ_INT*2) = shred->code; + *(m_uint*) MEM(-SZ_INT) = shred->pc; shred->pc = 0; - shred->code = code; + shred->code = *(VM_Code*)REG(0); + shred->instr = shred->code->instr; } ANN static inline void shred_func_need_this(const VM_Shred shred) { @@ -290,15 +294,10 @@ ANN static inline void shred_func_need_this(const VM_Shred shred) { PUSH_MEM(shred, SZ_INT); } -ANN static inline void shred_func_finish(const VM_Shred shred) { - if(GET_FLAG(shred->code, member)) - POP_MEM(shred, SZ_INT); - if(overflow_(shred)) - Except(shred, "StackOverflow"); -} - INSTR(FuncPtr) { GWDEBUG_EXE const VM_Code code = *(VM_Code*)REG(-SZ_INT*2); + if(!code) + Except(shred, "NullFuncPtrException"); if(!GET_FLAG(code, builtin)) FuncUsr(shred, instr); else if(GET_FLAG(code, member)) @@ -313,21 +312,24 @@ INSTR(FuncUsr) { GWDEBUG_EXE m_uint stack_depth = code->stack_depth; if(stack_depth) { POP_REG(shred, stack_depth); - if(GET_FLAG(shred->code, member)) { + if(GET_FLAG(code, member)) { shred_func_need_this(shred); stack_depth -= SZ_INT; } for(m_uint i = 0; i < stack_depth; i+= SZ_INT) *(m_uint*)MEM(i) = *(m_uint*)REG(i); + if(GET_FLAG(code, member)) + POP_MEM(shred, SZ_INT); } - shred_func_finish(shred); + if(overflow_(shred)) + Except(shred, "StackOverflow"); } INSTR(DotFunc) { GWDEBUG_EXE const M_Object obj = *(M_Object*)REG(-SZ_INT); if(!obj) Except(shred, "NullPtrException"); - *(Func*)REG(-SZ_INT) = (Func)vector_at(&obj->type_ref->nspc->vtable, instr->m_val); + *(VM_Code*)REG(-SZ_INT) = ((Func)vector_at(&obj->type_ref->nspc->vtable, instr->m_val))->code; } INSTR(FuncStatic) { GWDEBUG_EXE @@ -383,9 +385,10 @@ INSTR(FuncMember) { GWDEBUG_EXE } INSTR(FuncReturn) { GWDEBUG_EXE - shred->pc = *(m_uint*)MEM(-SZ_INT*2); - shred->code = *(VM_Code*)MEM(-SZ_INT*3); - POP_MEM(shred, *(m_uint*)MEM(-SZ_INT*4) + SZ_INT*4); + shred->pc = *(m_uint*)MEM(-SZ_INT); + shred->code = *(VM_Code*)MEM(-SZ_INT*2); + shred->instr = shred->code->instr; + POP_MEM(shred, *(m_uint*)MEM(-SZ_INT*3) + SZ_INT*3); } INSTR(PreCtor) { GWDEBUG_EXE diff --git a/src/parse/operator.c b/src/parse/operator.c index 475bc0247..2c2b7df32 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -173,7 +173,7 @@ ANN m_bool operator_set_func(const struct Op_Import* opi) { ANN static m_bool handle_instr(const Emitter emit, const M_Operator* mo) { if(mo->func) { const Instr instr = emit_add_instr(emit, RegPushImm); - *(Func*)instr->ptr = mo->func; + instr->m_val = (m_uint)mo->func; return emit_exp_call1(emit, mo->func); } emit_add_instr(emit, mo->instr); diff --git a/src/vm/vm.c b/src/vm/vm.c index e751f4bac..4fddafe82 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -74,6 +74,7 @@ ANN m_uint vm_add_shred(const VM* vm, const VM_Shred shred) { shred->me = new_shred(shred); shreduler_add(vm->shreduler, shred); shredule(vm->shreduler, shred, .5); + shred->instr = shred->code->instr; return shred->xid; } @@ -120,7 +121,8 @@ struct timespec exec_ini, exec_end, exec_ret; clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini); #endif do { - const Instr instr = (Instr)vector_at(shred->code->instr, shred->pc++); +// const Instr instr = (Instr)vector_at(shred->code->instr, shred->pc++); + const Instr instr = (Instr)vector_at(shred->instr, shred->pc++); instr->execute(shred, instr); VM_INFO; } while(s->curr); diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index 7501608d1..bc93a29f9 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -66,8 +66,10 @@ ANN static void free_code_instr(const Vector v) { } void free_vm_code(VM_Code a) { +#ifndef NOMEMOIZE if(a->memoize) memoize_end(a->memoize); +#endif if(a->instr) free_code_instr(a->instr); free(a->name);