From 78f7dc2cc481f5c66d90bf654d149bde58db4412 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 25 Jan 2019 20:32:27 +0100 Subject: [PATCH 01/59] :art: Fix instr improvements --- src/lib/instr.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lib/instr.c b/src/lib/instr.c index 9e689c161..9dfdfc3b9 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -90,7 +90,7 @@ INSTR(RegPush##name) { GWDEBUG_EXE \ PUSH_REG(shred, size); \ } -describe_regpushxxx(Mem, m_int, SZ_INT) +describe_regpushxxx(Mem, m_uint, SZ_INT) describe_regpushxxx(Mem2, m_float, SZ_FLOAT) INSTR(RegPushMem3) { GWDEBUG_EXE memcpy(REG(0), (shred->mem + instr->m_val), instr->m_val2); @@ -107,7 +107,7 @@ INSTR(RegPush##name) { GWDEBUG_EXE \ PUSH_REG(shred, size); \ } -describe_regpushbase(Base, m_int, SZ_INT) +describe_regpushbase(Base, m_uint, SZ_INT) describe_regpushbase(Base2, m_float, SZ_FLOAT) INSTR(RegPushBase3) { GWDEBUG_EXE memcpy(REG(0), (shred->base + instr->m_val), instr->m_val2); @@ -188,7 +188,7 @@ INSTR(BranchSwitch) { GWDEBUG_EXE const m_uint offset = *(m_uint*)instr->ptr; POP_REG(shred, SZ_INT + offset); const Map map = !offset ?(Map)instr->m_val2 : *(Map*)REG(0); - shred->pc = map_get(map, (vtype)*(m_int*)REG(offset)); + shred->pc = map_get(map, *(m_uint*)REG(offset)); if(!shred->pc) shred->pc = instr->m_val; } @@ -199,14 +199,14 @@ INSTR(Branch##name) { GWDEBUG_EXE \ if(*(type*)REG(0) op *(type*)REG(sz)) \ shred->pc = instr->m_val; \ } -branch(EqInt, m_int, SZ_INT, ==) -branch(NeqInt, m_int, SZ_INT, !=) -branch(EqFloat, m_float, SZ_FLOAT, ==) +branch(EqInt, m_uint, SZ_INT, ==) +branch(NeqInt, m_uint, SZ_INT, !=) +branch(EqFloat, m_float, SZ_FLOAT, ==) branch(NeqFloat, m_float, SZ_FLOAT, !=) INSTR(InitLoopCounter) { GWDEBUG_EXE POP_REG(shred, SZ_INT); - (*(m_int*)instr->m_val) = labs(*(m_int*)REG(0)); + (*(m_uint*)instr->m_val) = labs(*(m_int*)REG(0)); } INSTR(RegPushDeref) { GWDEBUG_EXE @@ -225,7 +225,7 @@ INSTR(RegPushDeref3) { GWDEBUG_EXE } INSTR(DecIntAddr) { GWDEBUG_EXE - --(*((m_int*)(instr->m_val))); + --(*((m_uint*)(instr->m_val))); } INSTR(Goto) { GWDEBUG_EXE From dac0fd231ba64e5bb5548566d8572db390a050cb Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 25 Jan 2019 20:34:50 +0100 Subject: [PATCH 02/59] :art: Fix user enums and other improvments --- src/emit/emit.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index bbd7b511e..982f460aa 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -286,8 +286,7 @@ ANN static m_bool emit_symbol(const Emitter emit, const Exp_Primary* prim) { GWD const Value v = prim->value; if(v->owner_class) return emit_symbol_owned(emit, prim); - if(GET_FLAG(v, builtin) || GET_FLAG(v, enum) || - GET_FLAG(v, union)) + if(GET_FLAG(v, builtin) || 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, !GET_FLAG(v, global) ? regpushmem : regpushbase); @@ -735,7 +734,7 @@ ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) { GWDEBUG_ SET_FLAG(emit->code, member); const Instr op = emit_add_instr(emit, MemPushImm); op->m_val = emit->code->stack_depth; - emit_add_instr(emit, RegPushImm); // should push func + emit_add_instr(emit, PushNull); // (was PushImm) should push func CHECK_BB(emit_exp_call1(emit, exp->m_func)) const VM_Code code = finalyze(emit); const m_uint size = exp->m_func->def->stack_depth - (GET_FLAG(exp->m_func, @@ -744,7 +743,7 @@ ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) { GWDEBUG_ } ANN static m_bool spork_code(const Emitter emit, const Stmt stmt) { GWDEBUG_EXE - emit_add_instr(emit, RegPushImm); + emit_add_instr(emit, PushNull); // was PushImm push_spork_code(emit, SPORK_CODE_PREFIX, stmt->pos); if(SAFE_FLAG(emit->env->func, member)) stack_alloc_this(emit); @@ -1457,7 +1456,7 @@ ANN static void emit_func_def_ensure(const Emitter emit, const Func_Def func_def const m_uint size = func_def->ret_type->size; if(size) { if(size == SZ_INT) - emit_add_instr(emit, RegPushImm); + emit_add_instr(emit, PushNull); else emit_kind(emit, size, 0, regpushimm); } From 33c91ae3566a5116a06755abea606cd4fcff37fc Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 8 Feb 2019 16:16:20 +0100 Subject: [PATCH 03/59] :art: Try vm with computed gotos --- examples/binary_tmpl.gw | 2 +- examples/class_coverage.gw | 4 +- examples/class_spork_func.gw | 2 +- examples/op2.gw | 4 +- examples/spork_exp.gw | 4 +- examples/spork_func.gw | 6 +- help/opcode.sh | 24 ++ include/context.h | 1 - include/gack.h | 4 + include/import.h | 16 +- include/instr.h | 96 +---- include/nspc.h | 1 - include/object.h | 2 + include/oo.h | 22 +- include/opcode.h | 310 +++++++++++++++ include/parse.h | 10 +- include/value.h | 1 - include/vm.h | 30 +- opcode.txt | 152 +++++++ src/emit/emit.c | 274 ++++++++----- src/emit/emitter.c | 7 +- src/lib/array.c | 25 +- src/lib/float.c | 146 ------- src/lib/func.c | 23 +- src/lib/gack.c | 29 +- src/lib/import.c | 5 +- src/lib/instr.c | 563 +++++--------------------- src/lib/int.c | 72 ---- src/lib/object.c | 38 +- src/lib/string.c | 5 - src/main.c | 27 +- src/oo/context.c | 14 +- src/oo/nspc.c | 24 +- src/oo/oo.c | 20 - src/oo/type.c | 18 +- src/oo/value.c | 18 +- src/parse/check.c | 58 ++- src/parse/func.c | 24 +- src/parse/scan1.c | 24 +- src/parse/scan2.c | 39 +- src/vm/shreduler.c | 1 - src/vm/vm.c | 674 +++++++++++++++++++++++++++++++- src/vm/vm_code.c | 44 +-- tests/error/empty_member_ptr.gw | 2 +- tests/error/func_ptr_empty.gw | 2 +- 45 files changed, 1738 insertions(+), 1129 deletions(-) create mode 100644 help/opcode.sh create mode 100644 include/gack.h create mode 100644 include/opcode.h create mode 100644 opcode.txt delete mode 100644 src/oo/oo.c diff --git a/examples/binary_tmpl.gw b/examples/binary_tmpl.gw index 71a1ae83b..60253182f 100644 --- a/examples/binary_tmpl.gw +++ b/examples/binary_tmpl.gw @@ -1,4 +1,4 @@ -template fun void test(A a) { <<>>; } +template<~A~> fun void test(A a) { <<>>; } 1 => test; 1.3 => test; test(1); diff --git a/examples/class_coverage.gw b/examples/class_coverage.gw index 7e19954e7..9bba0ea2e 100644 --- a/examples/class_coverage.gw +++ b/examples/class_coverage.gw @@ -4,8 +4,8 @@ class C float f; complex c; polar p; - Vec3 v; - Vec4 w; + Vec3 v; + Vec4 w; Object o; dtor { <<<"dtor">>>; } } diff --git a/examples/class_spork_func.gw b/examples/class_spork_func.gw index 14b0d02c3..e375e598a 100644 --- a/examples/class_spork_func.gw +++ b/examples/class_spork_func.gw @@ -5,7 +5,7 @@ class C samp => now; <<<"and now">>>; } - spork test(); + spork this.test(); } C c; diff --git a/examples/op2.gw b/examples/op2.gw index fee33bb90..0f1e51a21 100644 --- a/examples/op2.gw +++ b/examples/op2.gw @@ -12,9 +12,9 @@ operator => Vec3 (Vec3 c, C d){ << d.f>>>; return @(1.2, 6.1, 2.3 operator => Vec4 (Vec4 c, C d){ <<<"Vec4 => C: ", c.w => d.f>>>; return @(1.2, 6.1, 2.3, 9.3);} operator => float (C d, int c){ <<<"int => C: ", c => d.f>>>; return 2.0;} -operator => float (C d, float f){ <<<"float => C: ", f => d.f>>>; return 2.0;} +operator => float (C d, float f){ <<<"C => float: ", f => d.f>>>; return 2.0;} -operator => float (Vec3 v, float f){ <<<"float => C: ", f, v.x => f>>>; return 2.0;} +operator => float (Vec3 v, float f){ <<<"vec3 => C: ", f, " ", v.x => f>>>; return 2.0;} operator => complex (C d, complex c){ <<<"complex => C: ", c.re => d.f>>>; return #(1.2, 6.1);} operator => polar (C d, polar c){ <<<"complex => C: ", c.mod => d.f>>>; return %(2.3, 4.1);} diff --git a/examples/spork_exp.gw b/examples/spork_exp.gw index 1b539b078..8c3e465c9 100644 --- a/examples/spork_exp.gw +++ b/examples/spork_exp.gw @@ -2,11 +2,13 @@ class C { 12 => int i; Object o; +<<>>; spork { "test"; second => now; string s; - <<< "test spork exp." >>>; + <<< this, " test spork exp. " , s>>>; + } @=> Shred @shred; } diff --git a/examples/spork_func.gw b/examples/spork_func.gw index df34c858a..14252342e 100644 --- a/examples/spork_func.gw +++ b/examples/spork_func.gw @@ -1,13 +1,13 @@ class C { - function void test() { - <<<"here">>>; + function void test(int i) { + <<<"here => ", i>>>; samp => now; <<<"and now">>>; } } C c; -spork c.test(); +spork c.test(2); me.yield(); 4::samp => now; diff --git a/help/opcode.sh b/help/opcode.sh new file mode 100644 index 000000000..194df2b18 --- /dev/null +++ b/help/opcode.sh @@ -0,0 +1,24 @@ +echo "#ifndef __GWION_OPCODES__" +echo "#define __GWION_OPCODES__" + +list=$(grep -v "#" opcode.txt) +COUNT=0 +echo "enum {" +for a in ${list} +do + [ -z "$a" ] || { + echo " $a," + COUNT=$((COUNT+1)) + } +done +echo "};" +echo "" + +for a in ${list} +do + [ -z "$a" ] || echo "#define $a (f_instr)$a" +done | column -t + +echo "#endif" + +echo "generated" "$COUNT" "opcodes" >&2 diff --git a/include/context.h b/include/context.h index 60c42603a..2846abcb2 100644 --- a/include/context.h +++ b/include/context.h @@ -12,5 +12,4 @@ struct Context_ { ANN2(2) ANEW Context new_context(const Ast, const m_str); ANN void load_context(const Context, const Env); ANN void unload_context(const Context, const Env); -ANN void free_context(const Context); #endif diff --git a/include/gack.h b/include/gack.h new file mode 100644 index 000000000..54fc7fcb7 --- /dev/null +++ b/include/gack.h @@ -0,0 +1,4 @@ +#ifndef __GACK +#define __GACK +ANN void gack(const m_bit*, const Instr); +#endif diff --git a/include/import.h b/include/import.h index 453ed9339..c27a6a1c3 100644 --- a/include/import.h +++ b/include/import.h @@ -2,16 +2,22 @@ #define __IMPORT #define DLARG_MAX 6 -typedef void (*f_xtor)(const M_Object o, const VM_Shred sh); +typedef void (*f_xtor)(const M_Object o, const m_bit*, const VM_Shred); +//typedef void (*f_xtor)(const M_Object o, const VM_Shred); typedef void (*f_mfun)(const M_Object o, const m_bit* RETURN, const VM_Shred sh); typedef void (*f_sfun)(const m_bit* RETURN, const VM_Shred sh); +//typedef void (*f_sfun)(const m_bit*, const m_bit* RETURN, const VM_Shred sh); typedef void (*f_xfun)(); typedef struct Gwi_* Gwi; #define MFUN(a) ANN void a(const M_Object o __attribute__((unused)), const m_bit* RETURN __attribute__((unused)), const VM_Shred shred __attribute__((unused))) #define SFUN(a) ANN void a(const m_bit* RETURN __attribute__((unused)), const VM_Shred shred __attribute__((unused))) -#define CTOR(a) ANN void a(const M_Object o, const VM_Shred shred __attribute__((unused))) -#define DTOR(a) ANN void a(const M_Object o, const VM_Shred shred __attribute__((unused))) +//#define SFUN(a) ANN void a(const m_bit* mem __attribute__((unused)), const m_bit* RETURN +//__attribute__((unused)), const VM_Shred shred __attribute__((unused))) +#define CTOR(a) ANN void a(const M_Object o, const m_bit* _ __attribute__((unused)), const VM_Shred shred __attribute__((unused))) +//#define CTOR(a) ANN void a(const M_Object o, const VM_Shred shred __attribute__((unused))) +#define DTOR(a) ANN void a(const M_Object o, const m_bit* _ __attribute__((unused)), const VM_Shred shred __attribute__((unused))) +//#define DTOR(a) ANN void a(const M_Object o, const VM_Shred shred __attribute__((unused))) #define OP_CHECK(a) ANN Type a(const Env env __attribute__((unused)), void* data __attribute__((unused))) #define OP_EMIT(a) ANN m_bool a(const Emitter emit __attribute__((unused)), void* data __attribute__((unused))) #ifdef GWION_BUILTIN @@ -73,4 +79,8 @@ OP_CHECK(opck_basic_cast); OP_CHECK(opck_new); OP_EMIT(opem_basic_cast); OP_EMIT(opem_new); + + +ANN /*static */ Type_List str2tl(const Env env, const m_str s, m_uint *depth); + #endif diff --git a/include/instr.h b/include/instr.h index 9bdbc5cd1..8b1677be4 100644 --- a/include/instr.h +++ b/include/instr.h @@ -20,9 +20,14 @@ enum Kind { typedef struct Instr_ * Instr; typedef void (*f_instr)(const VM_Shred, const Instr); struct Instr_ { - void (*execute)(const VM_Shred shred, const Instr instr); - m_uint m_val, m_val2; + m_bit opcode; +// union { +// m_float f; + m_uint m_val; +// }; + m_uint m_val2; m_bit ptr[SZ_MINVAL]; + void (*execute)(const VM_Shred shred, const Instr instr); }; INSTR(EOC); @@ -30,99 +35,19 @@ INSTR(DTOR_EOC); INSTR(DtorReturn); INSTR(RegPushMe); -INSTR(RegPushNow); INSTR(RegPushMaybe); -/* staking */ -INSTR(RegPop); -INSTR(RegPushImm0); -INSTR(RegPushImm); -INSTR(RegPushImm2); -INSTR(RegPushImm3); -INSTR(RegPushImm4); -INSTR(RegPushMemAddr); -INSTR(MemPushImm); -INSTR(MemSetImm); -INSTR(RegPushMem); -INSTR(RegPushMem2); -INSTR(RegPushMem3); -INSTR(RegPushMem4); -INSTR(RegPushBase); -INSTR(RegPushBase2); -INSTR(RegPushBase3); -INSTR(RegPushBase4); -INSTR(RegPushPtr); -INSTR(RegDup); -INSTR(RegAddRef); - /* branching */ INSTR(BranchSwitch); INSTR(SwitchIni); INSTR(SwitchEnd); -INSTR(BranchEqInt); -INSTR(BranchNeqInt); -INSTR(BranchEqFloat); -INSTR(BranchNeqFloat); -INSTR(InitLoopCounter); -INSTR(RegPushDeref); -INSTR(RegPushDeref2); -INSTR(RegPushDeref3); -INSTR(DecIntAddr); -INSTR(Goto); - -/* casting */ -INSTR(CastI2F); -INSTR(CastF2I); - -/* debugging */ -INSTR(Gack); - -INSTR(RegPushStr); - -INSTR(IntNot); -INSTR(FloatTimes); INSTR(ComplexReal); INSTR(ComplexImag); -INSTR(AllocWord); -INSTR(AllocWord2); -INSTR(AllocWord3); -INSTR(AllocWord4); - /* function */ -INSTR(SporkExp); -INSTR(SporkFunc); -INSTR(FuncUsr); -INSTR(DotFunc); -INSTR(FuncStatic); -INSTR(FuncMember); -INSTR(FuncPtr); -INSTR(FuncReturn); INSTR(DtorReturn); -/* object */ -INSTR(PreCtor); -INSTR(ObjectInstantiate); -INSTR(ObjectAssign); -INSTR(PushNull); -INSTR(PushNull2); -INSTR(PushNull3); -INSTR(AllocMember4); -INSTR(DotStatic); -INSTR(DotStatic2); -INSTR(DotStatic3); -INSTR(DotStatic4); -INSTR(DotImport); -INSTR(DotImport2); -INSTR(DotImport3); -INSTR(DotImport4); -INSTR(DotMember); -INSTR(DotMember2); -INSTR(DotMember3); -INSTR(DotMember4); -INSTR(ObjectRelease); - /* array */ INSTR(ArrayTop); INSTR(ArrayBottom); @@ -144,17 +69,14 @@ INSTR(MemberFunction); INSTR(VecMember); INSTR(PopArrayClass); -INSTR(GcIni); -INSTR(GcEnd); -INSTR(GcAdd); - INSTR(AutoLoopStart); INSTR(AutoLoopEnd); - +INSTR(DotTmpl); // optimizations #ifdef OPTIMIZE INSTR(PutArgsInMem); INSTR(ConstPropSet); INSTR(ConstPropGet); #endif +#include "opcode.h" #endif diff --git a/include/nspc.h b/include/nspc.h index ccf7d6360..07c2d5ded 100644 --- a/include/nspc.h +++ b/include/nspc.h @@ -17,7 +17,6 @@ struct Nspc_ { }; extern ANEW ANN Nspc new_nspc(const m_str name); -extern ANN void free_nspc(const Nspc a); extern ANN void nspc_commit(const Nspc); //extern ANN void nspc_rollback(const Nspc); diff --git a/include/object.h b/include/object.h index 20afdbb1e..850a0ad68 100644 --- a/include/object.h +++ b/include/object.h @@ -4,6 +4,8 @@ typedef struct M_Object_ * M_Object; struct M_Object_ { m_bit* data; Type type_ref; +// Nspc nspc;// + Vector vtable; struct pool* p; size_t ref; }; diff --git a/include/oo.h b/include/oo.h index 566898b33..ec55ede30 100644 --- a/include/oo.h +++ b/include/oo.h @@ -1,25 +1,23 @@ #ifndef __OO #define __OO -typedef struct VM_Object_ * VM_Object; typedef struct Type_ * Type; typedef struct Nspc_ * Nspc; typedef struct Value_ * Value; typedef struct Func_ * Func; -typedef enum { - e_nspc_obj, e_context_obj, - e_type_obj, e_value_obj, e_func_obj, e_code_obj -} e_obj; struct VM_Object_ { - size_t ref_count; - e_obj type; -} __attribute__((packed)); - + uint16_t ref_count; // could be an unsigned short + void (*free)(void*); +}; #define HAS_OBJ struct VM_Object_ obj; -#define INIT_OO(a, b) { (a)->obj.type = b; (a)->obj.ref_count = 1; } -#define REM_REF(a) { rem_ref(&(a)->obj, (a)); } +#define INIT_OO(a, b) { (a)->obj.ref_count = 1; (a)->obj.free= (void(*)(void*))b; } +ANN static inline void rem_ref(struct VM_Object_* a, void* ptr) { + if(--a->ref_count) + return; + a->free(ptr); +} #define ADD_REF(a) { ++(a)->obj.ref_count; } -ANN void rem_ref(const VM_Object a, void* ptr); +#define REM_REF(a) { rem_ref(&(a)->obj, (a)); } #endif diff --git a/include/opcode.h b/include/opcode.h new file mode 100644 index 000000000..6af942c7a --- /dev/null +++ b/include/opcode.h @@ -0,0 +1,310 @@ +#ifndef __GWION_OPCODES__ +#define __GWION_OPCODES__ +enum { + RegPushImm, + RegPushImm2, + RegPushImm3, + RegPushImm4, + RegPushMem, + RegPushMem2, + RegPushMem3, + RegPushMem4, + RegPushNow, + RegPushBase, + RegPushBase2, + RegPushBase3, + RegPushBase4, + RegDup, + MemPushImm, + MemSetImm, + RegPop, + RegPushPtr, + FuncReturn, + Goto, + AllocWord, + AllocWord2, + AllocWord3, + AllocWord4, + int_plus, + int_minus, + int_mul, + int_div, + int_modulo, + int_eq, + int_neq, + int_and, + int_or, + int_gt, + int_ge, + int_lt, + int_le, + int_sl, + int_sr, + int_sand, + int_sor, + int_xor, + int_negate, + IntNot, + int_cmp, + int_r_assign, + int_r_plus, + int_r_minus, + int_r_mul, + int_r_div, + int_r_modulo, + int_r_sl, + int_r_sr, + int_r_sand, + int_r_sor, + int_r_sxor, + int_pre_inc, + int_pre_dec, + int_post_inc, + int_post_dec, + FloatPlus, + FloatMinus, + FloatTimes, + FloatDivide, + float_and, + float_or, + float_eq, + float_neq, + float_gt, + float_ge, + float_lt, + float_le, + float_negate, + float_not, + float_r_assign, + float_r_plus, + float_r_minus, + float_r_mul, + float_r_div, + int_float_plus, + int_float_minus, + int_float_mul, + int_float_div, + int_float_and, + int_float_or, + int_float_eq, + int_float_neq, + int_float_gt, + int_float_ge, + int_float_lt, + int_float_le, + int_float_r_assign, + int_float_r_plus, + int_float_r_minus, + int_float_r_mul, + int_float_r_div, + float_int_plus, + float_int_minus, + float_int_mul, + float_int_div, + float_int_and, + float_int_or, + float_int_eq, + float_int_neq, + float_int_gt, + float_int_ge, + float_int_lt, + float_int_le, + float_int_r_assign, + float_int_r_plus, + float_int_r_minus, + float_int_r_mul, + float_int_r_div, + CastI2F, + CastF2I, + Time_Advance, + FuncUsr, + FuncMember, + FuncStatic, + SporkIni, + SporkFunc, + SporkThis, + SporkExp, + SporkEnd, + FuncPtr, + BranchEqInt, + BranchNeqInt, + BranchEqFloat, + BranchNeqFloat, + DecIntAddr, + InitLoopCounter, + ObjectInstantiate, + RegAddRef, + ObjectAssign, + ObjectRelease, + GWOP_EXCEPT, + AllocMember4, + DotMember, + DotMember2, + DotMember3, + DotMember4, + DotStatic, + DotStatic2, + DotStatic3, + DotFunc, + PushStaticCode, + RegPushStr, + GcIni, + GcAdd, + GcEnd, + Gack, + OP_MAX, +}; + +#define RegPushImm (f_instr)RegPushImm +#define RegPushImm2 (f_instr)RegPushImm2 +#define RegPushImm3 (f_instr)RegPushImm3 +#define RegPushImm4 (f_instr)RegPushImm4 +#define RegPushMem (f_instr)RegPushMem +#define RegPushMem2 (f_instr)RegPushMem2 +#define RegPushMem3 (f_instr)RegPushMem3 +#define RegPushMem4 (f_instr)RegPushMem4 +#define RegPushNow (f_instr)RegPushNow +#define RegPushBase (f_instr)RegPushBase +#define RegPushBase2 (f_instr)RegPushBase2 +#define RegPushBase3 (f_instr)RegPushBase3 +#define RegPushBase4 (f_instr)RegPushBase4 +#define RegDup (f_instr)RegDup +#define MemPushImm (f_instr)MemPushImm +#define MemSetImm (f_instr)MemSetImm +#define RegPop (f_instr)RegPop +#define RegPushPtr (f_instr)RegPushPtr +#define FuncReturn (f_instr)FuncReturn +#define Goto (f_instr)Goto +#define AllocWord (f_instr)AllocWord +#define AllocWord2 (f_instr)AllocWord2 +#define AllocWord3 (f_instr)AllocWord3 +#define AllocWord4 (f_instr)AllocWord4 +#define int_plus (f_instr)int_plus +#define int_minus (f_instr)int_minus +#define int_mul (f_instr)int_mul +#define int_div (f_instr)int_div +#define int_modulo (f_instr)int_modulo +#define int_eq (f_instr)int_eq +#define int_neq (f_instr)int_neq +#define int_and (f_instr)int_and +#define int_or (f_instr)int_or +#define int_gt (f_instr)int_gt +#define int_ge (f_instr)int_ge +#define int_lt (f_instr)int_lt +#define int_le (f_instr)int_le +#define int_sl (f_instr)int_sl +#define int_sr (f_instr)int_sr +#define int_sand (f_instr)int_sand +#define int_sor (f_instr)int_sor +#define int_xor (f_instr)int_xor +#define int_negate (f_instr)int_negate +#define IntNot (f_instr)IntNot +#define int_cmp (f_instr)int_cmp +#define int_r_assign (f_instr)int_r_assign +#define int_r_plus (f_instr)int_r_plus +#define int_r_minus (f_instr)int_r_minus +#define int_r_mul (f_instr)int_r_mul +#define int_r_div (f_instr)int_r_div +#define int_r_modulo (f_instr)int_r_modulo +#define int_r_sl (f_instr)int_r_sl +#define int_r_sr (f_instr)int_r_sr +#define int_r_sand (f_instr)int_r_sand +#define int_r_sor (f_instr)int_r_sor +#define int_r_sxor (f_instr)int_r_sxor +#define int_pre_inc (f_instr)int_pre_inc +#define int_pre_dec (f_instr)int_pre_dec +#define int_post_inc (f_instr)int_post_inc +#define int_post_dec (f_instr)int_post_dec +#define FloatPlus (f_instr)FloatPlus +#define FloatMinus (f_instr)FloatMinus +#define FloatTimes (f_instr)FloatTimes +#define FloatDivide (f_instr)FloatDivide +#define float_and (f_instr)float_and +#define float_or (f_instr)float_or +#define float_eq (f_instr)float_eq +#define float_neq (f_instr)float_neq +#define float_gt (f_instr)float_gt +#define float_ge (f_instr)float_ge +#define float_lt (f_instr)float_lt +#define float_le (f_instr)float_le +#define float_negate (f_instr)float_negate +#define float_not (f_instr)float_not +#define float_r_assign (f_instr)float_r_assign +#define float_r_plus (f_instr)float_r_plus +#define float_r_minus (f_instr)float_r_minus +#define float_r_mul (f_instr)float_r_mul +#define float_r_div (f_instr)float_r_div +#define int_float_plus (f_instr)int_float_plus +#define int_float_minus (f_instr)int_float_minus +#define int_float_mul (f_instr)int_float_mul +#define int_float_div (f_instr)int_float_div +#define int_float_and (f_instr)int_float_and +#define int_float_or (f_instr)int_float_or +#define int_float_eq (f_instr)int_float_eq +#define int_float_neq (f_instr)int_float_neq +#define int_float_gt (f_instr)int_float_gt +#define int_float_ge (f_instr)int_float_ge +#define int_float_lt (f_instr)int_float_lt +#define int_float_le (f_instr)int_float_le +#define int_float_r_assign (f_instr)int_float_r_assign +#define int_float_r_plus (f_instr)int_float_r_plus +#define int_float_r_minus (f_instr)int_float_r_minus +#define int_float_r_mul (f_instr)int_float_r_mul +#define int_float_r_div (f_instr)int_float_r_div +#define float_int_plus (f_instr)float_int_plus +#define float_int_minus (f_instr)float_int_minus +#define float_int_mul (f_instr)float_int_mul +#define float_int_div (f_instr)float_int_div +#define float_int_and (f_instr)float_int_and +#define float_int_or (f_instr)float_int_or +#define float_int_eq (f_instr)float_int_eq +#define float_int_neq (f_instr)float_int_neq +#define float_int_gt (f_instr)float_int_gt +#define float_int_ge (f_instr)float_int_ge +#define float_int_lt (f_instr)float_int_lt +#define float_int_le (f_instr)float_int_le +#define float_int_r_assign (f_instr)float_int_r_assign +#define float_int_r_plus (f_instr)float_int_r_plus +#define float_int_r_minus (f_instr)float_int_r_minus +#define float_int_r_mul (f_instr)float_int_r_mul +#define float_int_r_div (f_instr)float_int_r_div +#define CastI2F (f_instr)CastI2F +#define CastF2I (f_instr)CastF2I +#define Time_Advance (f_instr)Time_Advance +#define FuncUsr (f_instr)FuncUsr +#define FuncMember (f_instr)FuncMember +#define FuncStatic (f_instr)FuncStatic +#define SporkIni (f_instr)SporkIni +#define SporkFunc (f_instr)SporkFunc +#define SporkThis (f_instr)SporkThis +#define SporkExp (f_instr)SporkExp +#define SporkEnd (f_instr)SporkEnd +#define FuncPtr (f_instr)FuncPtr +#define BranchEqInt (f_instr)BranchEqInt +#define BranchNeqInt (f_instr)BranchNeqInt +#define BranchEqFloat (f_instr)BranchEqFloat +#define BranchNeqFloat (f_instr)BranchNeqFloat +#define DecIntAddr (f_instr)DecIntAddr +#define InitLoopCounter (f_instr)InitLoopCounter +#define ObjectInstantiate (f_instr)ObjectInstantiate +#define RegAddRef (f_instr)RegAddRef +#define ObjectAssign (f_instr)ObjectAssign +#define ObjectRelease (f_instr)ObjectRelease +#define GWOP_EXCEPT (f_instr)GWOP_EXCEPT +#define AllocMember4 (f_instr)AllocMember4 +#define DotMember (f_instr)DotMember +#define DotMember2 (f_instr)DotMember2 +#define DotMember3 (f_instr)DotMember3 +#define DotMember4 (f_instr)DotMember4 +#define DotStatic (f_instr)DotStatic +#define DotStatic2 (f_instr)DotStatic2 +#define DotStatic3 (f_instr)DotStatic3 +#define DotFunc (f_instr)DotFunc +#define PushStaticCode (f_instr)PushStaticCode +#define RegPushStr (f_instr)RegPushStr +#define GcIni (f_instr)GcIni +#define GcAdd (f_instr)GcAdd +#define GcEnd (f_instr)GcEnd +#define Gack (f_instr)Gack +#define OP_MAX (f_instr)OP_MAX +#endif diff --git a/include/parse.h b/include/parse.h index bcd18e3d7..8b5b554a6 100644 --- a/include/parse.h +++ b/include/parse.h @@ -1,13 +1,19 @@ #ifndef __PARSE #define __PARSE #define RET_NSPC(exp) \ -++env->scope; \ +++env->scope; \ nspc_push_value(env->curr); \ const m_bool ret = exp; \ nspc_pop_value(env->curr); \ ---env->scope; \ +--env->scope; \ return ret; +#define SET_ACCESS(a,b) \ +if(GET_FLAG(a, private)) \ + SET_FLAG(b, private); \ +else if(GET_FLAG(a, protect)) \ + SET_FLAG(b, protect); + typedef m_bool (*_exp_func)(const void*, const void*); static inline m_bool dummy_func(const void*a __attribute__((unused)), const void*b __attribute__((unused))) { return 1; } diff --git a/include/value.h b/include/value.h index 541ae2044..403c28548 100644 --- a/include/value.h +++ b/include/value.h @@ -16,5 +16,4 @@ struct Value_ { }; ANEW ANN Value new_value(struct Gwion_* gwion, const Type type, const m_str name); -ANN void free_value(Value a); #endif diff --git a/include/vm.h b/include/vm.h index 628414b27..16e24d5fe 100644 --- a/include/vm.h +++ b/include/vm.h @@ -1,18 +1,16 @@ #ifndef __VM #define __VM -#ifdef USE_DOUBLE -#undef USE_DOUBLE -#endif - typedef struct VM_Code_* VM_Code; struct VM_Code_ { - Vector instr; - m_str name; - m_uint native_func; - void* memoize; + union { + Vector instr; + m_uint native_func; + }; size_t stack_depth; ae_flag flag; + void* memoize; + m_str name; HAS_OBJ }; @@ -30,33 +28,31 @@ typedef struct Emitter_ * Emitter; typedef struct VM_ { Shreduler shreduler; struct Vector_ ugen; - struct Gwion_* gwion; struct BBQ_* bbq; + struct Gwion_* gwion; uint32_t rand[2]; volatile unsigned is_running : 1; // => shreduler } VM; typedef struct VM_Shred_* VM_Shred; struct VM_Shred_ { - Vector instr; VM_Code code; - VM_Shred parent; m_bit* reg; m_bit* mem; - m_bit* _reg; m_bit* base; + size_t pc; + struct Vector_ gc; + m_bit* _reg; + VM_Shred prev, next, parent; m_str name; VM* vm; - VM_Shred prev, next; Vector args; // passed pointer from compile struct M_Object_* me; struct Vector_ child; - struct Vector_ gc;//, gc1; - size_t pc, xid; + size_t xid; m_float wake_time; }; -ANN2(4) ANEW VM_Code new_vm_code(const Vector instr, const m_uint stack_depth, const m_bool need_this, const m_str name); -ANN void free_vm_code(const VM_Code a); +ANN2(4) ANEW VM_Code new_vm_code(const Vector instr, const m_uint stack_depth, const ae_flag, const m_str name); ANN VM_Shred shreduler_get(const Shreduler s) __attribute__((hot)); ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const m_bool erase)__attribute__((hot)); diff --git a/opcode.txt b/opcode.txt new file mode 100644 index 000000000..35ddfcc8f --- /dev/null +++ b/opcode.txt @@ -0,0 +1,152 @@ +RegPushImm +RegPushImm2 +RegPushImm3 +RegPushImm4 +RegPushMem +RegPushMem2 +RegPushMem3 +RegPushMem4 +RegPushNow +RegPushBase +RegPushBase2 +RegPushBase3 +RegPushBase4 +RegDup +MemPushImm +MemSetImm +RegPop +RegPushPtr +FuncReturn +Goto +AllocWord +AllocWord2 +AllocWord3 +AllocWord4 +int_plus +int_minus +int_mul +int_div +int_modulo +int_eq +int_neq +int_and +int_or +int_gt +int_ge +int_lt +int_le +int_sl +int_sr +int_sand +int_sor +int_xor +int_negate +IntNot +int_cmp +int_r_assign +int_r_plus +int_r_minus +int_r_mul +int_r_div +int_r_modulo +int_r_sl +int_r_sr +int_r_sand +int_r_sor +int_r_sxor +int_pre_inc +int_pre_dec +int_post_inc +int_post_dec +FloatPlus +FloatMinus +FloatTimes +FloatDivide +float_and +float_or +float_eq +float_neq +float_gt +float_ge +float_lt +float_le +float_negate +float_not +float_r_assign +float_r_plus +float_r_minus +float_r_mul +float_r_div +int_float_plus +int_float_minus +int_float_mul +int_float_div +int_float_and +int_float_or +int_float_eq +int_float_neq +int_float_gt +int_float_ge +int_float_lt +int_float_le +int_float_r_assign +int_float_r_plus +int_float_r_minus +int_float_r_mul +int_float_r_div +float_int_plus +float_int_minus +float_int_mul +float_int_div +float_int_and +float_int_or +float_int_eq +float_int_neq +float_int_gt +float_int_ge +float_int_lt +float_int_le +float_int_r_assign +float_int_r_plus +float_int_r_minus +float_int_r_mul +float_int_r_div +CastI2F +CastF2I +Time_Advance +FuncUsr +FuncMember +FuncStatic +SporkIni +SporkFunc +SporkThis +SporkExp +SporkEnd +FuncPtr +BranchEqInt +BranchNeqInt +BranchEqFloat +BranchNeqFloat +DecIntAddr +InitLoopCounter +ObjectInstantiate +RegAddRef +ObjectAssign +ObjectRelease +GWOP_EXCEPT +AllocMember4 +DotMember +DotMember2 +DotMember3 +DotMember4 +DotStatic +DotStatic2 +DotStatic3 +DotFunc +PushStaticCode +RegPushStr +GcIni +GcAdd +GcEnd +Gack +OP_MAX diff --git a/src/emit/emit.c b/src/emit/emit.c index 982f460aa..3546e55ae 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -86,7 +86,7 @@ ANN static m_bool emit_exp(const Emitter emit, Exp exp, const m_bool add_ref); ANN static m_bool emit_stmt(const Emitter emit, const Stmt stmt, const m_bool pop); ANN static m_bool emit_stmt_list(const Emitter emit, Stmt_List list); ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot* member); -ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def); +ANN /*static */m_bool emit_func_def(const Emitter emit, const Func_Def func_def); ANEW static Code* new_code(const Emitter emit, const m_str name) { Code* code = mp_alloc(Code); @@ -143,21 +143,15 @@ ANN static inline m_uint emit_local(const Emitter emit, const m_uint size, const return frame_local(emit->code->frame, size, is_obj); } -ANN static void emit_pre_ctor_inner(const Emitter emit, const Type type) { GWDEBUG_EXE - const Instr instr = emit_add_instr(emit, PreCtor); - instr->m_val = (m_uint)type->nspc->pre_ctor; - instr->m_val2 = (m_uint)emit_code_offset(emit); -} - ANN static void emit_pre_ctor(const Emitter emit, const Type type) { GWDEBUG_EXE if(type->parent) emit_pre_ctor(emit, type->parent); if(type->nspc->pre_ctor) - emit_pre_ctor_inner(emit, type); + emit_ext_ctor(emit, type->nspc->pre_ctor); if(GET_FLAG(type, template) && GET_FLAG(type, builtin)) { const Type t = template_parent(type); if(t->nspc->pre_ctor) - emit_pre_ctor_inner(emit, t); + emit_ext_ctor(emit, t->nspc->pre_ctor); } } @@ -183,7 +177,7 @@ ANN ArrayInfo* emit_array_extend_inner(const Emitter emit, const Type t, const E info->depth = (m_int)t->array_depth; info->base = base; const Instr alloc = emit_add_instr(emit, ArrayAlloc); - *(ArrayInfo**)alloc->ptr = info; + alloc->m_val = (m_uint)info; if(isa(base, t_object) > 0) { emit_pre_constructor_array(emit, base); info->is_obj = 1; @@ -197,7 +191,7 @@ ANN void emit_ext_ctor(const Emitter emit, const VM_Code code) { GWDEBUG_EXE push_f->m_val = (m_uint)code; const Instr offset = emit_add_instr(emit, RegPushImm); offset->m_val = emit_code_offset(emit); - emit_add_instr(emit, FuncMember); + emit_add_instr(emit, !GET_FLAG(code, builtin) ? FuncUsr : FuncMember); } ANN m_bool emit_array_extend(const Emitter emit, const Type t, const Exp e) { GWDEBUG_EXE @@ -209,7 +203,8 @@ ANN m_bool emit_array_extend(const Emitter emit, const Type t, const Exp e) { GW ANN2(1,2) m_bool emit_instantiate_object(const Emitter emit, const Type type, const Array_Sub array, const uint is_ref) { if(type->array_depth) { - assert(array && array->exp); + assert(array); + assert(array->exp); ArrayInfo* info = emit_array_extend_inner(emit, type, array->exp); CHECK_OB(info) info->is_ref = !!is_ref; @@ -234,14 +229,13 @@ ANN static Instr emit_kind(Emitter emit, const m_uint size, const uint addr, con return instr; } -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 regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 }; 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 dotstatic[] = { DotStatic, DotStatic2, DotStatic3, DotStatic4 }; +static const f_instr dotstatic[] = { DotStatic, DotStatic2, DotStatic3, RegPushImm }; static const f_instr dotmember[] = { DotMember, DotMember2, DotMember3, DotMember4 }; -static const f_instr allocmember[] = { PushNull, PushNull2, PushNull3, AllocMember4 }; +static const f_instr allocmember[] = { RegPushImm, RegPushImm2, RegPushImm3, AllocMember4 }; static const f_instr allocword[] = { AllocWord, AllocWord2, AllocWord3, AllocWord4 }; ANN static m_bool emit_symbol_owned(const Emitter emit, const Exp_Primary* prim) { GWDEBUG_EXE @@ -266,18 +260,25 @@ ANN static m_bool emit_symbol_builtin(const Emitter emit, const Exp_Primary* pri } if(GET_FLAG(v, union)) { const m_uint size = v->type->size; - const Instr instr = emit_kind(emit, size, prim->self->emit_var, regpushderef); - *(m_uint*)instr->ptr = (m_uint)v->d.ptr; + const Instr instr = emit_kind(emit, size, prim->self->emit_var, dotstatic); + instr->m_val = (m_uint)v->d.ptr; } else { const m_uint size = v->type->size; const Instr instr = emit_kind(emit, size, prim->self->emit_var, regpushimm); - if(size == SZ_INT) { + if(!prim->self->emit_var && size == SZ_INT) { + if(isa(v->type, t_object) > 0) { instr->execute = RegPushImm; instr->m_val = (m_uint)v->d.ptr; } else if(v->d.ptr) + instr->m_val = *(m_uint*)v->d.ptr; +} +else if(v->d.ptr) memcpy(instr->ptr, v->d.ptr, v->type->size); +// memcpy(&instr->m_val, v->d.ptr, v->type->size); else *(m_uint**)instr->ptr = v->d.ptr; +// instr->m_val = v->d.ptr; + instr->m_val2 = size; } return GW_OK; } @@ -297,7 +298,7 @@ ANN static m_bool emit_symbol(const Emitter emit, const Exp_Primary* prim) { GWD ANEW ANN VM_Code emit_code(const Emitter emit) { GWDEBUG_EXE Code* c = emit->code; const VM_Code code = new_vm_code(&c->instr, c->stack_depth, - GET_FLAG(c, member), c->name); + c->flag, c->name); free_code(c); return code; } @@ -357,7 +358,8 @@ ANN static m_bool prim_vec(const Emitter emit, const Exp_Primary * primary) { GW CHECK_BB(emit_exp(emit, vec->exp, 0)); m_int n = (m_int)((t == ae_primary_vec ? 3 : 2) - vec->dim + 1); while(--n > 0) - emit_add_instr(emit, PushNull2); +// emit_add_instr(emit, PushNull2); + emit_add_instr(emit, RegPushImm2); return GW_OK; } @@ -425,8 +427,8 @@ ANN static m_bool prim_gack(const Emitter emit, const Exp_Primary* primary) { ERR_B(exp->pos, "\t... in 'gack' expression.") } const Instr instr = emit_add_instr(emit, Gack); - *(Vector*)instr->ptr = v; instr->m_val = offset; + instr->m_val2 = (m_uint)v; return GW_OK; } @@ -453,12 +455,11 @@ ANN static m_bool emit_exp_primary(const Emitter emit, const Exp_Primary* prim) return prim_func[prim->primary_type](emit, 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); - push->m_val = (m_uint)v->owner_class; +ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v, const uint emit_var) { GWDEBUG_EXE const m_uint size = v->type->size; const Instr instr = emit_kind(emit, size, emit_var, dotstatic); - instr->m_val = v->offset; + instr->m_val = (m_uint)(v->owner_class->nspc->class_data + v->offset); + instr->m_val2 = size; return GW_OK; } @@ -494,10 +495,38 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Var_Decl va f_instr *exec = (f_instr*)allocmember; if(!GET_FLAG(v, member)) { v->offset = emit_local(emit, v->type->size, is_obj); - exec = (f_instr*)allocword; + exec = (f_instr*)(allocword); } const Instr instr = emit_kind(emit, v->type->size, emit_addr, exec); instr->m_val = v->offset; + instr->m_val2 = v->type->size; + if(is_obj && (is_array || !is_ref)) { + const Instr assign = emit_add_instr(emit, ObjectAssign); + assign->m_val = (m_uint)emit_var; + if(is_array && !emit->env->scope) + ADD_REF(type) + } + return GW_OK; +} + +ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_decl, + const uint is_ref, const uint emit_var) { GWDEBUG_EXE + const Value v = var_decl->value; + const Type type = v->type; + const Array_Sub array = var_decl->array; + const m_bool is_array = array && array->exp; + const m_bool is_obj = isa(type, t_object) > 0; + const uint emit_addr = ((is_ref && !array) || isa(type, t_object) < 0) ? + emit_var : 1; + if(is_obj && (is_array || !is_ref)) + CHECK_BB(emit_instantiate_object(emit, type, array, is_ref)) + f_instr *exec = (f_instr*)dotstatic; + const Instr instr = emit_kind(emit, v->type->size, emit_addr, exec); +v->d.ptr = _mp_alloc(v->type->size); +// here union flag is more like 'treat as builtin' +SET_FLAG(v, builtin | ae_flag_union); + instr->m_val = (m_uint)v->d.ptr; + instr->m_val2 = v->type->size; if(is_obj && (is_array || !is_ref)) { const Instr assign = emit_add_instr(emit, ObjectAssign); assign->m_val = (m_uint)emit_var; @@ -536,8 +565,10 @@ ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) { GWDE continue; if(GET_FLAG(decl->td, static)) CHECK_BB(emit_exp_decl_static(emit, list->self, r)) - else + else if(!global) CHECK_BB(emit_exp_decl_non_static(emit, list->self, r, var)) +else + CHECK_BB(emit_exp_decl_global(emit, list->self, r, var)) } while((list = list->next)); if(global) emit_pop(emit, scope); @@ -587,7 +618,8 @@ ANN static inline m_int push_tmpl_func(const Emitter emit, const Func f, const Type_List types) { const Value v = f->value_ref; const m_uint scope = emit_push(emit, v->owner_class, v->owner); - CHECK_BB(traverse_func_template(emit->env, f->def, types)) +// CHECK_BB(traverse_func_template(emit->env, f->def, types)) + CHECK_BB(traverse_func_template(emit->env, v->d.func_ref->def, types)) return (m_int)scope; } @@ -647,37 +679,71 @@ ANN static m_bool emit_exp_dur(const Emitter emit, const Exp_Dur* dur) { GWDEBUG return GW_OK; } +ANN static m_bool is_special(const Type t) { + if(isa(t, t_complex) > 0 || isa(t, t_polar) > 0 || + isa(t, t_vec3) > 0 || isa(t, t_vec4) > 0 || + isa(t, t_vararg) > 0) + return GW_OK; + return GW_ERROR; +} + + 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; + if(GET_FLAG(f, template) && f->value_ref->owner_class) { + const Instr _instr = (Instr)vector_back(&emit->code->instr); +assert(_instr->execute == DotTmpl); + size_t len = strlen(f->name); + size_t sz = len - strlen(f->value_ref->owner_class->name); + char c[sz + 1]; + strncpy(c, f->name, sz); + c[sz] = '\0'; + _instr->m_val = (m_uint)s_name(insert_symbol(c)); + _instr->m_val2 = strlen(c); + *(m_int*)_instr->ptr = f->def->tmpl->base; return GW_OK; } const Instr instr = emit_add_instr(emit, RegPushPtr); return !!(instr->m_val = (m_uint)f->code); } - static m_bool emit_template_code(const Emitter emit, const Func f) { if(GET_FLAG(f, ref)) CHECK_BB(traverse_template(emit->env, f->value_ref->owner_class->def)) - CHECK_BB(emit_func_def(emit, f->def)) + const Value v = f->value_ref; + size_t scope = emit_push(emit, v->owner_class, v->owner); + CHECK_BB(emit_func_def(emit, f->def)) // orig + emit_pop(emit, scope); +if(!v->owner_class) { +/* no need for dynamicity */ +//assert(instr->opcode != MemSetImm); +//assert(instr->opcode == RegPushBase); +} // else push_tmpl_func return push_func_code(emit, f); } ANN static Instr emit_call(const Emitter emit, const Func f) { 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); + if(isa(t, t_fptr) < 0) { + const f_instr exec = GET_FLAG(f->def, builtin) ? GET_FLAG(f, member) ? + FuncMember : FuncStatic : FuncUsr; + return emit_add_instr(emit, exec); + } + const Instr ex = emit_add_instr(emit, GWOP_EXCEPT); + ex->m_val = -SZ_INT*2; + return emit_add_instr(emit, FuncPtr); } 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 + } +else if( +(f->value_ref->owner_class && is_special(f->value_ref->owner_class) > 0) || + +!f->value_ref->owner_class || GET_FLAG(f, template) +|| (f->value_ref->owner_class && GET_FLAG(f->def, op)) +) push_func_code(emit, f); const Instr offset = emit_add_instr(emit, RegPushImm); offset->m_val = emit_code_offset(emit); @@ -688,9 +754,25 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f) { GWDEBUG_EXE ANN2(1,2) static m_bool emit_exp_spork_finish(const Emitter emit, const VM_Code code, const m_uint depth, const m_bool f) { - const Instr spork = emit_add_instr(emit, f ? SporkExp : SporkFunc); - spork->m_val = depth; - spork->m_val2 = (m_uint)code; + const Instr ini = emit_add_instr(emit, SporkIni); + ini->m_val = (m_uint)code; + if(!f) { + const m_uint member = GET_FLAG(code, member) ? SZ_INT : 0; + const Instr pop = emit_add_instr(emit, RegPop); + pop->m_val = depth + member; + if(depth) { + const Instr spork = emit_add_instr(emit, SporkFunc); + spork->m_val = depth; + } + if(member) { + const Instr m = emit_add_instr(emit, SporkThis); + m->m_val = depth; + } + } else { + const Instr spork = emit_add_instr(emit, SporkExp); + spork->m_val = depth; + } + emit_add_instr(emit, SporkEnd); return GW_OK; } @@ -734,7 +816,11 @@ ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) { GWDEBUG_ SET_FLAG(emit->code, member); const Instr op = emit_add_instr(emit, MemPushImm); op->m_val = emit->code->stack_depth; - emit_add_instr(emit, PushNull); // (was PushImm) should push func +const Instr p = + + emit_add_instr(emit, RegPushImm); + p->m_val = (m_uint)exp->m_func->code; + CHECK_BB(emit_exp_call1(emit, exp->m_func)) const VM_Code code = finalyze(emit); const m_uint size = exp->m_func->def->stack_depth - (GET_FLAG(exp->m_func, @@ -743,9 +829,10 @@ ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) { GWDEBUG_ } ANN static m_bool spork_code(const Emitter emit, const Stmt stmt) { GWDEBUG_EXE - emit_add_instr(emit, PushNull); // was PushImm + emit_add_instr(emit, RegPushImm); push_spork_code(emit, SPORK_CODE_PREFIX, stmt->pos); - if(SAFE_FLAG(emit->env->func, member)) +// if(emit->env->class_def && !SAFE_FLAG(emit->env->func, static)) + if(!SAFE_FLAG(emit->env->func, member)) stack_alloc_this(emit); CHECK_BB(scoped_stmt(emit, stmt, 0)) const VM_Code code = finalyze(emit); @@ -775,10 +862,10 @@ ANN static m_bool emit_implicit_cast(const Emitter emit, ANN static Instr emit_flow(const Emitter emit, const Type type, const f_instr f1, const f_instr f2) { GWDEBUG_EXE if(isa(type, t_float) > 0) { - emit_add_instr(emit, PushNull2); +// emit_add_instr(emit, RegPushImm2); return emit_add_instr(emit, f2); } - emit_add_instr(emit, PushNull); +// emit_add_instr(emit, RegPushImm); return emit_add_instr(emit, f1); } @@ -881,6 +968,8 @@ ANN static m_bool emit_stmt_return(const Emitter emit, const Stmt_Exp stmt) { GW if(stmt->val) { OPTIMIZE_TCO CHECK_BB(emit_exp(emit, stmt->val, 0)) + if(isa(stmt->val->type, t_object) > 0) + emit_add_instr(emit, RegAddRef); } vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto)); return GW_OK; @@ -1001,13 +1090,17 @@ ANN static m_bool emit_stmt_auto(const Emitter emit, const Stmt_Auto stmt) { GWD s2->m_val = stmt->v->offset = offset + SZ_INT; CHECK_BB(emit_stmt(emit, stmt->body, 1)) const m_uint end_pc = emit_code_size(emit); + if(stmt->is_ptr) { + const Instr release = emit_add_instr(emit, ObjectRelease); + release->m_val = offset + SZ_INT; + } const Instr end = emit_add_instr(emit, AutoLoopEnd); const Instr tgt = emit_add_instr(emit, Goto); - *(m_uint*)end->ptr = emit_code_size(emit); + end->m_val2 = emit_code_size(emit); tgt->m_val = ini_pc; s1->m_val = end->m_val = loop->m_val = offset; if(stmt->is_ptr) - end->m_val2 = loop->m_val2 = (m_uint)stmt->v->type; + loop->m_val2 = (m_uint)stmt->v->type; emit_pop_stack(emit, end_pc); return GW_OK; } @@ -1019,10 +1112,10 @@ ANN static m_bool emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt) { GWD const Instr init = emit_add_instr(emit, InitLoopCounter); init->m_val = (m_uint)counter; const m_uint index = emit_code_size(emit); - const Instr deref = emit_add_instr(emit, RegPushDeref); + const Instr deref = emit_add_instr(emit, DotStatic); + deref->m_val = (m_uint)counter; deref->m_val2 = SZ_INT; - *(m_int**)deref->ptr = counter; - emit_add_instr(emit, PushNull); +// emit_add_instr(emit, RegPushImm); const Instr op = emit_add_instr(emit, BranchEqInt); const Instr dec = emit_add_instr(emit, DecIntAddr); dec->m_val = (m_uint)counter; @@ -1250,14 +1343,6 @@ ANN static m_bool emit_stmt_list(const Emitter emit, Stmt_List l) { GWDEBUG_EXE return GW_OK; } -ANN static m_bool is_special(const Type t) { - if(isa(t, t_complex) > 0 || isa(t, t_polar) > 0 || - isa(t, t_vec3) > 0 || isa(t, t_vec4) > 0 || - isa(t, t_vararg) > 0) - return GW_OK; - return GW_ERROR; -} - ANN static m_bool emit_dot_static_import_data(const Emitter emit, const Value v, const uint emit_addr) { GWDEBUG_EXE if(v->d.ptr && GET_FLAG(v, builtin)) { // from C if(GET_FLAG(v, enum)) { @@ -1265,18 +1350,16 @@ ANN static m_bool emit_dot_static_import_data(const Emitter emit, const Value v, 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); + const Instr instr = emit_kind(emit, size, emit_addr, regpushimm); instr->m_val = (isa(v->type, t_object) > 0 ? (m_uint)&v->d.ptr : (m_uint)v->d.ptr); + *(m_uint**)instr->ptr = (m_uint*)(isa(v->type, t_object) > 0 ? + (m_uint*)&v->d.ptr : v->d.ptr); + instr->m_val2 = size; } - } else { // from code - const Instr push_i = emit_add_instr(emit, RegPushImm); - 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; + return GW_OK; } - return GW_OK; + return emit_dot_static_data(emit, v, emit_addr); } ANN static m_bool emit_complex_member(const Emitter emit, const Exp_Dot* member) { GWDEBUG_EXE @@ -1287,8 +1370,7 @@ ANN static m_bool emit_complex_member(const Emitter emit, const Exp_Dot* member) s_name(member->xid)); if(is_complex && member->self->emit_var) // skip return GW_OK; - const Instr instr = is_complex ? emit_add_instr(emit, ComplexReal) : - emit_add_instr(emit, ComplexImag); + const Instr instr = emit_add_instr(emit, is_complex ? ComplexReal : ComplexImag); instr->m_val = member->self->emit_var; return GW_OK; } @@ -1360,26 +1442,43 @@ 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_i->m_val = (m_uint)func->code; +// if(func->code) { +// const Instr func_i = emit_add_instr(emit, RegPushImm); +// func_i->m_val = (m_uint)func->code; +// } else { + // TODO: improve me + const Instr func_i = emit_add_instr(emit, PushStaticCode); + func_i->m_val = (m_uint)func; +// } return GW_OK; } ANN static m_bool emit_member_func(const Emitter emit, const Exp_Dot* member, const Func func) { GWDEBUG_EXE - if(GET_FLAG(func, member)) { - if(emit_exp(emit, member->base, 0) < 0) - ERR_B(member->self->pos, "... in member function") // LCOV_EXCL_LINE - emit_add_instr(emit, RegDup); + if(emit_exp(emit, member->base, 0) < 0) + ERR_B(member->self->pos, "... in member function") // LCOV_EXCL_LINE + const Instr ex = emit_add_instr(emit, GWOP_EXCEPT); + ex->m_val = -SZ_INT; + if(GET_FLAG(member->base->type, force)) { + const Instr func_i = emit_add_instr(emit, RegPushImm); + func_i->m_val = (m_uint)func->code; + return GW_OK; + } + if(!func->def->tmpl) { const Instr func_i = emit_add_instr(emit, DotFunc); func_i->m_val = func->vt_index; + return GW_OK; } + emit_add_instr(emit, DotTmpl); return GW_OK; } ANN static inline void emit_member(const Emitter emit, const Value v, const uint emit_addr) { + const Instr ex = emit_add_instr(emit, GWOP_EXCEPT); + ex->m_val = -SZ_INT; const m_uint size = v->type->size; const Instr instr = emit_kind(emit, size, emit_addr, dotmember); instr->m_val = v->offset; + instr->m_val2 = size; } ANN static m_bool emit_exp_dot_instance(const Emitter emit, const Exp_Dot* member) { GWDEBUG_EXE @@ -1390,19 +1489,13 @@ ANN static m_bool emit_exp_dot_instance(const Emitter emit, const Exp_Dot* membe if(GET_FLAG(value, member)) { // member if(emit_exp(emit, member->base, 0) < 0) ERR_B(member->self->pos, "... in member function") // LCOV_EXCL_LINE - if(!GET_FLAG(value->type->d.func, global)) - emit_add_instr(emit, RegDup); emit_member(emit, value, emit_addr); return GW_OK; } else return emit_dot_static_data(emit, value, emit_addr); - } else if(isa(member->self->type, t_function) > 0) { // function - const Func func = value->d.func_ref; - if(GET_FLAG(func, member)) { - return emit_member_func(emit, member, func); - } else - return emit_dot_static_func(emit, func); - } else { // variable + } else if(isa(member->self->type, t_function) > 0) + return emit_member_func(emit, member, value->d.func_ref); + else { // variable if(GET_FLAG(value, member)) { // member CHECK_BB(emit_exp(emit, member->base, 0)) emit_member(emit, value, emit_addr); @@ -1455,10 +1548,8 @@ 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) { - if(size == SZ_INT) - emit_add_instr(emit, PushNull); - else - emit_kind(emit, size, 0, regpushimm); + const Instr instr = emit_kind(emit, size, 0, regpushimm); + instr->m_val2 = size; } vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto)); } @@ -1497,7 +1588,7 @@ ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def func_def return GW_OK; } -ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def) { GWDEBUG_EXE +ANN /*static */m_bool emit_func_def(const Emitter emit, const Func_Def func_def) { GWDEBUG_EXE const Func func = get_func(emit->env, func_def); if(func->code)return GW_OK; if(tmpl_list_base(func_def->tmpl)) { // don't check template definition @@ -1520,6 +1611,7 @@ 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(!emit->env->class_def && !GET_FLAG(func_def, template)) if(!emit->env->class_def) emit_func_def_global(emit, func->value_ref); MEMOIZE_INI diff --git a/src/emit/emitter.c b/src/emit/emitter.c index 4c46f6430..f84b9ab53 100644 --- a/src/emit/emitter.c +++ b/src/emit/emitter.c @@ -23,7 +23,12 @@ ANN void free_emitter(Emitter a) { __attribute__((returns_nonnull)) ANN2(1) Instr emit_add_instr(const Emitter emit, const f_instr f) { const Instr instr = mp_alloc(Instr); - instr->execute = f; + if((m_uint)f < 255) + instr->opcode = (m_uint)f; + else { + instr->opcode = (m_uint)OP_MAX; + instr->execute = f; + } vector_add(&emit->code->instr, (vtype)instr); return instr; } diff --git a/src/lib/array.c b/src/lib/array.c index 550fcbf0f..56ffc1a45 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -28,12 +28,26 @@ ANN m_uint m_vector_size(const M_Vector v) { M_Vector new_m_vector(const m_uint size) { const M_Vector array = mp_alloc(M_Vector); - array->ptr = (m_bit*)xcalloc(ARRAY_OFFSET + 2, size); +const size_t sz = (ARRAY_OFFSET*SZ_INT) + (2*size); + array->ptr = (m_bit*)xcalloc(1, sz); ARRAY_CAP(array) = 2; ARRAY_SIZE(array) = size; return array; } +M_Vector new_m_vector2(const m_uint size, const m_uint len) { + const M_Vector array = mp_alloc(M_Vector); + const size_t sz = (ARRAY_OFFSET*SZ_INT) + (len*size); + array->ptr = (m_bit*)xcalloc(1, sz); + m_uint cap = 1; + while(cap < len) + cap *= 2; + ARRAY_CAP(array) = cap; + ARRAY_SIZE(array) = size; + ARRAY_LEN(array) = len; + return array; +} + void free_m_vector(M_Vector a) { xfree(a->ptr); mp_free(M_Vector, a); @@ -52,14 +66,9 @@ static DTOR(array_dtor) { ANN M_Object new_array(const Type t, const m_uint length) { const M_Object a = new_object(NULL, t); - m_uint cap = 1; - while(cap < length) - cap *= 2; const m_uint depth = t->array_depth; const m_uint size = depth > 1 ? SZ_INT : array_base(t)->size; - const M_Vector array = ARRAY(a) = new_m_vector(size); - ARRAY_CAP(array) = cap; - ARRAY_LEN(array) = length; + ARRAY(a) = new_m_vector2(size,length); ADD_REF(t); return a; } @@ -305,7 +314,7 @@ ANN static M_Object* init_array(const VM_Shred shred, const ArrayInfo* info, m_u } INSTR(ArrayAlloc) { GWDEBUG_EXE - const ArrayInfo* info = *(ArrayInfo**)instr->ptr; + const ArrayInfo* info = (ArrayInfo*)instr->m_val; m_uint num_obj = 1; m_int idx = 0; const m_bool is_obj = info->is_obj && !info->is_ref; diff --git a/src/lib/float.c b/src/lib/float.c index 8f2023d15..74a0b27af 100644 --- a/src/lib/float.c +++ b/src/lib/float.c @@ -11,147 +11,12 @@ #include "emit.h" #include "operator.h" -#define describe(name, op) \ -INSTR(Float##name) { GWDEBUG_EXE \ - POP_REG(shred, SZ_FLOAT); \ - *(m_float*)REG(-SZ_FLOAT) op##= *(m_float*)REG(0); \ -} - -static describe(Plus, +) -static describe(Minus, -) -describe(Times, *) -static describe(Divide, /) - -#define describe_logical(name, op) \ -static INSTR(float_##name) { GWDEBUG_EXE \ - POP_REG(shred, SZ_FLOAT * 2 - SZ_INT); \ - *(m_int*)REG(-SZ_INT) = (*(m_float*)REG(-SZ_INT) op *(m_float*)REG(SZ_FLOAT -SZ_INT)); \ -} -describe_logical(and, &&) -describe_logical(or, ||) -describe_logical(eq, ==) -describe_logical(neq, !=) -describe_logical(gt, >) -describe_logical(ge, >=) -describe_logical(lt, <) -describe_logical(le, <=) - -INSTR(float_negate) { GWDEBUG_EXE - *(m_float*)REG(-SZ_FLOAT) = -*(m_float*)REG(-SZ_FLOAT); -} - - OP_CHECK(opck_unary_meta2) { const Exp_Unary* unary = (Exp_Unary*)data; unary->self->meta = ae_meta_value; return t_int; } -INSTR(float_not) { GWDEBUG_EXE - POP_REG(shred, SZ_FLOAT - SZ_INT) - *(m_int*)REG(-SZ_INT) = !*(m_float*)REG(-SZ_INT); -} - -static INSTR(float_r_assign) { GWDEBUG_EXE - POP_REG(shred, SZ_INT); - **(m_float**)REG(0) = *(m_float*)REG(-SZ_FLOAT); -} - -#define describe_r(name, op) \ -static INSTR(float_r_##name) { GWDEBUG_EXE \ - POP_REG(shred, SZ_INT); \ - *(m_float*)REG(-SZ_FLOAT) = (**(m_float**)REG(0) op##= (*(m_float*)REG(-SZ_FLOAT))); \ -} - -describe_r(plus, +) -describe_r(minus, -) -describe_r(mul, *) -describe_r(div, /) - -#define describe_if(name, op) \ -static INSTR(int_float_##name) { GWDEBUG_EXE \ - POP_REG(shred, SZ_INT); \ - *(m_float*)REG(-SZ_FLOAT) = (m_float)*(m_int*)REG(-SZ_FLOAT) op \ - *(m_float*)REG(SZ_INT-SZ_FLOAT); \ -} -describe_if(plus, +) -describe_if(minus, -) -describe_if(mul, *) -describe_if(div, /) - -#define describe_logical_if(name, op) \ -static INSTR(int_float_##name) { GWDEBUG_EXE \ - POP_REG(shred, SZ_FLOAT); \ - *(m_int*)REG(-SZ_INT) = (*(m_int*)REG(-SZ_INT) op (m_int)*(m_float*)REG(0)); \ -} -describe_logical_if(and, &&) -describe_logical_if(or, ||) -describe_logical_if(eq, ==) -describe_logical_if(neq, !=) -describe_logical_if(gt, >) -describe_logical_if(ge, >=) -describe_logical_if(lt, <) -describe_logical_if(le, <=) - -#define describe_r_if(name, op) \ -static INSTR(int_float_r_##name) { GWDEBUG_EXE \ - POP_REG(shred, SZ_INT * 2 - SZ_FLOAT); \ - *(m_float*)REG(-SZ_FLOAT) = (**(m_float**)REG(SZ_INT - SZ_FLOAT) op##= \ - (m_float)*(m_int*)REG(-SZ_FLOAT)); \ -} -describe_r_if(assign, ) -describe_r_if(plus, +) -describe_r_if(minus, -) -describe_r_if(mul, *) -describe_r_if(div, /) - -#define describe_fi(name, op) \ -static INSTR(float_int_##name) { GWDEBUG_EXE \ - POP_REG(shred, SZ_INT); \ - *(m_float*)REG(-SZ_FLOAT) op##= (m_float)*(m_int*)REG(0); \ -} -describe_fi(plus, +) -describe_fi(minus, -) -describe_fi(mul, *) -describe_fi(div, /) - -#define describe_logical_fi(name, op) \ -static INSTR(float_int_##name) { GWDEBUG_EXE \ - POP_REG(shred, SZ_FLOAT); \ - *(m_int*)REG(-SZ_INT) = ((m_int)*(m_float*)REG(-SZ_INT) op *(m_int*)REG(SZ_FLOAT-SZ_INT)); \ -} -describe_logical_fi(and, &&) -describe_logical_fi(or, ||) -describe_logical_fi(eq, ==) -describe_logical_fi(neq, !=) -describe_logical_fi(gt, >) -describe_logical_fi(ge, >=) -describe_logical_fi(lt, <) -describe_logical_fi(le, <=) - -static INSTR(float_int_r_assign) { GWDEBUG_EXE - POP_REG(shred, SZ_FLOAT); - *(m_int*)REG(-SZ_INT) = **(m_int**)REG(SZ_FLOAT-SZ_INT) = - (m_int)*(m_float*)REG(-SZ_INT); -} - -#define describe_r_fi(name, op) \ -static INSTR(float_int_r_##name) { GWDEBUG_EXE \ - POP_REG(shred, SZ_FLOAT); \ - *(m_int*)REG(-SZ_INT) = (**(m_int**)REG(SZ_FLOAT -SZ_INT) op##= (m_int)(*(m_float*)REG(-SZ_INT))); \ -} -describe_r_fi(plus, +) -describe_r_fi(minus, -) -describe_r_fi(mul, *) -describe_r_fi(div, /) - -static INSTR(Time_Advance) { GWDEBUG_EXE - POP_REG(shred, SZ_FLOAT); - const m_float f = *(m_float*)REG(-SZ_FLOAT); - *(m_float*)REG(-SZ_FLOAT) = (shred->wake_time += f); - shredule(shred->vm->shreduler, shred, f); -} - static GWION_IMPORT(values) { VM* vm = gwi_vm(gwi); ALLOC_PTR(d_zero, m_float, 0.0); @@ -213,17 +78,6 @@ static OP_EMIT(opem_f2i) { return GW_OK; } -INSTR(CastI2F) { GWDEBUG_EXE - POP_REG(shred, SZ_INT - SZ_FLOAT); - *(m_float*)REG(-SZ_FLOAT) = (m_float)*(m_int*)REG(-SZ_FLOAT); -} - - -INSTR(CastF2I) { GWDEBUG_EXE - POP_REG(shred, SZ_FLOAT - SZ_INT); - *(m_int*)REG(-SZ_INT) = (m_int)*(m_float*)REG(-SZ_INT); -} - #define CHECK_OP(op, check, func) _CHECK_OP(op, check, float_##func) #define CHECK_IF(op, check, func) _CHECK_OP(op, check, int_float_##func) #define CHECK_FI(op, check, func) _CHECK_OP(op, check, float_int_##func) diff --git a/src/lib/func.c b/src/lib/func.c index 61975a738..6a8bdbd03 100644 --- a/src/lib/func.c +++ b/src/lib/func.c @@ -17,10 +17,9 @@ ANN Type check_exp_call1(const Env env, const Exp_Call *exp); ANN m_bool emit_exp_spork(const Emitter, const Exp_Unary*); -static INSTR(assign_func) { GWDEBUG_EXE - const Func f = **(Func**)REG(-SZ_INT) = *(Func*)REG(-(SZ_INT*2+instr->m_val2)); - POP_REG(shred, instr->m_val + instr->m_val2) - *(Func*)REG(-SZ_INT) = f; // do we need this ? +static INSTR(FuncAssign) { GWDEBUG_EXE + POP_REG(shred, SZ_INT) + **(Func**)REG(0) = *(Func*)REG(-SZ_INT); } static OP_CHECK(opck_func_call) { @@ -106,19 +105,6 @@ static OP_CHECK(opck_spork) { ERR_O(unary->self->pos, "only function calls can be sporked...") return NULL; } -static OP_EMIT(opem_fptr_at) { - const Exp_Binary* bin = (Exp_Binary*)data; - const Instr instr = emit_add_instr(emit, assign_func); - if(GET_FLAG(bin->rhs->type->d.func, global)) - instr->m_val = SZ_INT; - else if(GET_FLAG(bin->rhs->type->d.func, member)) { - if(bin->rhs->exp_type != ae_exp_decl) - instr->m_val2 = SZ_INT; - instr->m_val = SZ_INT*2; - } else - instr->m_val = SZ_INT; - return GW_OK; -} static OP_EMIT(opem_spork) { const Exp_Unary* unary = (Exp_Unary*)data; @@ -131,8 +117,7 @@ GWION_IMPORT(func) { CHECK_BB(gwi_oper_end(gwi, op_chuck, NULL)) CHECK_BB(gwi_oper_ini(gwi, "@function", "@func_ptr", NULL)) CHECK_BB(gwi_oper_add(gwi, opck_fptr_at)) - CHECK_BB(gwi_oper_emi(gwi, opem_fptr_at)) - CHECK_BB(gwi_oper_end(gwi, op_ref, NULL)) + CHECK_BB(gwi_oper_end(gwi, op_ref, FuncAssign)) CHECK_BB(gwi_oper_add(gwi, opck_fptr_cast)) CHECK_BB(gwi_oper_emi(gwi, opem_basic_cast)) CHECK_BB(gwi_oper_end(gwi, op_cast, NULL)) diff --git a/src/lib/gack.c b/src/lib/gack.c index 0e53bdc93..5064b5948 100644 --- a/src/lib/gack.c +++ b/src/lib/gack.c @@ -91,11 +91,11 @@ static void print_prim(const Type type, const m_bit* stack) { else print_float(*(m_float*)stack); } - +/* INSTR(Gack) { GWDEBUG_EXE - const Vector v = *(Vector*)instr->ptr; - const m_uint size = vector_size(v); m_uint offset = instr->m_val; + const Vector v = (Vector)instr->m_val2; + const m_uint size = vector_size(v); for(m_uint i = size + 1; --i;) { const Type type = (Type)vector_at(v, size - i); if(size == 1) @@ -114,3 +114,26 @@ INSTR(Gack) { GWDEBUG_EXE } gw_out("\n"); } +*/ +void gack(const m_bit* reg, const Instr instr) { + m_uint offset = instr->m_val; + const Vector v = (Vector)instr->m_val2; + const m_uint size = vector_size(v); + for(m_uint i = size + 1; --i;) { + const Type type = (Type)vector_at(v, size - i); + if(size == 1) + print_type(type); + if(isa(type, t_object) > 0) + print_object(type, *(M_Object*)(reg-offset)); + else if(isa(type, t_function) > 0) + print_func(type, (reg-offset)); + else if(isa(type, t_class) > 0) + print_type(type->d.base_type); + else if(isa(type, t_void) > 0) + print_string1("void"); + else + print_prim(type, (reg-offset)); + offset -= type->size; + } + gw_out("\n"); +} diff --git a/src/lib/import.c b/src/lib/import.c index 392a46759..233e53ece 100644 --- a/src/lib/import.c +++ b/src/lib/import.c @@ -166,9 +166,8 @@ ANN static ID_List str2list(const m_str path, m_uint* array_depth) { ANN static m_bool mk_xtor(const Type type, const m_uint d, const ae_flag e) { VM_Code* code = e == ae_flag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor; const m_str name = type->name; - *code = new_vm_code(NULL, SZ_INT, 1, name); + *code = new_vm_code(NULL, SZ_INT, e | ae_flag_member | ae_flag_builtin, name); (*code)->native_func = (m_uint)d; - (*code)->flag = (e | ae_flag_member | ae_flag_builtin); type->flag |= e; return GW_OK; } @@ -353,7 +352,7 @@ static Array_Sub make_dll_arg_list_array(Array_Sub array_sub, return array_sub; } -ANN static Type_List str2tl(const Env env, const m_str s, m_uint *depth) { +ANN /*static */ Type_List str2tl(const Env env, const m_str s, m_uint *depth) { Type_Decl* td = str2decl(env, s, depth); td->array = make_dll_arg_list_array(NULL, depth, 0); return new_type_list(td, NULL); diff --git a/src/lib/instr.c b/src/lib/instr.c index 9dfdfc3b9..6065c331a 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -13,30 +13,6 @@ #include "array.h" #include "nspc.h" -ANN static inline m_bool overflow_(const VM_Shred c) { - return c->mem > ((c->_reg + SIZEOF_REG) + (SIZEOF_MEM) - (MEM_STEP)); -} - -static inline void dl_return_push(const m_bit* retval, const VM_Shred shred, - const m_uint size __attribute__((unused))) { - *(m_uint*)REG(0) = *(m_uint*)retval; - PUSH_REG(shred, SZ_INT); -} - -static inline void dl_return_push2(const m_bit* retval, const VM_Shred shred, - const m_uint size __attribute__((unused))) { - *(m_float*)REG(0) = *(m_float*)retval; - PUSH_REG(shred, SZ_FLOAT); -} - -static inline void dl_return_push3(const m_bit* retval, const VM_Shred shred, const m_uint size) { - memcpy(REG(0), retval, size); - PUSH_REG(shred, size); -} - -static void (*dl_return[])(const m_bit*, const VM_Shred, const m_uint) = - { dl_return_push, dl_return_push2, dl_return_push3 }; - INSTR(EOC) { GWDEBUG_EXE vm_shred_exit(shred); } @@ -55,128 +31,20 @@ INSTR(EOC2) { GWDEBUG_EXE shreduler_remove(shred->vm->shreduler, shred, 0); } -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(Imm2, m_float, SZ_FLOAT) -INSTR(RegPushImm3) { GWDEBUG_EXE - memcpy(REG(0), instr->ptr, instr->m_val2); - PUSH_REG(shred, instr->m_val2); -} - -INSTR(MemPushImm) { GWDEBUG_EXE - *(m_uint*)MEM(0) = instr->m_val; - PUSH_MEM(shred, SZ_INT); -} - -INSTR(MemSetImm) { GWDEBUG_EXE - *(m_uint*)MEM(instr->m_val) = instr->m_val2; -} - -#define describe_regpushxxx(name, type, size) \ -INSTR(RegPush##name) { GWDEBUG_EXE \ - *(type*)REG(0) = *(type*)(shred->mem + instr->m_val); \ - PUSH_REG(shred, size); \ -} - -describe_regpushxxx(Mem, m_uint, SZ_INT) -describe_regpushxxx(Mem2, m_float, SZ_FLOAT) -INSTR(RegPushMem3) { GWDEBUG_EXE - memcpy(REG(0), (shred->mem + instr->m_val), instr->m_val2); - PUSH_REG(shred, instr->m_val2); -} -INSTR(RegPushMem4) { GWDEBUG_EXE - *(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); \ -} - -describe_regpushbase(Base, m_uint, 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(RegPushPtr) { GWDEBUG_EXE - *(m_uint*)REG(-SZ_INT) = instr->m_val; -} - -INSTR(RegDup) { GWDEBUG_EXE - *(M_Object*)REG(0) = *(M_Object*)REG(-SZ_INT); - PUSH_REG(shred, SZ_INT); -} - -INSTR(RegAddRef) { GWDEBUG_EXE - const M_Object obj = instr->m_val ? **(M_Object**)REG(-SZ_INT) : - *(M_Object*)REG(-SZ_INT); - if(obj) - ++obj->ref; -} - INSTR(RegPushMe) { GWDEBUG_EXE *(M_Object*)REG(0) = shred->me; PUSH_REG(shred, SZ_INT); } -INSTR(RegPushNow) { GWDEBUG_EXE - *(m_float*)REG(0) = (m_float)shred->vm->bbq->pos; - PUSH_REG(shred, SZ_FLOAT); -} - INSTR(RegPushMaybe) { GWDEBUG_EXE *(m_uint*)REG(0) = gw_rand(shred->vm->rand) > (UINT32_MAX / 2); PUSH_REG(shred, SZ_INT); } -INSTR(AllocWord) { GWDEBUG_EXE - *(m_uint*)MEM(instr->m_val) = 0; - *(m_uint*)REG(0) = 0; // MEM(instr->m_val); - PUSH_REG(shred, SZ_INT); -} - -INSTR(AllocWord2) { GWDEBUG_EXE - *(m_float*)MEM(instr->m_val) = 0.0; - *(m_float*)REG(0) = 0.0; // MEM(instr->m_val); - PUSH_REG(shred, SZ_FLOAT); -} - -INSTR(AllocWord3) { GWDEBUG_EXE - memset(MEM(instr->m_val), 0, instr->m_val2); - memset(REG(0), 0, instr->m_val2); // MEM(instr->m_val) - PUSH_REG(shred, instr->m_val2); -} - -INSTR(AllocWord4) { GWDEBUG_EXE - memset(MEM(instr->m_val), 0, instr->m_val2); - *(m_bit**)REG(0) = (m_bit*)MEM(instr->m_val); - PUSH_REG(shred, SZ_INT); -} - /* branching */ INSTR(SwitchIni) { const Vector v = (Vector)instr->m_val; - const m_uint size = vector_size(v);; + const m_uint size = vector_size(v); const Map m = (Map)instr->m_val2; POP_REG(shred, SZ_INT * (size - 1)); for(m_uint i = 0; i < size; ++i) @@ -193,337 +61,6 @@ INSTR(BranchSwitch) { GWDEBUG_EXE shred->pc = instr->m_val; } -#define branch(name, type, sz, op) \ -INSTR(Branch##name) { GWDEBUG_EXE \ - POP_REG(shred, sz * 2); \ - if(*(type*)REG(0) op *(type*)REG(sz)) \ - shred->pc = instr->m_val; \ -} -branch(EqInt, m_uint, SZ_INT, ==) -branch(NeqInt, m_uint, SZ_INT, !=) -branch(EqFloat, m_float, SZ_FLOAT, ==) -branch(NeqFloat, m_float, SZ_FLOAT, !=) - -INSTR(InitLoopCounter) { GWDEBUG_EXE - POP_REG(shred, SZ_INT); - (*(m_uint*)instr->m_val) = labs(*(m_int*)REG(0)); -} - -INSTR(RegPushDeref) { GWDEBUG_EXE - *(m_uint*)REG(0) = **(m_uint**)instr->ptr; - PUSH_REG(shred, SZ_INT); -} - -INSTR(RegPushDeref2) { GWDEBUG_EXE - *(m_float*)REG(0) = *(m_float*)instr->ptr; - PUSH_REG(shred, SZ_FLOAT); -} - -INSTR(RegPushDeref3) { GWDEBUG_EXE - memcpy(REG(0), *(void**)instr->ptr, instr->m_val2); - PUSH_REG(shred, instr->m_val2); -} - -INSTR(DecIntAddr) { GWDEBUG_EXE - --(*((m_uint*)(instr->m_val))); -} - -INSTR(Goto) { GWDEBUG_EXE - shred->pc = instr->m_val; -} - -ANN static VM_Shred init_spork_shred(const VM_Shred shred, const VM_Code code) { - const VM_Shred sh = new_vm_shred(code); - ADD_REF(code) - sh->parent = shred; - if(!shred->child.ptr) - vector_init(&shred->child); - vector_add(&shred->child, (vtype)sh); - sh->base = shred->base; - vm_add_shred(shred->vm, sh); - return sh; -} -#include "value.h" -static inline void push_me(VM_Shred shred, VM_Shred sh) { - *(M_Object*)REG(0) = sh->me; - PUSH_REG(shred, SZ_INT); -} - -INSTR(SporkFunc) { GWDEBUG_EXE - POP_REG(shred, SZ_INT); - const VM_Code code = (VM_Code)instr->m_val2; - const VM_Shred sh = init_spork_shred(shred, code); - const m_uint need = GET_FLAG(code, member) ? SZ_INT : 0; - shred->reg -= instr->m_val + need; - if(instr->m_val) { - for(m_uint i = 0; i < instr->m_val; i+= SZ_INT) - *(m_uint*)(sh->reg + i) = *(m_uint*)REG(i); - sh->reg += instr->m_val; - } - if(need) { - *(M_Object*)sh->reg = *(M_Object*)REG(instr->m_val); - PUSH_REG(sh, SZ_INT); - } - push_me(shred, sh); -} - -INSTR(SporkExp) { GWDEBUG_EXE - POP_REG(shred, SZ_INT); - const VM_Code code = (VM_Code)instr->m_val2; - const VM_Shred sh = init_spork_shred(shred, code); - for(m_uint i = 0; i < instr->m_val; i+= SZ_INT) - *(m_uint*)(sh->mem + i) = *(m_uint*)MEM(i); - push_me(shred, sh); -} - -ANN static void shred_func_prepare(const VM_Shred shred) { - POP_REG(shred, SZ_INT * 2); - // 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 = *(VM_Code*)REG(0); - shred->instr = shred->code->instr; -} - -ANN static inline void shred_func_need_this(const VM_Shred shred) { - *(m_uint*)MEM(0) = *(m_uint*)REG(shred->code->stack_depth - SZ_INT); - PUSH_MEM(shred, SZ_INT); -} - -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)) - FuncMember(shred, instr); - else - FuncStatic(shred, instr); -} - -INSTR(FuncUsr) { GWDEBUG_EXE - shred_func_prepare(shred); - const VM_Code code = shred->code; - m_uint stack_depth = code->stack_depth; - if(stack_depth) { - POP_REG(shred, stack_depth); - 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); - } - if(overflow_(shred)) - Except(shred, "StackOverflow"); -} - -INSTR(DotFunc) { GWDEBUG_EXE - const M_Object obj = *(M_Object*)REG(-SZ_INT); - if(!obj) - Except(shred, "NullPtrException"); - *(VM_Code*)REG(-SZ_INT) = ((Func)vector_at(&obj->type_ref->nspc->vtable, instr->m_val))->code; -} - -INSTR(FuncStatic) { GWDEBUG_EXE - POP_REG(shred, SZ_INT * 2); - const VM_Code code = *(VM_Code*)REG(0); - const m_uint local_depth = *(m_uint*)REG(SZ_INT); - PUSH_MEM(shred, local_depth); - const m_uint stack_depth = code->stack_depth; - if(stack_depth) { - POP_REG(shred, stack_depth); - for(m_uint i = 0; i < stack_depth; i+= SZ_INT) - *(m_uint*)MEM(i) = *(m_uint*)REG(i); - } - if(overflow_(shred)) - Except(shred, "StackOverflow"); - const m_bit retval[instr->m_val]; - const f_sfun f = (f_sfun)code->native_func; - f(retval, shred); - if(instr->m_val) - dl_return[instr->m_val2](retval, shred, instr->m_val); - POP_MEM(shred, local_depth); -} - -ANN static inline void copy_member_args(const VM_Shred shred, const VM_Code func) { - const m_uint stack_depth = func->stack_depth; - const m_uint depth = stack_depth -SZ_INT; - POP_REG(shred, stack_depth); - *(m_uint*)MEM(0) = *(m_uint*)REG(depth); - for(m_uint i = 0; i < stack_depth; i+= SZ_INT) - *(m_uint*)MEM(i+SZ_INT) = *(m_uint*)REG(i); -} - -INSTR(FuncMember) { GWDEBUG_EXE - POP_REG(shred, SZ_INT * 2); - const VM_Code code = *(VM_Code*)REG(0); - const m_uint local_depth = *(m_uint*)REG(SZ_INT); - PUSH_MEM(shred, local_depth); - copy_member_args(shred, code); - if(overflow_(shred)) - Except(shred, "StackOverflow"); - if(GET_FLAG(code, ctor)) { - const f_xtor f = (f_xtor)code->native_func; - f(*(M_Object*)MEM(0), shred); - } else { - assert(instr); - const m_bit retval[instr->m_val]; - const f_mfun f = (f_mfun)code->native_func; - f((*(M_Object*)MEM(0)), retval, shred); - if(instr->m_val) - dl_return[instr->m_val2](retval, shred, instr->m_val); - } - POP_MEM(shred, local_depth); -} - -INSTR(FuncReturn) { GWDEBUG_EXE - 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 - const VM_Code pre_ctor = (VM_Code)instr->m_val; - *(m_uint*)REG(0) = *(m_uint*)REG(-SZ_INT); - *(VM_Code*)REG(SZ_INT) = pre_ctor; - *(m_uint*)REG(SZ_INT*2) = instr->m_val2; - PUSH_REG(shred, SZ_INT*3); - if(GET_FLAG(pre_ctor, builtin)) - FuncMember(shred, NULL); - else - FuncUsr(shred, NULL); -} - -INSTR(ObjectInstantiate) { GWDEBUG_EXE - const M_Object o = new_object(shred, (Type)instr->m_val); - *(M_Object*)REG(0) = o; - PUSH_REG(shred, SZ_INT); -} - -INSTR(PushNull) { GWDEBUG_EXE - *(m_uint*)REG(0) = 0; - PUSH_REG(shred, SZ_INT); -} - -INSTR(PushNull2) { GWDEBUG_EXE - *(m_float*)REG(0) = 0.0; - PUSH_REG(shred, SZ_FLOAT); -} - -INSTR(PushNull3) { GWDEBUG_EXE - memset(REG(0), 0, instr->m_val2); // 0 <=> *data - PUSH_REG(shred, instr->m_val2); -} - -INSTR(AllocMember4) { GWDEBUG_EXE - const M_Object obj = *(M_Object*)MEM(0); - *(const m_bit**)REG(0) = obj->data + instr->m_val; - PUSH_REG(shred, SZ_INT); -} - -INSTR(DotStatic) { GWDEBUG_EXE - const Type t = *(Type*)REG(-SZ_INT); - m_uint *const data = (m_uint*)(t->nspc->class_data + instr->m_val); - *(m_uint*)REG(-SZ_INT) = data ? *data : 0; -} - -INSTR(DotStatic2) { GWDEBUG_EXE - const Type t = *(Type*)REG(-SZ_INT); - m_float *const data = (m_float*)(t->nspc->class_data + instr->m_val); - *(m_float*)REG(-SZ_INT) = *data; - PUSH_REG(shred, SZ_FLOAT - SZ_INT); -} - -INSTR(DotStatic3) { GWDEBUG_EXE - const Type t = *(Type*)REG(-SZ_INT); - const m_bit* data = t->nspc->class_data + instr->m_val; - memcpy(REG(-SZ_INT), data, instr->m_val2); - PUSH_REG(shred, instr->m_val2 - SZ_INT); -} - -INSTR(DotStatic4) { GWDEBUG_EXE - const Type t = *(Type*)REG(-SZ_INT); - const m_bit* data = t->nspc->class_data + instr->m_val; - *(m_bit**)REG(-SZ_INT) = (m_bit*)data; -} - -INSTR(DotImport) { GWDEBUG_EXE - *(m_uint*)REG(0) = *(m_uint*)instr->m_val; - PUSH_REG(shred, SZ_INT); -} - -INSTR(DotImport2) { GWDEBUG_EXE - *(m_float*)REG(0) = *(m_float*)instr->m_val; - PUSH_REG(shred, SZ_FLOAT); -} - -INSTR(DotImport3) { GWDEBUG_EXE - memcpy(REG(0), (m_bit*)instr->m_val, instr->m_val2); - PUSH_REG(shred, instr->m_val2); -} - -INSTR(DotImport4) { GWDEBUG_EXE - *(m_bit**)REG(0) = (m_bit*)(instr->m_val); - PUSH_REG(shred, SZ_INT); -} - -INSTR(DotMember) { GWDEBUG_EXE - const M_Object obj = *(M_Object*)REG(-SZ_INT); - if(!obj) - Except(shred, "NullPtrException"); - *(m_uint*)REG(-SZ_INT) = *(m_uint*)(obj->data + instr->m_val); -} - -INSTR(DotMember2) { GWDEBUG_EXE - const M_Object obj = *(M_Object*)REG(-SZ_INT); - if(!obj) - Except(shred, "NullPtrException"); - *(m_float*)REG(-SZ_INT) = *(m_float*)(obj->data + instr->m_val); - PUSH_REG(shred, SZ_FLOAT - SZ_INT); -} - -INSTR(DotMember3) { GWDEBUG_EXE - const M_Object obj = *(M_Object*)REG(-SZ_INT); - if(!obj) - Except(shred, "NullPtrException"); - memcpy(REG(-SZ_INT), (obj->data + instr->m_val), instr->m_val2); - PUSH_REG(shred, instr->m_val2 - SZ_INT); -} - -INSTR(DotMember4) { GWDEBUG_EXE - const M_Object obj = *(M_Object*)REG(-SZ_INT); - if(!obj) - Except(shred, "NullPtrException"); - *(m_bit**)REG(-SZ_INT) = (m_bit*)(obj->data + instr->m_val); -} - -INSTR(ObjectRelease) { GWDEBUG_EXE - release(*(M_Object*)MEM(instr->m_val), shred); -} - -INSTR(GcIni) { GWDEBUG_EXE - vector_add(&shred->gc, (vtype)NULL); -} - -INSTR(GcAdd) { GWDEBUG_EXE - vector_add(&shred->gc, *(vtype*)REG(-SZ_INT)); -} - -INSTR(GcEnd) { GWDEBUG_EXE - M_Object o; - while((o = (M_Object)vector_pop(&shred->gc))) - _release(o, shred); -} - INSTR(AutoLoopStart) { GWDEBUG_EXE const M_Object o = *(M_Object*)REG(-SZ_INT); if(!o) @@ -542,15 +79,11 @@ INSTR(AutoLoopStart) { GWDEBUG_EXE } INSTR(AutoLoopEnd) { GWDEBUG_EXE - if(instr->m_val2) { - const M_Object ptr = *(M_Object*)MEM(instr->m_val + SZ_INT); - _release(ptr, shred); - } m_uint* idx = (m_uint*)MEM(instr->m_val); ++*idx; const M_Object o = *(M_Object*)REG(-SZ_INT); if(*idx >= m_vector_size(ARRAY(o))) { - shred->pc = *(m_uint*)instr->ptr; + shred->pc = instr->m_val2; POP_REG(shred, SZ_INT); } } @@ -585,6 +118,18 @@ INSTR(ConstPropGet) { GWDEBUG_EXE } #endif +Type_List tmpl_tl(const Env env, const m_str name) { +// const Value v = f->value_ref; +m_str start = strchr(name, '<'); +m_str end = strchr(name, '@'); +char c[strlen(name)]; +strcpy(c, start + 1); +c[strlen(start) - strlen(end) - 2] = '\0'; +m_uint depth; + return str2tl(env, c, &depth); +} + + INSTR(PopArrayClass) { GWDEBUG_EXE POP_REG(shred, SZ_INT); const M_Object obj = *(M_Object*)REG(-SZ_INT); @@ -593,3 +138,83 @@ INSTR(PopArrayClass) { GWDEBUG_EXE free_object(tmp); ADD_REF(obj->type_ref) // add ref to typedef array type } +#include "gwion.h" +#include "emit.h" +#include "value.h" +#include "template.h" +INSTR(DotTmpl) { + const m_str name = (m_str)instr->m_val; + const M_Object o = *(M_Object*)REG(-SZ_INT); + Type t = o->type_ref; + do { + char str[instr->m_val2 + strlen(t->name) + 1]; + strcpy(str, name); + strcpy(str + instr->m_val2, t->name); + const Value value = nspc_lookup_value1(t->nspc, insert_symbol(str)); + const Func f = nspc_lookup_func1(t->nspc, insert_symbol(str)); + if(f) { + if(!f->code) { + const Emitter emit = shred->vm->gwion->emit; +emit->env->name = "runtime"; + const Value v = f->value_ref; +m_str start = strchr(name, '<'); +m_str end = strchr(name, '@'); +char c[instr->m_val2]; +strcpy(c, start + 1); +c[strlen(start) - strlen(end) - 2] = '\0'; +m_uint depth; +const Type_List tl = str2tl(emit->env, c, &depth); +assert(v); +assert(v->d.func_ref->def = f->def); +env_push_type(emit->env, v->owner_class); +if(template_push_types(emit->env, f->def->tmpl->list, tl) > 0) +// if(traverse_func_def(emit->env, f->value_ref->d.func_ref->def) > 0) + if(traverse_func_def(emit->env, f->def) > 0) +emit_func_def(emit, f->def); +assert(f->code); +assert(f->code = f->def->func->code); +nspc_pop_type(emit->env->curr); +env_pop(emit->env, 0); +free_type_list(tl); +f->def->func->code->stack_depth -= SZ_INT; +} + *(VM_Code*)shred->reg = f->code; + shred->reg += SZ_INT; + return; + } else { + const Emitter emit = shred->vm->gwion->emit; +emit->env->name = "runtime"; +//m_str start = strchr(name, '<'); +m_str start = name; +m_str end = strchr(name, '<'); +char c[instr->m_val2]; +strcpy(c, start); +c[strlen(start) - strlen(end)] = '\0'; +const Symbol sym = func_symbol(o->type_ref->name, c, "template", +*(m_uint*)instr->ptr); + const Value v = nspc_lookup_value1(o->type_ref->nspc, sym); + const Func_Def base = v->d.func_ref->def; + const Func_Def def = new_func_def(base->td, insert_symbol(v->name), + base->arg_list, base->d.code, base->flag); + def->tmpl = new_tmpl_list(base->tmpl->list, *(m_int*)instr->ptr); + SET_FLAG(def, template); + Type_List tl = tmpl_tl(emit->env, name); + env_push_type(emit->env, v->owner_class); + if(template_push_types(emit->env, def->tmpl->list, tl) > 0) + if(traverse_func_def(emit->env, def) > 0) { + emit_func_def(emit, def); + nspc_pop_type(emit->env->curr); + } +env_pop(emit->env, 0); +def->func->code->stack_depth -= SZ_INT; + *(VM_Code*)shred->reg = def->func->code; + shred->reg += SZ_INT; + return; + + + +} + } while((t = t->parent)); +// should not be reached + Except(shred, "MissigTmplException[internal]"); +} diff --git a/src/lib/int.c b/src/lib/int.c index bcb4acb10..06070ff40 100644 --- a/src/lib/int.c +++ b/src/lib/int.c @@ -8,76 +8,6 @@ #include "object.h" #include "import.h" -#define TEST0(pos) if(!*(m_int*)REG(pos))Except(shred, "ZeroDivideException") -#define PREFIX int - -#define _describe(prefix, sz, name, action, ...) \ -static INSTR(prefix##_##name) { GWDEBUG_EXE \ - POP_REG(shred, sz); \ - __VA_ARGS__ \ - action \ -} - -#define describe(name, op, ...) _describe(int, SZ_INT, name, \ - {*(m_int*)REG(-SZ_INT) op##= *(m_int*)REG(0); }, __VA_ARGS__) - -#define describe_r(name, op, ...) _describe(int_r, SZ_INT, name, \ - {*(m_int*)REG(-SZ_INT) = (**(m_int**)REG(0) op##= (*(m_int*)REG(-SZ_INT)));}, __VA_ARGS__) - -#define describe_logical(name, op) _describe(int, SZ_INT, name, \ - {*(m_int*)REG(-SZ_INT) = (*(m_int*)REG(-SZ_INT) op *(m_int*)REG(0));},) -#define describe_pre(name, op) \ -static INSTR(int_pre_##name) { *(m_int*)REG(- SZ_INT) = op(**(m_int**)REG(- SZ_INT)); } -#define describe_post(name, op) \ -static INSTR(int_post_##name) { GWDEBUG_EXE *(m_int*)REG(- SZ_INT) = (**(m_int**)REG(- SZ_INT))op; } - -static INSTR(int_negate) { GWDEBUG_EXE *(m_int*)REG(-SZ_INT) *= -1; } -static INSTR(int_cmp) { GWDEBUG_EXE *(m_int*)REG(-SZ_INT) = ~*(m_int*)REG(-SZ_INT); } - -INSTR(IntNot) { GWDEBUG_EXE *(m_int*)REG(-SZ_INT) = !*(m_int*)REG(-SZ_INT); } - -static INSTR(int_r_assign) { GWDEBUG_EXE - POP_REG(shred, SZ_INT); - **(m_int**)REG(0) = *(m_int*)REG(-SZ_INT); -} - -describe(plus, +,) -describe(minus, -,) -describe(mul, *,) -describe(div, /, TEST0(0)) -describe(modulo, %, TEST0(0)) - -describe_logical(and, &&) -describe_logical(or, ||) -describe_logical(eq, ==) -describe_logical(neq, !=) -describe_logical(gt, >) -describe_logical(ge, >=) -describe_logical(lt, <) -describe_logical(le, <=) -describe_logical(sl, <<) -describe_logical(sr, >>) -describe_logical(sand, &) -describe_logical(sor, |) -describe_logical(xor, ^) - -describe_pre(inc, ++) -describe_pre(dec, --) -//describe_pre(cmp, ~) -describe_post(inc, ++) -describe_post(dec, --) - -describe_r(plus, +,) -describe_r(minus, -,) -describe_r(mul, *,) -describe_r(div, /, TEST0(-SZ_INT)) -describe_r(modulo, %, TEST0(-SZ_INT)) -describe_r(sl, <<,) -describe_r(sr, >>,) -describe_r(sand, &,) -describe_r(sor, |,) -describe_r(sxor, ^,) - #define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func) GWION_IMPORT(int) { @@ -116,11 +46,9 @@ GWION_IMPORT(int) { CHECK_BB(gwi_oper_end(gwi, op_sub, int_negate)) CHECK_BB(gwi_oper_add(gwi, opck_unary_meta)) CHECK_BB(gwi_oper_end(gwi, op_not, IntNot)) -// CHECK_OP(not, unary_meta, not) CHECK_OP(inc, unary, pre_inc) CHECK_OP(dec, unary, pre_dec) CHECK_BB(gwi_oper_end(gwi, op_cmp, int_cmp)) -// CHECK_OP(cmp, unary, pre_cmp) CHECK_BB(gwi_oper_ini(gwi, "int", NULL, "int")) CHECK_OP(inc, post, post_inc) CHECK_OP(dec, post, post_dec) diff --git a/src/lib/object.c b/src/lib/object.c index b390eaebc..7620acf19 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -23,6 +23,7 @@ M_Object new_object(const VM_Shred shred, const Type t) { const M_Object a = mp_alloc(M_Object); a->ref = 1; a->type_ref = t; + a->vtable = &t->nspc->vtable; if(t->nspc->offset) { Type type = t; while(!type->p) @@ -69,7 +70,7 @@ ANN static void handle_dtor(const M_Object object, const VM_Shred shred) { __attribute__((hot)) ANN void __release(const M_Object obj, const VM_Shred shred) { Type t = obj->type_ref; - do { + while(t->parent) { struct scope_iter iter = { &t->nspc->value, 0, 0 };\ Value v; while(scope_iter(&iter, &v) > 0) { @@ -77,36 +78,24 @@ ANN void __release(const M_Object obj, const VM_Shred shred) { release(*(M_Object*)(obj->data + v->offset), shred); } if(GET_FLAG(t, dtor)) { - if(t->nspc->dtor->native_func) - ((f_xtor)t->nspc->dtor->native_func)(obj, shred); + if(GET_FLAG(t->nspc->dtor, builtin)) + ((f_xtor)t->nspc->dtor->native_func)(obj, NULL, shred); else { handle_dtor(obj, shred); return; } } - } while((t = t->parent)); + t = t->parent; + } + free_object(obj); } -void free_object(const M_Object o) { +ANN void free_object(const M_Object o) { if(o->data) _mp_free2(o->p, o->data); mp_free(M_Object, o); } -static DTOR(object_dtor) { free_object(o); } -INSTR(ObjectAssign) { GWDEBUG_EXE - POP_REG(shred, SZ_INT); - const M_Object src = *(M_Object*)REG(-SZ_INT); - const M_Object tgt = **(M_Object**)REG(0); - if(tgt) { - --tgt->ref; - _release(tgt, shred); - } - if(instr->m_val) - *(m_bit**)REG(-SZ_INT) = REG(-SZ_INT); - **(M_Object**)REG(0) = src; -} - #define describe_logical(name, op) \ static INSTR(name##Object) { GWDEBUG_EXE \ POP_REG(shred, SZ_INT); \ @@ -138,7 +127,14 @@ static OP_CHECK(opck_object_cast) { const Exp_Cast* cast = (Exp_Cast*)data; const Type l = cast->exp->type; const Type r = cast->self->type; - return isa(l, r) > 0 ? r : t_null; +// return isa(l, r) > 0 ? r : t_null; + if(isa(l, r) > 0) { + const Type t = type_copy(r); + SET_FLAG(t, force); + env_add_type(env, t); + return t; + } + return t_null; } static OP_CHECK(opck_implicit_null2obj) { @@ -148,7 +144,7 @@ static OP_CHECK(opck_implicit_null2obj) { GWION_IMPORT(object) { CHECK_OB((t_object = gwi_mk_type(gwi, "Object", SZ_INT, NULL))) - CHECK_BB(gwi_class_ini(gwi, t_object, NULL, object_dtor)) + CHECK_BB(gwi_class_ini(gwi, t_object, NULL, NULL)) CHECK_BB(gwi_class_end(gwi)) CHECK_BB(gwi_oper_ini(gwi, "@null", "Object", "Object")) CHECK_BB(gwi_oper_add(gwi, at_object)) diff --git a/src/lib/string.c b/src/lib/string.c index 7818a2158..87f24563d 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -161,11 +161,6 @@ describe_string_plus(Vec4_, SZ_VEC4, m_vec4,, describe_string_plus(Object_, SZ_INT, M_Object, release(lhs, shred), 11, "%p", (void*)lhs) -INSTR(RegPushStr) { GWDEBUG_EXE - *(M_Object*)REG(0) = new_string2(shred, (m_str)instr->m_val); - PUSH_REG(shred, SZ_INT); -} - static CTOR(string_ctor) { STRING(o) = ""; } diff --git a/src/main.c b/src/main.c index 6a148ea6a..a7fe6ff51 100644 --- a/src/main.c +++ b/src/main.c @@ -1,17 +1,14 @@ #include #include -//#include #include #include -#include +#include // arg memset #include #include "gwion_util.h" #include "gwion_ast.h" #include "oo.h" #include "vm.h" #include "env.h" -#include "type.h" -#include "instr.h" #include "compile.h" #include "driver.h" #include "arg.h" @@ -33,8 +30,6 @@ #endif #include "plug.h" -#include -#include extern void parse_args(Arg*, DriverInfo*); static VM* some_static_vm; @@ -45,19 +40,18 @@ static void sig(int unused __attribute__((unused))) { #include "gwion.h" int main(int argc, char** argv) { - Driver d; - Arg arg; + Driver d = { }; + Arg arg = { .argc = argc, .argv=argv, .loop=-1, .quit=0}; DriverInfo di = { 2, 2, 2, 48000, 256, 3, "default:CARD=CODEC", 0, 0, D_FUNC, vm_run, 0, 0}; - d.del = NULL; - memset(&arg, 0, sizeof(Arg)); - arg.argc = argc; - arg.argv = argv; - arg.loop = -1; arg_init(&arg); -//__fsetlocking(stdout, FSETLOCKING_BYCALLER); -//__fsetlocking(stderr, FSETLOCKING_BYCALLER); + +#define STD_BUFSZ 10000 +char buf[STD_BUFSZ]; +setvbuf(stdout, buf, _IOFBF, STD_BUFSZ); +char buf2[STD_BUFSZ]; +setvbuf(stderr, buf2, _IOFBF, STD_BUFSZ); parse_args(&arg, &di); struct Gwion_ gwion; @@ -92,9 +86,6 @@ struct Gwion_ gwion; arg_release(&arg); if(d.del) d.del(gwion.vm, &di); -#ifndef __linux__ - sleep(1); -#endif plug_end(pi); gwion_release(&gwion); return 0; diff --git a/src/oo/context.c b/src/oo/context.c index eff355b1e..370b3b632 100644 --- a/src/oo/context.c +++ b/src/oo/context.c @@ -6,22 +6,20 @@ #include "nspc.h" #include "context.h" +ANN static void free_context(const Context a) { + REM_REF(a->nspc) + mp_free(Context, a); +} + ANN2(2) Context new_context(const Ast ast, const m_str str) { const Context context = mp_alloc(Context); context->nspc = new_nspc(str); context->tree = ast; context->name = str; - INIT_OO(context, e_context_obj); + INIT_OO(context, free_context); return context; } -ANN void free_context(const Context a) { -//if(a->nspc->obj.ref_count > 1)exit(2); -// REM_REF(a->nspc); - free_nspc(a->nspc); - mp_free(Context, a); -} - ANN void load_context(const Context context, const Env env) { ADD_REF((env->context = context)) vector_add(&env->nspc_stack, (vtype)env->curr); diff --git a/src/oo/nspc.c b/src/oo/nspc.c index 0b3c730a8..bea7357ea 100644 --- a/src/oo/nspc.c +++ b/src/oo/nspc.c @@ -18,20 +18,10 @@ ANN void nspc_commit(const Nspc nspc) { scope_commit(&nspc->type); } -ANN Nspc new_nspc(const m_str name) { - const Nspc a = mp_alloc(Nspc); - a->name = name; - scope_init(&a->value); - scope_init(&a->type); - scope_init(&a->func); - INIT_OO(a, e_nspc_obj); - return a; -} - ANN static void nspc_release_object(const Nspc a, Value value) { if(value->d.ptr || (GET_FLAG(value, static) && a->class_data) || (value->d.ptr && GET_FLAG(value, builtin))) { - const VM_Code code = new_vm_code(NULL, 0, 0, "in code dtor"); + const VM_Code code = new_vm_code(NULL, 0, ae_flag_builtin, "in code dtor"); const VM_Shred s = new_vm_shred(code); const M_Object obj = value->d.ptr ? (M_Object)value->d.ptr : *(M_Object*)(a->class_data + value->offset); @@ -67,7 +57,7 @@ ANN static void nspc_free_##b(Nspc n) {\ describe_nspc_free(Func, func) describe_nspc_free(Type, type) -ANN void free_nspc(Nspc a) { +ANN static void free_nspc(Nspc a) { free_nspc_value(a); nspc_free_func(a); nspc_free_type(a); @@ -84,3 +74,13 @@ ANN void free_nspc(Nspc a) { free_op_map(&a->op_map); mp_free(Nspc, a); } + +ANN Nspc new_nspc(const m_str name) { + const Nspc a = mp_alloc(Nspc); + a->name = name; + scope_init(&a->value); + scope_init(&a->type); + scope_init(&a->func); + INIT_OO(a, free_nspc); + return a; +} diff --git a/src/oo/oo.c b/src/oo/oo.c deleted file mode 100644 index 657ad330f..000000000 --- a/src/oo/oo.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" - -extern ANN void free_nspc(void* a); -extern ANN void free_type(void* a); -extern ANN void free_value(void* a); -extern ANN void free_context(void* a); -extern ANN void free_func(void* a); -extern ANN void free_vm_code(void* a); - -typedef void (*cleaner)(void*); -static cleaner cleaners[] = { free_nspc, free_context, free_type, - free_value, free_func, free_vm_code }; - -ANN void rem_ref(const VM_Object a, void* ptr) { - if(--a->ref_count) - return; - cleaners[a->type](ptr); -} diff --git a/src/oo/type.c b/src/oo/type.c index 9aa04e0a1..e7e2877ca 100644 --- a/src/oo/type.c +++ b/src/oo/type.c @@ -6,6 +6,14 @@ #include "type.h" #include "nspc.h" +ANN static void free_type(Type a) { + if(GET_FLAG(a, template)) + free_class_def(a->def); + if(a->nspc) + REM_REF(a->nspc); + mp_free(Type, a); +} + ANN2(2) Type new_type(const m_uint xid, const m_str name, const Type parent) { const Type type = mp_alloc(Type); type->xid = xid; @@ -13,18 +21,10 @@ ANN2(2) Type new_type(const m_uint xid, const m_str name, const Type parent) { type->parent = parent; if(type->parent) type->size = parent->size; - INIT_OO(type, e_type_obj); + INIT_OO(type, free_type); return type; } -ANN void free_type(Type a) { - if(GET_FLAG(a, template)) - free_class_def(a->def); - if(a->nspc) - REM_REF(a->nspc); - mp_free(Type, a); -} - ANN Type type_copy(const Type type) { const Type a = new_type(type->xid, type->name, type->parent); a->nspc = type->nspc; diff --git a/src/oo/value.c b/src/oo/value.c index 91afaa90f..c06b0795c 100644 --- a/src/oo/value.c +++ b/src/oo/value.c @@ -6,15 +6,7 @@ #include "value.h" #include "type.h" -ANN Value new_value(struct Gwion_* gwion, const Type type, const m_str name) { - const Value a = mp_alloc(Value); - a->type = type; - a->name = name; - a->gwion = gwion; - INIT_OO(a, e_value_obj); - return a; -} -ANN void free_value(Value a) { +ANN static void free_value(Value a) { // if(!GET_FLAG(a, func) && !GET_FLAG(a, constprop) && a->d.ptr && isa(a->type, t_object) < 0) if(!GET_FLAG(a, func) && !GET_FLAG(a, constprop) && a->d.ptr && !(GET_FLAG(a, enum) && GET_FLAG(a, builtin) && a->owner_class) @@ -27,3 +19,11 @@ ANN void free_value(Value a) { mp_free(Value, a); } +ANN Value new_value(struct Gwion_* gwion, const Type type, const m_str name) { + const Value a = mp_alloc(Value); + a->type = type; + a->name = name; + a->gwion = gwion; + INIT_OO(a, free_value); + return a; +} diff --git a/src/parse/check.c b/src/parse/check.c index da48ad874..1eabd258f 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -368,7 +368,7 @@ ANN static inline Value template_get_ready(const Value v, const m_str tmpl, cons nspc_lookup_value1(v->owner, sym); } -ANN Func find_template_match(const Env env, const Value v, const Exp_Call* exp) { +ANN static Func _find_template_match(const Env env, const Value v, const Exp_Call* exp) { const Exp args = exp->args; const Type_List types = exp->tmpl->types; Func m_func = exp->m_func; @@ -385,15 +385,25 @@ ANN Func find_template_match(const Env env, const Value v, const Exp_Call* exp) return env->func; } base = def = value->d.func_ref->def; +if(!def->tmpl) { + if(!(value = template_get_ready(v, "template", i))) + continue; + base = value->d.func_ref->def; + def->tmpl = new_tmpl_list(base->tmpl->list, (m_int)i); +} } else { if(!(value = template_get_ready(v, "template", i))) continue; base = value->d.func_ref->def; def = new_func_def(base->td, insert_symbol(v->name), +// def = new_func_def(base->td, insert_symbol(v->name), base->arg_list, base->d.code, base->flag); +//create = 1; +//assert(base->tmpl); def->tmpl = new_tmpl_list(base->tmpl->list, (m_int)i); SET_FLAG(def, template); } +//assert(def->tmpl); if(traverse_func_template(env, def, types) > 0) { nspc_pop_type(env->curr); if(check_call(env, exp) > 0) { @@ -402,21 +412,49 @@ ANN Func find_template_match(const Env env, const Value v, const Exp_Call* exp) m_func = find_func_match(env, def->func, args); def->func->next = next; if(m_func) { +if(!m_func->def->ret_type) { +if(!m_func->def->td)exit(76); +m_func->def->ret_type = type_decl_resolve(env, m_func->def->td); +exit(77); +} SET_FLAG(m_func, checked | ae_flag_template); goto end; } } } SET_FLAG(base, template); - free_func_def(def); +//if(create) +// free_func_def(def); } - assert(exp->self); - err_msg(exp->self->pos, "arguments do not match for template call"); +// assert(exp->self); +// err_msg(exp->self->pos, "arguments do not match for template call"); end: free(tmpl_name); env_pop(env, scope); return m_func; } +ANN Func find_template_match(const Env env, const Value value, const Exp_Call* exp) { +// Value v = value; + Type t = value->owner_class; + const Func f = _find_template_match(env, value, exp); + if(f) + return f; + while(t) { +//assert(t->nspc); + const Value v = nspc_lookup_value1(t->nspc, value->d.func_ref->def->name); +if(!v)goto next; + const Func f = _find_template_match(env, v, exp); + if(f) + return f; +next: +t = t->parent; +} + + assert(exp->self); + err_msg(exp->self->pos, "arguments do not match for template call"); + return NULL; +} + ANN static void print_current_args(Exp e) { gw_err("and not\n\t"); @@ -511,6 +549,7 @@ ANN static Type check_exp_call_template(const Env env, const Exp_Call *exp) { Tmpl_Call tmpl = { .types=tl[0] }; const Exp_Call tmp_func = { .func=call, .args=args, .tmpl=&tmpl, .self=base }; const Func func = get_template_func(env, &tmp_func, base, value); +//exit(2); if(base->exp_type == ae_exp_call) base->d.exp_call.m_func = func; else // if(base->exp_type == ae_exp_binary) @@ -590,7 +629,7 @@ ANN static Type check_exp_dur(const Env env, const Exp_Dur* exp) { GWDEBUG_EXE ANN static Type check_exp_call(const Env env, Exp_Call* exp) { GWDEBUG_EXE if(exp->tmpl) { - CHECK_OO(check_exp(env, exp->func)) // → puts this up ? + CHECK_OO(check_exp(env, exp->func)) const Type t = actual_type(exp->func->type); const Value v = nspc_lookup_value1(t->owner, insert_symbol(t->name)); if(!v) @@ -926,7 +965,8 @@ ANN static m_bool check_stmt_list(const Env env, Stmt_List l) { GWDEBUG_EXE } ANN static m_bool check_signature_match(const Func_Def f, const Func parent) { GWDEBUG_EXE - if(GET_FLAG(parent->def, static) || GET_FLAG(f, static)) { +// if(GET_FLAG(parent->def, static) || GET_FLAG(f, static)) { + if(GET_FLAG(parent->def, static) != GET_FLAG(f, static)) { // wath me const m_str c_name = f->func->value_ref->owner_class->name; const m_str p_name = parent->value_ref->owner_class->name; const m_str f_name = s_name(f->name); @@ -946,7 +986,7 @@ ANN static m_bool parent_match_actual(const Env env, const restrict Func_Def f, if(compat_func(f, parent_func->def) > 0) { CHECK_BB(check_signature_match(f, parent_func)) f->func->vt_index = parent_func->vt_index; - vector_set(&env->curr->vtable, f->func->vt_index, (vtype)func); + vector_set(&env->curr->vtable, f->func->vt_index, (vtype)f->func); return GW_OK; } } while((parent_func = parent_func->next)); @@ -964,7 +1004,9 @@ ANN static m_bool check_parent_match(const Env env, const Func_Def f) { GWDEBUG_ return match; } } - if(GET_FLAG(func, member)) { +// if(SAFE_FLAG(func, member)) { +// if(GET_FLAG(func, member)) { + if(func->value_ref->owner_class) { if(!env->curr->vtable.ptr) vector_init(&env->curr->vtable); func->vt_index = vector_size(&env->curr->vtable); diff --git a/src/parse/func.c b/src/parse/func.c index 4bf0a42c3..23fb0a9d3 100644 --- a/src/parse/func.c +++ b/src/parse/func.c @@ -8,26 +8,24 @@ #include "nspc.h" #include "func.h" +ANN static void free_func(Func a) { + if(GET_FLAG(a, template)) { + free_tmpl_list(a->def->tmpl); + mp_free(Func_Def, a->def); + } + if(a->code) + REM_REF(a->code); + mp_free(Func, a); +} + ANN Func new_func(const m_str name, const Func_Def def) { Func func = mp_alloc(Func); func->name = name; func->def = def; - INIT_OO(func, e_func_obj); + INIT_OO(func, free_func); return func; } -ANN void free_func(Func a) { - if(GET_FLAG(a, ref)) { - if(GET_FLAG(a, template)) { - free_tmpl_list(a->def->tmpl); - mp_free(Func_Def, a->def); - } - } - if(a->code) - REM_REF(a->code); - mp_free(Func, a); -} - #include #include "env.h" #include "type.h" diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 742ef6e1c..7ecc459ae 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -16,12 +16,6 @@ ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list); ANN m_bool scan1_class_def(const Env env, const Class_Def class_def); ANN static m_bool scan1_stmt(const Env env, Stmt stmt); -ANN static void scan1_exp_decl_template(const Type t, const Exp_Decl* decl) { - Exp_Decl* d = (Exp_Decl*)decl; - d->base = t->def; - d->type = t; -} - ANN static Type void_type(const Env env, const Type_Decl* td, const uint pos) { const Type t = known_type(env, td); CHECK_OO(t) @@ -30,7 +24,7 @@ ANN static Type void_type(const Env env, const Type_Decl* td, const uint pos) { ERR_O(pos, "cannot declare variables of size '0' (i.e. 'void')...") } -ANN static Type scan1_exp_decl_type(const Env env, const Exp_Decl* decl) { +ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) { const Type t = void_type(env, decl->td, decl->self->pos); CHECK_OO(t); if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, ref)) @@ -49,17 +43,18 @@ ANN static Type scan1_exp_decl_type(const Env env, const Exp_Decl* decl) { if(GET_FLAG(decl->td, global) && env->class_def) // forbid this ? UNSET_FLAG(decl->td, global); } - if(GET_FLAG(t, template)) - scan1_exp_decl_template(t, decl); + // for template + decl->base = t->def; + decl->type = t; return t; } -ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE +ANN m_bool scan1_exp_decl(const Env env, Exp_Decl* decl) { GWDEBUG_EXE CHECK_BB(env_access(env, decl->td->flag)) env_storage(env, &decl->td->flag); Var_Decl_List list = decl->list; m_uint scope; - ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, decl); + ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl); CHECK_OB(decl->type) const m_bool global = GET_FLAG(decl->td, global); const Nspc nspc = !global ? env->curr : env->global_nspc; @@ -90,7 +85,7 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE v->owner = !env->func ? env->curr : NULL; v->owner_class = env->scope ? NULL : env->class_def; } while((list = list->next)); - ((Exp_Decl*)decl)->type = decl->list->self->value->type; + decl->type = decl->list->self->value->type; if(global) env_pop(env, scope); return GW_OK; @@ -192,10 +187,7 @@ ANN m_bool scan1_stmt_enum(const Env env, const Stmt_Enum stmt) { GWDEBUG_EXE v->owner_class = env->class_def; v->owner = env->curr; SET_FLAG(v, static); - if(GET_FLAG(stmt, private)) - SET_FLAG(v, private); - else if(GET_FLAG(stmt, protect)) - SET_FLAG(v, protect); + SET_ACCESS(stmt, v) } SET_FLAG(v, const | ae_flag_enum | ae_flag_checked); nspc_add_value(stmt->t->owner, list->xid, v); diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 5de5a3ecc..464897003 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -82,10 +82,7 @@ ANN static Value scan2_func_assign(const Env env, const Func_Def d, if(GET_FLAG(f, member)) SET_FLAG(v, member); else SET_FLAG(v, static); - if(GET_FLAG(d, private)) - SET_FLAG(v, private); - else if(GET_FLAG(d, protect)) - SET_FLAG(v, protect); + SET_ACCESS(d, v) } d->func = v->d.func_ref = f; return f->value_ref = v; @@ -133,9 +130,19 @@ ANN static inline Value prim_value(const Env env, const Symbol s) { } ANN static inline m_bool scan2_exp_primary(const Env env, const Exp_Primary* prim) { GWDEBUG_EXE - if(prim->primary_type == ae_primary_hack) + if(prim->primary_type == ae_primary_hack) { CHECK_BB(scan2_exp(env, prim->d.exp)) - else if(prim->primary_type == ae_primary_id) { + Exp e = prim->d.exp; + do { + if(e->exp_type == ae_exp_decl) { + Var_Decl_List l = e->d.exp_decl.list; + do { + const Value v = l->self->value; + SET_FLAG(v, used); + }while ((l = l->next)); + } + } while((e = e->next)); + } else if(prim->primary_type == ae_primary_id) { const Value v = prim_value(env, prim->d.var); if(v) SET_FLAG(v, used); @@ -335,14 +342,14 @@ ANN2(1,2) static Value func_value(const Env env, const Func f, if(!overload) { ADD_REF(v); nspc_add_value(env->curr, f->def->name, v); - } else { + } else if(!GET_FLAG(f->def, template)) { f->next = overload->d.func_ref->next; overload->d.func_ref->next = f; } return v; } -ANN2(1, 2) static m_bool scan2_func_def_template (const Env env, const Func_Def f, const Value overload) { GWDEBUG_EXE +ANN2(1, 2) static m_bool scan2_func_def_template(const Env env, const Func_Def f, const Value overload) { GWDEBUG_EXE const m_str func_name = s_name(f->name); const Func func = scan_new_func(env, f, func_name); const Value value = func_value(env, func, overload); @@ -350,13 +357,16 @@ ANN2(1, 2) static m_bool scan2_func_def_template (const Env env, const Func_Def SET_FLAG(value->type, func); // the only types with func flag, name could be better const Symbol sym = func_symbol(env->curr->name, func_name, "template", overload ? ++overload->offset : 0); nspc_add_value(env->curr, sym, value); +if(!overload) { + ADD_REF(value) + nspc_add_value(env->curr, f->name, value); +} return GW_OK; } ANN static m_bool scan2_func_def_builtin(const Func func, const m_str name) { GWDEBUG_EXE SET_FLAG(func, builtin); - func->code = new_vm_code(NULL, func->def->stack_depth, GET_FLAG(func, member), name); - SET_FLAG(func->code, builtin); + func->code = new_vm_code(NULL, func->def->stack_depth, func->flag, name); func->code->native_func = (m_uint)func->def->d.dl_func_ptr; return GW_OK; } @@ -431,6 +441,7 @@ ANN2(1,2,4) static Value func_create(const Env env, const Func_Def f, scan2_func_def_flag(f); if(GET_FLAG(f, builtin)) CHECK_BO(scan2_func_def_builtin(func, func->name)) +// if(GET_FLAG(func, member) && !GET_FLAG(func->def, func)) if(GET_FLAG(func, member)) f->stack_depth += SZ_INT; if(GET_FLAG(func->def, variadic)) @@ -452,11 +463,14 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE const Symbol sym = func_symbol(env->curr->name, func_name, NULL, overload ? ++overload->offset : 0); func_name = s_name(sym); } else { +if(f->func) + func_name = f->func->name; +else func_name = func_tmpl_name(env, f); const Func func = nspc_lookup_func1(env->curr, insert_symbol(func_name)); if(func) { f->ret_type = type_decl_resolve(env, f->td); - return f->arg_list ? scan2_args(env, f) : 1; + return f->arg_list ? scan2_args(env, f) : GW_OK; } } const Func base = get_func(env, f); @@ -467,8 +481,9 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE CHECK_OB((value = func_create(env, f, overload, func_name))) if(GET_FLAG(f, global)) env_pop(env, scope); - } else + } else { f->func = base; +} if(f->arg_list) CHECK_BB(scan2_args(env, f)) if(!GET_FLAG(f, builtin) && f->d.code->d.stmt_code.stmt_list) diff --git a/src/vm/shreduler.c b/src/vm/shreduler.c index c0a586c63..3d369016c 100644 --- a/src/vm/shreduler.c +++ b/src/vm/shreduler.c @@ -34,7 +34,6 @@ ANN static void shreduler_parent(const VM_Shred out, const Vector v) { vector_release(v); out->parent->child.ptr = NULL; } - out->parent = NULL; } ANN static void shreduler_child(const Shreduler s, const Vector v) { diff --git a/src/vm/vm.c b/src/vm/vm.c index 4fddafe82..f614e31d9 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -6,13 +6,21 @@ #include "oo.h" #include "vm.h" #include "env.h" +#include "nspc.h"//dot func +#include "func.h"//dot func #include "type.h" #include "instr.h" #include "object.h" +#include "import.h" #include "ugen.h" #include "shreduler_private.h" #include "emit.h" #include "gwion.h" +#include "map_private.h" + +#include "value.h" + + static inline uint64_t splitmix64_stateless(uint64_t index) { uint64_t z = (index + UINT64_C(0x9E3779B97F4A7C15)); z = (z ^ (z >> 30)) * UINT64_C(0xBF58476D1CE4E5B9); @@ -74,7 +82,6 @@ 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; } @@ -100,7 +107,7 @@ ANN static inline void vm_ugen_init(const VM* vm) { #define VM_INFO \ if(s->curr) \ gw_err("shred[%" UINT_F "] mem[%" INT_F"] reg[%" INT_F"]\n", shred->xid, \ - shred->mem - (shred->_reg + SIZEOF_REG), shred->reg - shred->_reg); + mem - (shred->_reg + SIZEOF_REG), reg - shred->_reg); #else #define VM_INFO #endif @@ -111,20 +118,674 @@ static struct timespec exec_time; #include #endif + +ANN static inline m_bool overflow_(const m_bit* mem, const VM_Shred c) { + return mem > ((c->_reg + SIZEOF_REG) + (SIZEOF_MEM) - (MEM_STEP)); +} + +ANN static inline VM_Shred init_spork_shred(const VM_Shred shred, const VM_Code code) { + const VM_Shred sh = new_vm_shred(code); + ADD_REF(code) + sh->parent = shred; + if(!shred->child.ptr) + vector_init(&shred->child); + vector_add(&shred->child, (vtype)sh); + sh->base = shred->base; + vm_add_shred(shred->vm, sh); + return sh; +} + +#define TEST0(t, pos) if(!*(t*)(reg-pos)){ exception(shred, "ZeroDivideException"); break; } + __attribute__((hot)) ANN void vm_run(const VM* vm) { + static const void* dispatch[] = { + &®pushimm, &®pushfloat, &®pushother, &®pushaddr, + &®pushmem, &®pushmemfloat, &®pushmemother, &®pushmemaddr, + &&pushnow, + &&baseint, &&basefloat, &&baseother, &&baseaddr, + &®dup, + &&mempushimm, &&memsetimm, + &®pop, &®pushptr, + &&funcreturn, + &&_goto, + &&allocint, &&allocfloat, &&allocother, &&allocaddr, + &&intplus, &&intminus, && intmul, &&intdiv, &&intmod, + // int relationnal + &&inteq, &&intne, &&intand, &&intor, + &&intgt, &&intge, &&intlt, &&intle, + &&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, +// logical + &&floatand, &&floator, &&floateq, &&floatne, + &&floatgt, &&floatge, &&floatlt, &&floatle, + &&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, + &&funcusr, &&funcmember, &&funcstatic, + &&sporkini, &&sporkfunc, &&sporkthis, &&sporkexp, &&sporkend, + &&funcptr, + &&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat, + &&decintaddr, &&initloop, + &&newobj, + &&addref, &&assign, &&remref, + &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr, + &&staticint, &&staticfloat, &&staticother, + &&dotfunc,&&staticcode, &&pushstr, + &&gcini, &&gcadd, &&gcend, + &&gack, &&other + }; const Shreduler s = vm->shreduler; VM_Shred shred; + + +#define DISPATCH()\ + instr =(Instr)(ip[pc++]);\ + VM_INFO;\ + goto *dispatch[instr->opcode]; + while((shred = shreduler_get(s))) { +register VM_Code code = shred->code; +register +m_uint* ip = code->instr->ptr + OFFSET; +register +size_t pc = shred->pc; +register +m_bit* reg = shred->reg; +register +m_bit* mem = shred->mem; + +register union { +M_Object obj; +VM_Code code; +VM_Shred child; +} a; + #ifdef VMBENCH 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->instr, shred->pc++); + register Instr instr; DISPATCH(); +regpushimm: + *(m_uint*)reg = instr->m_val; + reg += SZ_INT; + DISPATCH(); +regpushfloat: +// *(m_float*)reg = instr->f; + *(m_float*)reg = *(m_float*)instr->ptr; + reg += SZ_FLOAT; + DISPATCH(); +regpushother: + LOOP_OPTIM + for(m_uint i = 0; i <= instr->m_val2; i+= SZ_INT) +// *(m_bit**)(reg+i) = (m_bit*)(instr->m_val + i); + *(m_bit**)(reg+i) = (m_bit*)(instr->ptr + i); + reg += instr->m_val2; + DISPATCH(); +regpushaddr: +// *(m_bit**)reg = &instr->m_val; + *(m_bit**)reg = instr->ptr; + reg += SZ_INT; + DISPATCH() +regpushmem: + *(m_uint*)reg = *(m_uint*)(mem + instr->m_val); + reg += SZ_INT; + DISPATCH(); +regpushmemfloat: + *(m_float*)reg = *(m_float*)(mem + instr->m_val); + reg += SZ_FLOAT; + DISPATCH(); +regpushmemother: + LOOP_OPTIM + for(m_uint i = 0; i <= instr->m_val2; i+= SZ_INT) + *(m_uint*)(reg+i) = *(m_uint*)((mem + instr->m_val) + i); + reg += instr->m_val2; + DISPATCH(); +regpushmemaddr: + *(m_bit**)reg = (mem + instr->m_val); + reg += SZ_INT; + DISPATCH() +pushnow: + *(m_float*)reg = vm->bbq->pos; + reg += SZ_FLOAT; + DISPATCH(); +baseint: + *(m_uint*)reg = *(m_uint*)(shred->base + instr->m_val); + reg += SZ_INT; + DISPATCH(); +basefloat: + *(m_float*)reg = *(m_float*)(shred->base + instr->m_val); + reg += SZ_FLOAT; + DISPATCH(); +baseother: + LOOP_OPTIM + for(m_uint i = 0; i <= instr->m_val2; i+= SZ_INT) + *(m_uint*)(reg+i) = *(m_uint*)((shred->base + instr->m_val) + i); + reg += instr->m_val2; + DISPATCH(); +baseaddr: + *(m_bit**)reg = (shred->base + instr->m_val); + reg += SZ_INT; + DISPATCH(); +regdup: + *(m_uint*)reg = *(m_uint*)(reg-SZ_INT); + reg += SZ_INT; + DISPATCH() +mempushimm: + *(m_uint*)mem = instr->m_val; + mem += SZ_INT; + DISPATCH(); +memsetimm: + *(m_uint*)(mem+instr->m_val) = instr->m_val2; + DISPATCH(); +regpop: + reg -= instr->m_val; + DISPATCH(); +regpushptr: + *(m_uint*)(reg-SZ_INT) = instr->m_val; + DISPATCH() +funcreturn: + pc = *(m_uint*)(mem-SZ_INT); + code = *(VM_Code*)(mem-SZ_INT*2); + mem -= (*(m_uint*)(mem-SZ_INT*3) + SZ_INT*3); + ip = code->instr->ptr + OFFSET; + DISPATCH(); +_goto: + pc = instr->m_val; + DISPATCH(); +allocint: + *(m_uint*)reg = *(m_uint*)(mem+instr->m_val) = 0; + reg += SZ_INT; + DISPATCH() +allocfloat: + *(m_float*)reg = *(m_float*)(mem+instr->m_val) = 0; + reg += SZ_FLOAT; + DISPATCH() +allocother: + LOOP_OPTIM + for(m_uint i = 0; i <= instr->m_val; i += SZ_INT) + *(m_uint*)(reg+i) = (*(m_uint*)(mem+instr->m_val+i) = 0); + reg += instr->m_val2; + DISPATCH() +allocaddr: + *(m_uint*)(mem+instr->m_val) = 0; // just set object to null in + *(m_bit**)reg = mem + instr->m_val; + reg += SZ_INT; + DISPATCH() +#define OP(t, sz, op, ...) \ + reg -= sz;\ + __VA_ARGS__\ + *(t*)(reg - sz) op##= *(t*)reg;\ + DISPATCH(); + +#define INT_OP(op, ...) OP(m_int, SZ_INT, op, __VA_ARGS__) +intplus: INT_OP(+) +intminus: INT_OP(-) +intmul: INT_OP(*) +intdiv: INT_OP(/, TEST0(m_int, 0)) +intmod: INT_OP(%, TEST0(m_int, 0)) + +#define LOGICAL(t, sz0, sz, op)\ +reg -= sz0;\ +*(m_int*)(reg-SZ_INT) = (*(t*)(reg - SZ_INT) op *(t*)(reg+sz));\ +DISPATCH() + +// rename to int logical +#define INT_REL(op) LOGICAL(m_int, SZ_INT, 0, op) +inteq: INT_REL(==) +intne: INT_REL(!=) +intand: INT_REL(&&) +intor: INT_REL(||) +intgt: INT_REL(>) +intge: INT_REL(>=) +intlt: INT_REL(<) +intle: INT_REL(<=) +intsl: INT_REL(<<) +intsr: INT_REL(>>) +intsand: INT_REL(&) +intsor: INT_REL(|) +intxor: INT_REL(^) + +#define SELF(t, sz,op) \ + *(t*)(reg - sz) = op*(t*)(reg - sz);\ + DISPATCH(); +#define INT_SELF(op) SELF(m_int, SZ_INT, op) +intnegate: + *(m_int*)(reg - SZ_INT) *= -1; + DISPATCH() +intnot: INT_SELF(!) +intcmp: INT_SELF(~) + +intrassign: + reg -= SZ_INT; +/*assert(*(m_int**)reg);*/ + **(m_int**)reg = *(m_int*)(reg-SZ_INT); + DISPATCH() + +#define R(t, sz, op, ...) \ +reg -= SZ_INT;\ +__VA_ARGS__\ +*(t*)(reg-sz) = (**(t**)reg op##= (*(t*)(reg-sz)));\ +DISPATCH() +#define INT_R(op, ...) R(m_int, SZ_INT, op, __VA_ARGS__) +intradd: INT_R(+) +intrsub: INT_R(-) +intrmul: INT_R(*) +intrdiv: INT_R(/, TEST0(m_int, -SZ_INT)) +intrmod: INT_R(%, TEST0(m_int, -SZ_INT)) +intrsl: INT_R(<<) +intrsr: INT_R(>>) +intrsand: INT_R(&) +intrsor: INT_R(|) +intrxor: INT_R(^) + +#define INT_PRE(op) \ +/*assert(*(m_int**)(reg-SZ_INT));*/\ +*(m_int*)(reg- SZ_INT) = op(**(m_int**)(reg-SZ_INT));\ +DISPATCH() +preinc: INT_PRE(++) +predec: INT_PRE(--) + +#define INT_POST(op) \ +/*assert(*(m_int**)(reg-SZ_INT));*/\ +*(m_int*)(reg- SZ_INT) = (**(m_int**)(reg-SZ_INT))op;\ +DISPATCH() +postinc: INT_POST(++) +postdec: INT_POST(--) + + +#define FLOAT_OP(op) OP(m_float, SZ_FLOAT, op) + +floatadd: FLOAT_OP(+) +floatsub: FLOAT_OP(-) +floatmul: FLOAT_OP(*) +floatdiv: FLOAT_OP(/) + +#define FLOAT_LOGICAL(op) LOGICAL(m_float, SZ_FLOAT * 2 - SZ_INT, \ + SZ_FLOAT - SZ_INT, op) +floatand: FLOAT_LOGICAL(&&) +floator: FLOAT_LOGICAL(||) +floateq: FLOAT_LOGICAL(==) +floatne: FLOAT_LOGICAL(!=) +floatgt: FLOAT_LOGICAL(>) +floatge: FLOAT_LOGICAL(>=) +floatlt: FLOAT_LOGICAL(<) +floatle: FLOAT_LOGICAL(<=) + +floatneg: SELF(m_float, SZ_FLOAT, -) + +floatnot: + reg -= SZ_FLOAT - SZ_INT; + *(m_int*)(reg - SZ_INT) = !*(m_float*)(reg - SZ_INT); + DISPATCH() + +floatrassign: + reg -= SZ_INT; + **(m_float**)reg = *(m_float*)(reg-SZ_FLOAT); + DISPATCH() + +#define FLOAT_R(op, ...) R(m_float, SZ_FLOAT, op) +floatradd: FLOAT_R(+) +floatrsub: FLOAT_R(-) +floatrmul: FLOAT_R(*) +floatrdiv: FLOAT_R(/) + +#define IF_OP(op) \ + reg -=SZ_INT;\ + *(m_float*)(reg-SZ_FLOAT) = (m_float)*(m_int*)(reg-SZ_FLOAT) op \ + *(m_float*)(reg + SZ_INT - SZ_FLOAT); \ + DISPATCH() +ifadd: IF_OP(+) +ifsub: IF_OP(-) +ifmul: IF_OP(*) +ifdiv: IF_OP(/) + +#define IF_LOGICAL(op)\ + reg -= SZ_FLOAT; \ + *(m_int*)(reg-SZ_INT) = (*(m_int*)(reg-SZ_INT) op (m_int)*(m_float*)reg); \ + DISPATCH() +ifand: IF_LOGICAL(&&) +ifor: IF_LOGICAL(||) +ifeq: IF_LOGICAL(==) +ifne: IF_LOGICAL(!=) +ifgt: IF_LOGICAL(>) +ifge: IF_LOGICAL(>=) +iflt: IF_LOGICAL(<) +ifle: IF_LOGICAL(<=) + +#define IF_R(op) \ + reg -= SZ_INT * 2 - SZ_FLOAT; \ + *(m_float*)(reg-SZ_FLOAT) = (**(m_float**)(reg +SZ_INT - SZ_FLOAT) op##= \ + (m_float)*(m_int*)(reg-SZ_FLOAT)); \ + DISPATCH() +ifrassign: IF_R() +ifradd: IF_R(+) +ifrsub: IF_R(-) +ifrmul: IF_R(*) +ifrdiv: IF_R(/) + +#define FI_OP(op)\ + reg -= SZ_INT; \ + *(m_float*)(reg-SZ_FLOAT) op##= (m_float)*(m_int*)reg; \ + DISPATCH() +fiadd: FI_OP(+) +fisub: FI_OP(-) +fimul: FI_OP(*) +fidiv: FI_OP(/) + +#define FI_LOGICAL(op) \ + reg -= SZ_FLOAT; \ + *(m_int*)(reg-SZ_INT) = ((m_int)*(m_float*)(reg-SZ_INT) op\ + *(m_int*)(reg + SZ_FLOAT-SZ_INT)); \ + DISPATCH() +fiand: FI_LOGICAL(&&) +fior: FI_LOGICAL(||) +fieq: FI_LOGICAL(==) +fine: FI_LOGICAL(!=) +figt: FI_LOGICAL( >) +fige: FI_LOGICAL(>=) +filt: FI_LOGICAL( <) +file: FI_LOGICAL(<=) + +firassign: + reg -=SZ_FLOAT; + *(m_int*)(reg-SZ_INT) = **(m_int**)(reg + SZ_FLOAT-SZ_INT) = + (m_int)*(m_float*)(reg-SZ_INT); + DISPATCH() + +#define FI_R(op) \ + reg -= SZ_FLOAT; \ + *(m_int*)(reg-SZ_INT) = (**(m_int**)(reg+SZ_FLOAT -SZ_INT) op##= \ + (m_int)(*(m_float*)(reg-SZ_INT))); \ + DISPATCH() +firadd: FI_R(+) +firsub: FI_R(-) +firmul: FI_R(*) +firdiv: FI_R(/) + +itof: + reg -=SZ_INT - SZ_FLOAT; + *(m_float*)(reg-SZ_FLOAT) = (m_float)*(m_int*)(reg-SZ_FLOAT); + DISPATCH() +ftoi: + reg -= SZ_FLOAT -SZ_INT; + *(m_int*)(reg-SZ_INT) = (m_int)*(m_float*)(reg-SZ_INT); + DISPATCH() + +timeadv: + reg -= SZ_FLOAT; +{ + register const m_float f = *(m_float*)(reg-SZ_FLOAT); + *(m_float*)(reg-SZ_FLOAT) = (shred->wake_time += f); + shredule(s, shred, f); +} +shred->code = code; +shred->reg = reg; +shred->mem = mem; +shred->pc = pc; + break; + +funcusr: +{ + reg -= SZ_INT * 2; + register const m_uint push = *(m_uint*)(reg + SZ_INT) + *(m_uint*)(mem-SZ_INT); + mem += push; + *(m_uint*) mem = push;mem += SZ_INT; + *(VM_Code*) mem = code; mem += SZ_INT; + *(m_uint*) mem = pc; mem += SZ_INT; + pc = 0; + code = *(VM_Code*)reg; +//puts(code->name); +// assert(code); + ip = code->instr->ptr + OFFSET; + m_uint stack_depth = code->stack_depth; + if(stack_depth) { + register const m_uint f = GET_FLAG(code, member) ? SZ_INT : 0; + if(f) { + *(m_uint*)mem = *(m_uint*)(reg - SZ_INT); + stack_depth -= SZ_INT; + } + reg-=code->stack_depth; + LOOP_OPTIM + for(m_uint i = 0; i < stack_depth; i+= SZ_INT) + *(m_uint*)(mem+i+f) = *(m_uint*)(reg+i); + } + if(overflow_(mem, shred)) + Except(shred, "StackOverflow"); +} +//puts(code->name); +DISPATCH(); +funcmember: +{ + reg -= SZ_INT * 2; + a.code = *(VM_Code*)reg; + register const m_uint local_depth = *(m_uint*)(reg + SZ_INT); + register m_bit* m = mem + local_depth; +// assert(a.code); + register const m_uint stack_depth = a.code->stack_depth; + register const m_uint depth = stack_depth -SZ_INT; + reg -= stack_depth; + *(m_uint*)m = *(m_uint*)(reg + depth); +// for(m_uint i = 0; i < stack_depth; i+= SZ_INT) + LOOP_OPTIM + for(m_uint i = 0; i < depth; i+= SZ_INT) + *(m_uint*)(m+i+SZ_INT) = *(m_uint*)(reg+i); + if(overflow_(m, shred)) + Except(shred, "StackOverflow"); + shred->mem = m; + shred->pc = pc; + if(GET_FLAG(a.code, ctor)) { + register const f_xtor f = (f_xtor)a.code->native_func; + f(*(M_Object*)m, NULL, shred);// callnat + goto funcend2;//2 + } + register const f_mfun f = (f_mfun)a.code->native_func; + f((*(M_Object*)m), reg, shred);//call native + goto funcend; +} +funcstatic: +{ + reg -= SZ_INT * 2; + a.code = *(VM_Code*)reg; + register const m_uint local_depth = *(m_uint*)(reg + SZ_INT); + register m_bit* m = mem + local_depth; + //assert(a.code); + register const m_uint stack_depth = a.code->stack_depth; + if(stack_depth) { + reg -= stack_depth; + LOOP_OPTIM + for(m_uint i = 0; i < stack_depth; i+= SZ_INT) + *(m_uint*)(m+i) = *(m_uint*)(reg+i); + } + if(overflow_(m, shred)) + Except(shred, "StackOverflow"); +// shred->reg = reg; + shred->mem = m; + shred->pc = pc; + register const f_sfun f = (f_sfun)a.code->native_func; + f(reg, shred); +funcend: + reg += instr->m_val; +funcend2: + if(!s->curr)break; + pc = shred->pc; + DISPATCH() +} +sporkini: + a.child = init_spork_shred(shred, (VM_Code)instr->m_val); + DISPATCH() +sporkfunc: + LOOP_OPTIM + for(m_uint i = 0; i < instr->m_val; i+= SZ_INT) + *(m_uint*)(a.child->reg + i) = *(m_uint*)(reg + i - SZ_INT); + a.child->reg += instr->m_val; + DISPATCH() +sporkthis: + *(M_Object*)a.child->reg = *(M_Object*)(reg + instr->m_val); + a.child->reg += SZ_INT; + DISPATCH() +sporkexp: + LOOP_OPTIM + for(m_uint i = 0; i < instr->m_val; i+= SZ_INT) + *(m_uint*)(a.child->mem + i) = *(m_uint*)(mem+i); + DISPATCH() +sporkend: + *(M_Object*)(reg-SZ_INT) = a.child->me; + DISPATCH() +funcptr: + if(!GET_FLAG((VM_Code)a.code, builtin)) + goto funcusr; + else if(GET_FLAG((VM_Code)a.code, member)) + goto funcmember; + else + goto funcstatic; +brancheqint: + reg -= SZ_INT; + if(!*(m_uint*)reg) + pc = instr->m_val; + DISPATCH(); +branchneint: + reg -= SZ_INT; + if(*(m_uint*)reg) + pc = instr->m_val; + DISPATCH(); +brancheqfloat: + reg -= SZ_FLOAT; + if(!*(m_float*)reg) + pc = instr->m_val; + DISPATCH(); +branchnefloat: + reg -= SZ_FLOAT; + if(*(m_float*)reg) + pc = instr->m_val; + DISPATCH(); +decintaddr: + --(*((m_uint*)(instr->m_val))); + DISPATCH() +initloop: + reg -= SZ_INT; + (*(m_uint*)instr->m_val) = labs(*(m_int*)reg); + DISPATCH() +newobj: + *(M_Object*)reg = new_object(shred, (Type)instr->m_val); + reg += SZ_INT; + DISPATCH() +addref: +// assert(instr->m_val ? *(m_bit**)(reg-SZ_INT) : reg); // scan-build + if((a.obj = instr->m_val ? **(M_Object**)(reg-SZ_INT) : + *(M_Object*)(reg-SZ_INT))) + ++a.obj->ref; + DISPATCH() +assign: + reg -= SZ_INT; + a.obj = *(M_Object*)(reg-SZ_INT); +// assert(*(M_Object**)reg); // scan-build + const M_Object tgt = **(M_Object**)reg; + if(tgt) { + --tgt->ref; + _release(tgt, shred); + } + **(M_Object**)reg = a.obj; + DISPATCH() +remref: + release(*(M_Object*)(mem + instr->m_val), shred); + DISPATCH() +except: + if(!(a.obj = *(M_Object*)(reg+instr->m_val))) + Except(shred, "NullPtrException"); + DISPATCH(); +allocmemberaddr: + a.obj = *(M_Object*)mem; + *(m_bit**)reg = a.obj->data + instr->m_val; + reg += SZ_INT; + DISPATCH() +dotmember: + *(m_uint*)(reg-SZ_INT) = *(m_uint*)(a.obj->data + instr->m_val); + DISPATCH() +dotfloat: + *(m_float*)(reg-SZ_INT) = *(m_float*)(a.obj->data + instr->m_val); + reg += SZ_FLOAT - SZ_INT; + DISPATCH() +dotother: + LOOP_OPTIM + for(m_uint i = 0; i <= instr->m_val2; i += SZ_INT) + *(m_uint*)(reg+i-SZ_INT) = *(m_uint*)((a.obj->data + instr->m_val) + i); + reg += instr->m_val2 - SZ_INT; + DISPATCH() +dotaddr: + *(m_bit**)(reg-SZ_INT) = (a.obj->data + instr->m_val); + DISPATCH() +staticint: + *(m_uint*)reg = *(m_uint*)instr->m_val; + reg += SZ_INT; + DISPATCH() +staticfloat: + *(m_float*)reg = *(m_float*)instr->m_val; + reg += SZ_FLOAT; + DISPATCH() +staticother: + LOOP_OPTIM + for(m_uint i = 0; i <= instr->m_val2; i += SZ_INT) + *(m_uint*)(reg+i) = *(m_uint*)(instr->m_val + i); + reg += instr->m_val2; + DISPATCH() +dotfunc: + assert(a.obj); +// *(VM_Code*)(reg) = ((Func)vector_at(&a.obj->type_ref->nspc->vtable, instr->m_val))->code; + *(VM_Code*)(reg) = ((Func)vector_at(a.obj->vtable, instr->m_val))->code; + reg += SZ_INT; + DISPATCH() +//dottemplate: +staticcode: + (*(VM_Code*)reg = ((Func)instr->m_val)->code); + reg += SZ_INT; + DISPATCH() +pushstr: + *(M_Object*)reg = new_string2(shred, (m_str)instr->m_val); + reg += SZ_INT; + DISPATCH(); +gcini: + vector_add(&shred->gc, 0); + DISPATCH(); +gcadd: + vector_add(&shred->gc, *(vtype*)(reg-SZ_INT)); + DISPATCH(); +gcend: + while((a.obj = (M_Object)vector_pop(&shred->gc))) { + assert(a.obj); + _release(a.obj, shred); + } + DISPATCH() +gack: + gack(reg, instr); + DISPATCH() +other: +shred->code = code; +shred->reg = reg; +shred->mem = mem; +shred->pc = pc; instr->execute(shred, instr); - VM_INFO; +if(!s->curr)break; +code = shred->code; +ip = shred->code->instr->ptr + OFFSET; +reg = shred->reg; +mem = shred->mem; +pc = shred->pc; +DISPATCH() } while(s->curr); #ifdef VMBENCH clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_end); @@ -135,8 +796,9 @@ timespecadd(&exec_time, &exec_ret, &exec_time); if(!vm->is_running) { #ifdef VMBENCH printf("[VM] exec time %lu.%09lu\n", exec_time.tv_sec, exec_time.tv_nsec); + printf("[VM] exec time %09lu\n", exec_time.tv_nsec/1000); #endif return; - } +} vm_ugen_init(vm); } diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index bc93a29f9..be729fe0a 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -12,21 +12,8 @@ #include "array.h" #include "memoize.h" -VM_Code new_vm_code(const Vector instr, const m_uint stack_depth, - const m_bool need_this, const m_str name) { - VM_Code code = mp_alloc(VM_Code); - code->instr = instr ? vector_copy(instr) : NULL; - code->name = strdup(name); - code->stack_depth = stack_depth; - code->native_func = 0; - if(need_this) - SET_FLAG(code, member); - INIT_OO(code, e_code_obj) - return code; -} - ANN static void free_code_instr_gack(const Instr instr) { - const Vector v = *(Vector*)instr->ptr; + const Vector v = (Vector)instr->m_val2; for(m_uint i = vector_size(v) + 1; --i;) REM_REF(((Type)vector_at(v, i - 1))); free_vector(v); @@ -41,20 +28,18 @@ ANN static void free_array_info(ArrayInfo* info) { ANN static void free_code_instr(const Vector v) { for(m_uint i = vector_size(v) + 1; --i;) { const Instr instr = (Instr)vector_at(v, i - 1); - if(instr->execute == SporkExp) - REM_REF((VM_Code)instr->m_val2) - else if(instr->execute == SporkFunc) - REM_REF((VM_Code)instr->m_val2) + if(instr->opcode == (m_uint)SporkIni) + REM_REF((VM_Code)instr->m_val) else if(instr->execute == ArrayAlloc) - free_array_info(*(ArrayInfo**)instr->ptr); - else if(instr->execute == Gack) + free_array_info((ArrayInfo*)instr->m_val); + else if(instr->opcode == (m_uint)Gack) free_code_instr_gack(instr); else if(instr->execute == BranchSwitch) free_map((Map)instr->m_val2); else if(instr->execute == SwitchIni) { free_vector((Vector)instr->m_val); free_map((Map)instr->m_val2); - } else if(instr->execute == InitLoopCounter) + } else if(instr->opcode == (m_uint)InitLoopCounter) free((m_int*)instr->m_val); else if(instr->execute == VarargIni) { if(instr->m_val2) @@ -65,13 +50,26 @@ ANN static void free_code_instr(const Vector v) { free_vector(v); } -void free_vm_code(VM_Code a) { +ANN static void free_vm_code(VM_Code a) { #ifndef NOMEMOIZE if(a->memoize) memoize_end(a->memoize); #endif - if(a->instr) + if(!GET_FLAG(a, builtin)) +// if(a->instr) free_code_instr(a->instr); free(a->name); mp_free(VM_Code, a); } + +VM_Code new_vm_code(const Vector instr, const m_uint stack_depth, + const ae_flag flag, const m_str name) { + VM_Code code = mp_alloc(VM_Code); + code->instr = instr ? vector_copy(instr) : NULL; + code->name = strdup(name); + code->stack_depth = stack_depth; + code->flag = flag; + INIT_OO(code, free_vm_code) + return code; +} + diff --git a/tests/error/empty_member_ptr.gw b/tests/error/empty_member_ptr.gw index b2b9b24f1..4f233108b 100644 --- a/tests/error/empty_member_ptr.gw +++ b/tests/error/empty_member_ptr.gw @@ -1,4 +1,4 @@ -// [contains] NullFuncPtrException +// [contains] NullPtrException class C { typedef void test(); diff --git a/tests/error/func_ptr_empty.gw b/tests/error/func_ptr_empty.gw index 879ac9a0a..e31849738 100644 --- a/tests/error/func_ptr_empty.gw +++ b/tests/error/func_ptr_empty.gw @@ -1,4 +1,4 @@ -// [contains] NullFuncPtrException +// [contains] NullPtrException typedef void Test() Test test; test(); From a7f31cac6d83c88d36feedd4643ca272fed8739e Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 8 Feb 2019 16:33:57 +0100 Subject: [PATCH 04/59] :art: Update util (finally) --- util | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util b/util index 03a9cf22e..b485442ac 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit 03a9cf22e9a5388cf396503ff722a84d137f48f8 +Subproject commit b485442ac6206ead4ad0faca19e853eed0528394 From 1a1d163508bfaeac7b33b0f83c81b7e87a328c94 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 8 Feb 2019 17:01:38 +0100 Subject: [PATCH 05/59] :art: no stdxxx buf --- src/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index a7fe6ff51..a41534be0 100644 --- a/src/main.c +++ b/src/main.c @@ -47,11 +47,11 @@ int main(int argc, char** argv) { arg_init(&arg); -#define STD_BUFSZ 10000 -char buf[STD_BUFSZ]; -setvbuf(stdout, buf, _IOFBF, STD_BUFSZ); -char buf2[STD_BUFSZ]; -setvbuf(stderr, buf2, _IOFBF, STD_BUFSZ); +//#define STD_BUFSZ 10000 +//char buf[STD_BUFSZ]; +//setvbuf(stdout, buf, _IOFBF, STD_BUFSZ); +//char buf2[STD_BUFSZ]; +//setvbuf(stderr, buf2, _IOFBF, STD_BUFSZ); parse_args(&arg, &di); struct Gwion_ gwion; From d587c3bc7838c8347b2e9d4fcf047d282b8a13d5 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 8 Feb 2019 17:24:33 +0100 Subject: [PATCH 06/59] :art: Gack, BCH --- .bettercodehub.yml | 1 + src/lib/gack.c | 35 ++++++----------------------------- 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/.bettercodehub.yml b/.bettercodehub.yml index e961b8eee..9a69c0114 100644 --- a/.bettercodehub.yml +++ b/.bettercodehub.yml @@ -9,6 +9,7 @@ languages: - /src/ast/parser\.c - /src/ast/lexer\.c - /src/lib/soundpipe\.c + - /src/drvr/*\.c test: include: - /tests/test_plugins/.*\.c diff --git a/src/lib/gack.c b/src/lib/gack.c index 5064b5948..c2e2185a9 100644 --- a/src/lib/gack.c +++ b/src/lib/gack.c @@ -46,7 +46,7 @@ static inline void print_polar(const m_complex c) { gw_out("*pi)"); } -static inline void print_vec(const m_bit* f, const m_uint size) { +ANN 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))); @@ -64,20 +64,20 @@ 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) { +ANN2(1) 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) { +ANN 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) { +ANN 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) @@ -91,31 +91,8 @@ static void print_prim(const Type type, const m_bit* stack) { else print_float(*(m_float*)stack); } -/* -INSTR(Gack) { GWDEBUG_EXE - m_uint offset = instr->m_val; - const Vector v = (Vector)instr->m_val2; - const m_uint size = vector_size(v); - for(m_uint i = size + 1; --i;) { - const Type type = (Type)vector_at(v, size - i); - if(size == 1) - print_type(type); - if(isa(type, t_object) > 0) - print_object(type, *(M_Object*)REG(-offset)); - else if(isa(type, t_function) > 0) - print_func(type, REG(-offset)); - else if(isa(type, t_class) > 0) - print_type(type->d.base_type); - else if(isa(type, t_void) > 0) - print_string1("void"); - else - print_prim(type, REG(-offset)); - offset -= type->size; - } - gw_out("\n"); -} -*/ -void gack(const m_bit* reg, const Instr instr) { + +ANN void gack(const m_bit* reg, const Instr instr) { m_uint offset = instr->m_val; const Vector v = (Vector)instr->m_val2; const m_uint size = vector_size(v); From 720188981a6631b0ee88ccc77e79089d4a301ec4 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 8 Feb 2019 17:31:36 +0100 Subject: [PATCH 07/59] :art: fix BCH --- .bettercodehub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bettercodehub.yml b/.bettercodehub.yml index 9a69c0114..02e0810a3 100644 --- a/.bettercodehub.yml +++ b/.bettercodehub.yml @@ -9,7 +9,7 @@ languages: - /src/ast/parser\.c - /src/ast/lexer\.c - /src/lib/soundpipe\.c - - /src/drvr/*\.c + - /src/drvr/.*\.c test: include: - /tests/test_plugins/.*\.c From 049a5d1b6e0523c8824cabcea03861f51c025b48 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 8 Feb 2019 17:59:17 +0100 Subject: [PATCH 08/59] :fire: move int.c to prim.c and split funcs --- src/lib/prim.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/lib/prim.c diff --git a/src/lib/prim.c b/src/lib/prim.c new file mode 100644 index 000000000..933e44a8e --- /dev/null +++ b/src/lib/prim.c @@ -0,0 +1,85 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "instr.h" +#include "object.h" +#include "import.h" + +#define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func) + +GWION_IMPORT(int_op) { + CHECK_BB(gwi_oper_ini(gwi, "int", "int", "int")) + CHECK_BB(gwi_oper_end(gwi, op_add, int_plus)) + CHECK_BB(gwi_oper_end(gwi, op_sub, int_minus)) + CHECK_BB(gwi_oper_end(gwi, op_mul, int_mul)) + CHECK_BB(gwi_oper_end(gwi, op_div, int_div)) + return gwi_oper_end(gwi, op_mod, int_modulo); +} + +static GWION_IMPORT(int_logical) { + CHECK_BB(gwi_oper_end(gwi, op_and, int_and)) + CHECK_BB(gwi_oper_end(gwi, op_or, int_or)) + CHECK_BB(gwi_oper_end(gwi, op_eq, int_eq)) + CHECK_BB(gwi_oper_end(gwi, op_ne, int_neq)) + CHECK_BB(gwi_oper_end(gwi, op_gt, int_gt)) + CHECK_BB(gwi_oper_end(gwi, op_ge, int_ge)) + CHECK_BB(gwi_oper_end(gwi, op_lt, int_lt)) + CHECK_BB(gwi_oper_end(gwi, op_le, int_le)) + CHECK_BB(gwi_oper_end(gwi, op_shr, int_sr)) + CHECK_BB(gwi_oper_end(gwi, op_shl, int_sl)) + CHECK_BB(gwi_oper_end(gwi, op_sand, int_sand)) + CHECK_BB(gwi_oper_end(gwi, op_sor, int_sor)) + return gwi_oper_end(gwi, op_sxor, int_xor); +} + +static GWION_IMPORT(int_r) { + CHECK_OP(chuck, rassign, r_assign) + CHECK_OP(radd, rassign, r_plus) + CHECK_OP(rsub, rassign, r_minus) + CHECK_OP(rmul, rassign, r_mul) + CHECK_OP(rdiv, rassign, r_div) + CHECK_OP(rmod, rassign, r_modulo) + CHECK_OP(rsl, rassign, r_sl) + CHECK_OP(rsr, rassign, r_sr) + CHECK_OP(rsand, rassign, r_sand) + CHECK_OP(rsor, rassign, r_sor) + CHECK_OP(rsxor, rassign, r_sxor) + return GW_OK; +} + +static GWION_IMPORT(int_unary) { + CHECK_BB(gwi_oper_ini(gwi, NULL, "int", "int")) + CHECK_BB(gwi_oper_add(gwi, opck_unary_meta)) + CHECK_BB(gwi_oper_end(gwi, op_sub, int_negate)) + CHECK_BB(gwi_oper_add(gwi, opck_unary_meta)) + CHECK_BB(gwi_oper_end(gwi, op_not, IntNot)) + CHECK_OP(inc, unary, pre_inc) + CHECK_OP(dec, unary, pre_dec) + CHECK_BB(gwi_oper_end(gwi, op_cmp, int_cmp)) + CHECK_BB(gwi_oper_ini(gwi, "int", NULL, "int")) + CHECK_OP(inc, post, post_inc) + CHECK_BB(gwi_oper_add(gwi, opck_post)) + CHECK_BB(gwi_oper_end(gwi, op_dec, int_post_dec)) + return GW_OK; +} + +static GWION_IMPORT(int_values) { + CHECK_BB(gwi_enum_ini(gwi, "bool")) + CHECK_BB(gwi_enum_add(gwi, "false", 0)) + CHECK_BB(gwi_enum_add(gwi, "true", 1)) + CHECK_BB(gwi_enum_end(gwi)) + CHECK_BB(gwi_item_ini(gwi, "bool", "maybe")) + return gwi_item_end(gwi, 0, NULL); +} + +GWION_IMPORT(int) { + CHECK_BB(gwi_oper_ini(gwi, "int", "int", "int")) + CHECK_BB(import_int_op(gwi)) + CHECK_BB(import_int_logical(gwi)) + CHECK_BB(import_int_r(gwi)) + CHECK_BB(import_int_unary(gwi)) + return import_int_values(gwi); +} From cd10181557d672aa839e65d6c1f7676e0088f946 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 8 Feb 2019 18:02:33 +0100 Subject: [PATCH 09/59] :fire: Really move int.c to prim.c and split funcs --- src/lib/int.c | 62 -------------------------------------------------- src/lib/prim.c | 38 +++++++++++++++---------------- 2 files changed, 19 insertions(+), 81 deletions(-) delete mode 100644 src/lib/int.c diff --git a/src/lib/int.c b/src/lib/int.c deleted file mode 100644 index 06070ff40..000000000 --- a/src/lib/int.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "instr.h" -#include "object.h" -#include "import.h" - -#define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func) - -GWION_IMPORT(int) { - CHECK_BB(gwi_oper_ini(gwi, "int", "int", "int")) - CHECK_BB(gwi_oper_end(gwi, op_add, int_plus)) - CHECK_BB(gwi_oper_end(gwi, op_sub, int_minus)) - CHECK_BB(gwi_oper_end(gwi, op_mul, int_mul)) - CHECK_BB(gwi_oper_end(gwi, op_div, int_div)) - CHECK_BB(gwi_oper_end(gwi, op_mod, int_modulo)) - CHECK_BB(gwi_oper_end(gwi, op_and, int_and)) - CHECK_BB(gwi_oper_end(gwi, op_or, int_or)) - CHECK_BB(gwi_oper_end(gwi, op_eq, int_eq)) - CHECK_BB(gwi_oper_end(gwi, op_ne, int_neq)) - CHECK_BB(gwi_oper_end(gwi, op_gt, int_gt)) - CHECK_BB(gwi_oper_end(gwi, op_ge, int_ge)) - CHECK_BB(gwi_oper_end(gwi, op_lt, int_lt)) - CHECK_BB(gwi_oper_end(gwi, op_le, int_le)) - CHECK_BB(gwi_oper_end(gwi, op_shr, int_sr)) - CHECK_BB(gwi_oper_end(gwi, op_shl, int_sl)) - CHECK_BB(gwi_oper_end(gwi, op_sand, int_sand)) - CHECK_BB(gwi_oper_end(gwi, op_sor, int_sor)) - CHECK_BB(gwi_oper_end(gwi, op_sxor, int_xor)) - CHECK_OP(chuck, rassign, r_assign) - CHECK_OP(radd, rassign, r_plus) - CHECK_OP(rsub, rassign, r_minus) - CHECK_OP(rmul, rassign, r_mul) - CHECK_OP(rdiv, rassign, r_div) - CHECK_OP(rmod, rassign, r_modulo) - CHECK_OP(rsl, rassign, r_sl) - CHECK_OP(rsr, rassign, r_sr) - CHECK_OP(rsand, rassign, r_sand) - CHECK_OP(rsor, rassign, r_sor) - CHECK_OP(rsxor, rassign, r_sxor) - CHECK_BB(gwi_oper_ini(gwi, NULL, "int", "int")) - CHECK_BB(gwi_oper_add(gwi, opck_unary_meta)) - CHECK_BB(gwi_oper_end(gwi, op_sub, int_negate)) - CHECK_BB(gwi_oper_add(gwi, opck_unary_meta)) - CHECK_BB(gwi_oper_end(gwi, op_not, IntNot)) - CHECK_OP(inc, unary, pre_inc) - CHECK_OP(dec, unary, pre_dec) - CHECK_BB(gwi_oper_end(gwi, op_cmp, int_cmp)) - CHECK_BB(gwi_oper_ini(gwi, "int", NULL, "int")) - CHECK_OP(inc, post, post_inc) - CHECK_OP(dec, post, post_dec) - CHECK_BB(gwi_enum_ini(gwi, "bool")) - CHECK_BB(gwi_enum_add(gwi, "false", 0)) - CHECK_BB(gwi_enum_add(gwi, "true", 1)) - CHECK_BB(gwi_enum_end(gwi)) - gwi_item_ini(gwi, "bool", "maybe"); - gwi_item_end(gwi, 0, NULL); - return GW_OK; -} diff --git a/src/lib/prim.c b/src/lib/prim.c index 933e44a8e..ce575e13d 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -12,27 +12,27 @@ GWION_IMPORT(int_op) { CHECK_BB(gwi_oper_ini(gwi, "int", "int", "int")) - CHECK_BB(gwi_oper_end(gwi, op_add, int_plus)) - CHECK_BB(gwi_oper_end(gwi, op_sub, int_minus)) - CHECK_BB(gwi_oper_end(gwi, op_mul, int_mul)) - CHECK_BB(gwi_oper_end(gwi, op_div, int_div)) - return gwi_oper_end(gwi, op_mod, int_modulo); + CHECK_BB(gwi_oper_end(gwi, op_add, int_plus)) + CHECK_BB(gwi_oper_end(gwi, op_sub, int_minus)) + CHECK_BB(gwi_oper_end(gwi, op_mul, int_mul)) + CHECK_BB(gwi_oper_end(gwi, op_div, int_div)) + return gwi_oper_end(gwi, op_mod, int_modulo); } static GWION_IMPORT(int_logical) { - CHECK_BB(gwi_oper_end(gwi, op_and, int_and)) - CHECK_BB(gwi_oper_end(gwi, op_or, int_or)) - CHECK_BB(gwi_oper_end(gwi, op_eq, int_eq)) - CHECK_BB(gwi_oper_end(gwi, op_ne, int_neq)) - CHECK_BB(gwi_oper_end(gwi, op_gt, int_gt)) - CHECK_BB(gwi_oper_end(gwi, op_ge, int_ge)) - CHECK_BB(gwi_oper_end(gwi, op_lt, int_lt)) - CHECK_BB(gwi_oper_end(gwi, op_le, int_le)) + CHECK_BB(gwi_oper_end(gwi, op_and, int_and)) + CHECK_BB(gwi_oper_end(gwi, op_or, int_or)) + CHECK_BB(gwi_oper_end(gwi, op_eq, int_eq)) + CHECK_BB(gwi_oper_end(gwi, op_ne, int_neq)) + CHECK_BB(gwi_oper_end(gwi, op_gt, int_gt)) + CHECK_BB(gwi_oper_end(gwi, op_ge, int_ge)) + CHECK_BB(gwi_oper_end(gwi, op_lt, int_lt)) + CHECK_BB(gwi_oper_end(gwi, op_le, int_le)) CHECK_BB(gwi_oper_end(gwi, op_shr, int_sr)) - CHECK_BB(gwi_oper_end(gwi, op_shl, int_sl)) - CHECK_BB(gwi_oper_end(gwi, op_sand, int_sand)) - CHECK_BB(gwi_oper_end(gwi, op_sor, int_sor)) - return gwi_oper_end(gwi, op_sxor, int_xor); + CHECK_BB(gwi_oper_end(gwi, op_shl, int_sl)) + CHECK_BB(gwi_oper_end(gwi, op_sand, int_sand)) + CHECK_BB(gwi_oper_end(gwi, op_sor, int_sor)) + return gwi_oper_end(gwi, op_sxor, int_xor); } static GWION_IMPORT(int_r) { @@ -56,11 +56,11 @@ static GWION_IMPORT(int_unary) { CHECK_BB(gwi_oper_end(gwi, op_sub, int_negate)) CHECK_BB(gwi_oper_add(gwi, opck_unary_meta)) CHECK_BB(gwi_oper_end(gwi, op_not, IntNot)) - CHECK_OP(inc, unary, pre_inc) + CHECK_OP(inc, unary, pre_inc) CHECK_OP(dec, unary, pre_dec) CHECK_BB(gwi_oper_end(gwi, op_cmp, int_cmp)) CHECK_BB(gwi_oper_ini(gwi, "int", NULL, "int")) - CHECK_OP(inc, post, post_inc) + CHECK_OP(inc, post, post_inc) CHECK_BB(gwi_oper_add(gwi, opck_post)) CHECK_BB(gwi_oper_end(gwi, op_dec, int_post_dec)) return GW_OK; From 5cad14ebf880376c7b36a9934a5919b61e7f745e Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 8 Feb 2019 18:12:24 +0100 Subject: [PATCH 10/59] :art: Move define outside vm --- src/vm/vm.c | 183 +++++++++++++++++++++++++++------------------------- 1 file changed, 95 insertions(+), 88 deletions(-) diff --git a/src/vm/vm.c b/src/vm/vm.c index f614e31d9..ded4ca533 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -136,8 +136,87 @@ ANN static inline VM_Shred init_spork_shred(const VM_Shred shred, const VM_Code } #define TEST0(t, pos) if(!*(t*)(reg-pos)){ exception(shred, "ZeroDivideException"); break; } +#define DISPATCH()\ + instr =(Instr)(ip[pc++]);\ + VM_INFO;\ + goto *dispatch[instr->opcode]; + +#define OP(t, sz, op, ...) \ + reg -= sz;\ + __VA_ARGS__\ + *(t*)(reg - sz) op##= *(t*)reg;\ + DISPATCH(); + +#define INT_OP(op, ...) OP(m_int, SZ_INT, op, __VA_ARGS__) +#define FLOAT_OP(op) OP(m_float, SZ_FLOAT, op) + +#define LOGICAL(t, sz0, sz, op)\ +reg -= sz0;\ +*(m_int*)(reg-SZ_INT) = (*(t*)(reg - SZ_INT) op *(t*)(reg+sz));\ +DISPATCH() + +#define INT_LOGICAL(op) LOGICAL(m_int, SZ_INT, 0, op) +#define FLOAT_LOGICAL(op) LOGICAL(m_float, SZ_FLOAT * 2 - SZ_INT, \ + SZ_FLOAT - SZ_INT, op) + +#define SELF(t, sz,op) \ + *(t*)(reg - sz) = op*(t*)(reg - sz);\ + DISPATCH(); + +#define R(t, sz, op, ...) \ +reg -= SZ_INT;\ +__VA_ARGS__\ +*(t*)(reg-sz) = (**(t**)reg op##= (*(t*)(reg-sz)));\ +DISPATCH() +#define INT_R(op, ...) R(m_int, SZ_INT, op, __VA_ARGS__) +#define FLOAT_R(op, ...) R(m_float, SZ_FLOAT, op) + +#define INT_PRE(op) \ +/*assert(*(m_int**)(reg-SZ_INT));*/\ +*(m_int*)(reg- SZ_INT) = op(**(m_int**)(reg-SZ_INT));\ +DISPATCH() + +#define INT_POST(op) \ +/*assert(*(m_int**)(reg-SZ_INT));*/\ +*(m_int*)(reg- SZ_INT) = (**(m_int**)(reg-SZ_INT))op;\ +DISPATCH() + +#define IF_OP(op) \ + reg -=SZ_INT;\ + *(m_float*)(reg-SZ_FLOAT) = (m_float)*(m_int*)(reg-SZ_FLOAT) op \ + *(m_float*)(reg + SZ_INT - SZ_FLOAT); \ + DISPATCH() + +#define IF_LOGICAL(op)\ + reg -= SZ_FLOAT; \ + *(m_int*)(reg-SZ_INT) = (*(m_int*)(reg-SZ_INT) op (m_int)*(m_float*)reg); \ + DISPATCH() __attribute__((hot)) + +#define IF_R(op) \ + reg -= SZ_INT * 2 - SZ_FLOAT; \ + *(m_float*)(reg-SZ_FLOAT) = (**(m_float**)(reg +SZ_INT - SZ_FLOAT) op##= \ + (m_float)*(m_int*)(reg-SZ_FLOAT)); \ + DISPATCH() + +#define FI_OP(op)\ + reg -= SZ_INT; \ + *(m_float*)(reg-SZ_FLOAT) op##= (m_float)*(m_int*)reg; \ + DISPATCH() + +#define FI_LOGICAL(op) \ + reg -= SZ_FLOAT; \ + *(m_int*)(reg-SZ_INT) = ((m_int)*(m_float*)(reg-SZ_INT) op\ + *(m_int*)(reg + SZ_FLOAT-SZ_INT)); \ + DISPATCH() + +#define FI_R(op) \ + reg -= SZ_FLOAT; \ + *(m_int*)(reg-SZ_INT) = (**(m_int**)(reg+SZ_FLOAT -SZ_INT) op##= \ + (m_int)(*(m_float*)(reg-SZ_INT))); \ + DISPATCH() + ANN void vm_run(const VM* vm) { static const void* dispatch[] = { &®pushimm, &®pushfloat, &®pushother, &®pushaddr, @@ -189,13 +268,7 @@ ANN void vm_run(const VM* vm) { &&gack, &&other }; const Shreduler s = vm->shreduler; - VM_Shred shred; - - -#define DISPATCH()\ - instr =(Instr)(ip[pc++]);\ - VM_INFO;\ - goto *dispatch[instr->opcode]; + register VM_Shred shred; while((shred = shreduler_get(s))) { register VM_Code code = shred->code; @@ -326,49 +399,31 @@ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini); *(m_bit**)reg = mem + instr->m_val; reg += SZ_INT; DISPATCH() -#define OP(t, sz, op, ...) \ - reg -= sz;\ - __VA_ARGS__\ - *(t*)(reg - sz) op##= *(t*)reg;\ - DISPATCH(); - -#define INT_OP(op, ...) OP(m_int, SZ_INT, op, __VA_ARGS__) intplus: INT_OP(+) intminus: INT_OP(-) intmul: INT_OP(*) intdiv: INT_OP(/, TEST0(m_int, 0)) intmod: INT_OP(%, TEST0(m_int, 0)) -#define LOGICAL(t, sz0, sz, op)\ -reg -= sz0;\ -*(m_int*)(reg-SZ_INT) = (*(t*)(reg - SZ_INT) op *(t*)(reg+sz));\ -DISPATCH() - -// rename to int logical -#define INT_REL(op) LOGICAL(m_int, SZ_INT, 0, op) -inteq: INT_REL(==) -intne: INT_REL(!=) -intand: INT_REL(&&) -intor: INT_REL(||) -intgt: INT_REL(>) -intge: INT_REL(>=) -intlt: INT_REL(<) -intle: INT_REL(<=) -intsl: INT_REL(<<) -intsr: INT_REL(>>) -intsand: INT_REL(&) -intsor: INT_REL(|) -intxor: INT_REL(^) +inteq: INT_LOGICAL(==) +intne: INT_LOGICAL(!=) +intand: INT_LOGICAL(&&) +intor: INT_LOGICAL(||) +intgt: INT_LOGICAL(>) +intge: INT_LOGICAL(>=) +intlt: INT_LOGICAL(<) +intle: INT_LOGICAL(<=) +intsl: INT_LOGICAL(<<) +intsr: INT_LOGICAL(>>) +intsand: INT_LOGICAL(&) +intsor: INT_LOGICAL(|) +intxor: INT_LOGICAL(^) -#define SELF(t, sz,op) \ - *(t*)(reg - sz) = op*(t*)(reg - sz);\ - DISPATCH(); -#define INT_SELF(op) SELF(m_int, SZ_INT, op) intnegate: *(m_int*)(reg - SZ_INT) *= -1; DISPATCH() -intnot: INT_SELF(!) -intcmp: INT_SELF(~) +intnot: SELF(m_int, SZ_INT, !) +intcmp: SELF(m_int, SZ_INT, ~) intrassign: reg -= SZ_INT; @@ -376,12 +431,6 @@ intcmp: INT_SELF(~) **(m_int**)reg = *(m_int*)(reg-SZ_INT); DISPATCH() -#define R(t, sz, op, ...) \ -reg -= SZ_INT;\ -__VA_ARGS__\ -*(t*)(reg-sz) = (**(t**)reg op##= (*(t*)(reg-sz)));\ -DISPATCH() -#define INT_R(op, ...) R(m_int, SZ_INT, op, __VA_ARGS__) intradd: INT_R(+) intrsub: INT_R(-) intrmul: INT_R(*) @@ -393,30 +442,17 @@ intrsand: INT_R(&) intrsor: INT_R(|) intrxor: INT_R(^) -#define INT_PRE(op) \ -/*assert(*(m_int**)(reg-SZ_INT));*/\ -*(m_int*)(reg- SZ_INT) = op(**(m_int**)(reg-SZ_INT));\ -DISPATCH() preinc: INT_PRE(++) predec: INT_PRE(--) -#define INT_POST(op) \ -/*assert(*(m_int**)(reg-SZ_INT));*/\ -*(m_int*)(reg- SZ_INT) = (**(m_int**)(reg-SZ_INT))op;\ -DISPATCH() postinc: INT_POST(++) postdec: INT_POST(--) - -#define FLOAT_OP(op) OP(m_float, SZ_FLOAT, op) - floatadd: FLOAT_OP(+) floatsub: FLOAT_OP(-) floatmul: FLOAT_OP(*) floatdiv: FLOAT_OP(/) -#define FLOAT_LOGICAL(op) LOGICAL(m_float, SZ_FLOAT * 2 - SZ_INT, \ - SZ_FLOAT - SZ_INT, op) floatand: FLOAT_LOGICAL(&&) floator: FLOAT_LOGICAL(||) floateq: FLOAT_LOGICAL(==) @@ -438,26 +474,16 @@ floatneg: SELF(m_float, SZ_FLOAT, -) **(m_float**)reg = *(m_float*)(reg-SZ_FLOAT); DISPATCH() -#define FLOAT_R(op, ...) R(m_float, SZ_FLOAT, op) floatradd: FLOAT_R(+) floatrsub: FLOAT_R(-) floatrmul: FLOAT_R(*) floatrdiv: FLOAT_R(/) -#define IF_OP(op) \ - reg -=SZ_INT;\ - *(m_float*)(reg-SZ_FLOAT) = (m_float)*(m_int*)(reg-SZ_FLOAT) op \ - *(m_float*)(reg + SZ_INT - SZ_FLOAT); \ - DISPATCH() ifadd: IF_OP(+) ifsub: IF_OP(-) ifmul: IF_OP(*) ifdiv: IF_OP(/) -#define IF_LOGICAL(op)\ - reg -= SZ_FLOAT; \ - *(m_int*)(reg-SZ_INT) = (*(m_int*)(reg-SZ_INT) op (m_int)*(m_float*)reg); \ - DISPATCH() ifand: IF_LOGICAL(&&) ifor: IF_LOGICAL(||) ifeq: IF_LOGICAL(==) @@ -467,31 +493,17 @@ ifge: IF_LOGICAL(>=) iflt: IF_LOGICAL(<) ifle: IF_LOGICAL(<=) -#define IF_R(op) \ - reg -= SZ_INT * 2 - SZ_FLOAT; \ - *(m_float*)(reg-SZ_FLOAT) = (**(m_float**)(reg +SZ_INT - SZ_FLOAT) op##= \ - (m_float)*(m_int*)(reg-SZ_FLOAT)); \ - DISPATCH() ifrassign: IF_R() ifradd: IF_R(+) ifrsub: IF_R(-) ifrmul: IF_R(*) ifrdiv: IF_R(/) -#define FI_OP(op)\ - reg -= SZ_INT; \ - *(m_float*)(reg-SZ_FLOAT) op##= (m_float)*(m_int*)reg; \ - DISPATCH() fiadd: FI_OP(+) fisub: FI_OP(-) fimul: FI_OP(*) fidiv: FI_OP(/) -#define FI_LOGICAL(op) \ - reg -= SZ_FLOAT; \ - *(m_int*)(reg-SZ_INT) = ((m_int)*(m_float*)(reg-SZ_INT) op\ - *(m_int*)(reg + SZ_FLOAT-SZ_INT)); \ - DISPATCH() fiand: FI_LOGICAL(&&) fior: FI_LOGICAL(||) fieq: FI_LOGICAL(==) @@ -507,11 +519,6 @@ file: FI_LOGICAL(<=) (m_int)*(m_float*)(reg-SZ_INT); DISPATCH() -#define FI_R(op) \ - reg -= SZ_FLOAT; \ - *(m_int*)(reg-SZ_INT) = (**(m_int**)(reg+SZ_FLOAT -SZ_INT) op##= \ - (m_int)(*(m_float*)(reg-SZ_INT))); \ - DISPATCH() firadd: FI_R(+) firsub: FI_R(-) firmul: FI_R(*) From 337d51dee2bc46000eba5eaaccd25c2b03714fe8 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 8 Feb 2019 18:24:42 +0100 Subject: [PATCH 11/59] :art: BCH --- .bettercodehub.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.bettercodehub.yml b/.bettercodehub.yml index 02e0810a3..aa9927009 100644 --- a/.bettercodehub.yml +++ b/.bettercodehub.yml @@ -6,10 +6,8 @@ languages: include: - /src/.*\.c exclude: - - /src/ast/parser\.c - - /src/ast/lexer\.c - - /src/lib/soundpipe\.c - /src/drvr/.*\.c + - /src/vm/vm.c test: include: - /tests/test_plugins/.*\.c From 3ad74738e5e8d53e6bbb52f77f1c9ae55a639221 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 00:31:39 +0100 Subject: [PATCH 12/59] :art: More ... --- src/vm/vm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vm/vm.c b/src/vm/vm.c index ded4ca533..60a7f7bea 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -628,6 +628,7 @@ DISPATCH(); funcend: reg += instr->m_val; funcend2: + shred->mem = mem; if(!s->curr)break; pc = shred->pc; DISPATCH() From d37335e787c37660edc3e4eebd00ed2b0606fedc Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 00:32:14 +0100 Subject: [PATCH 13/59] :Fix: Operator emit func->code --- src/parse/operator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parse/operator.c b/src/parse/operator.c index 2c2b7df32..fb59741d1 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); - instr->m_val = (m_uint)mo->func; + instr->m_val = (m_uint)mo->func->code; return emit_exp_call1(emit, mo->func); } emit_add_instr(emit, mo->instr); From 0078f9d2438a194f7e7bc14b09c2fffffb69ba9b Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 00:32:14 +0100 Subject: [PATCH 14/59] :Fix: Operator emit func->code, add instr --- include/instr.h | 3 --- include/opcode.h | 6 ++++-- opcode.txt | 3 ++- src/emit/emit.c | 7 +------ src/lib/instr.c | 10 ---------- src/parse/operator.c | 2 +- src/vm/vm.c | 16 ++++++++++------ 7 files changed, 18 insertions(+), 29 deletions(-) diff --git a/include/instr.h b/include/instr.h index 8b1677be4..3b57e5785 100644 --- a/include/instr.h +++ b/include/instr.h @@ -34,9 +34,6 @@ INSTR(EOC); INSTR(DTOR_EOC); INSTR(DtorReturn); -INSTR(RegPushMe); -INSTR(RegPushMaybe); - /* branching */ INSTR(BranchSwitch); INSTR(SwitchIni); diff --git a/include/opcode.h b/include/opcode.h index 6af942c7a..d7b01b37a 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -15,10 +15,11 @@ enum { RegPushBase3, RegPushBase4, RegDup, - MemPushImm, MemSetImm, RegPop, RegPushPtr, + RegPushMe, + RegPushMaybe, FuncReturn, Goto, AllocWord, @@ -169,10 +170,11 @@ enum { #define RegPushBase3 (f_instr)RegPushBase3 #define RegPushBase4 (f_instr)RegPushBase4 #define RegDup (f_instr)RegDup -#define MemPushImm (f_instr)MemPushImm #define MemSetImm (f_instr)MemSetImm #define RegPop (f_instr)RegPop #define RegPushPtr (f_instr)RegPushPtr +#define RegPushMe (f_instr)RegPushMe +#define RegPushMaybe (f_instr)RegPushMaybe #define FuncReturn (f_instr)FuncReturn #define Goto (f_instr)Goto #define AllocWord (f_instr)AllocWord diff --git a/opcode.txt b/opcode.txt index 35ddfcc8f..ef5908a04 100644 --- a/opcode.txt +++ b/opcode.txt @@ -12,10 +12,11 @@ RegPushBase2 RegPushBase3 RegPushBase4 RegDup -MemPushImm MemSetImm RegPop RegPushPtr +RegPushMe +RegPushMaybe FuncReturn Goto AllocWord diff --git a/src/emit/emit.c b/src/emit/emit.c index 3546e55ae..530933953 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -814,13 +814,8 @@ ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) { GWDEBUG_ push_spork_code(emit, SPORK_FUNC_PREFIX, exp->self->pos); if(GET_FLAG(exp->m_func, member)) SET_FLAG(emit->code, member); - const Instr op = emit_add_instr(emit, MemPushImm); - op->m_val = emit->code->stack_depth; -const Instr p = - - emit_add_instr(emit, RegPushImm); + const Instr p = emit_add_instr(emit, RegPushImm); p->m_val = (m_uint)exp->m_func->code; - CHECK_BB(emit_exp_call1(emit, exp->m_func)) const VM_Code code = finalyze(emit); const m_uint size = exp->m_func->def->stack_depth - (GET_FLAG(exp->m_func, diff --git a/src/lib/instr.c b/src/lib/instr.c index 6065c331a..8c928f867 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -31,16 +31,6 @@ INSTR(EOC2) { GWDEBUG_EXE shreduler_remove(shred->vm->shreduler, shred, 0); } -INSTR(RegPushMe) { GWDEBUG_EXE - *(M_Object*)REG(0) = shred->me; - PUSH_REG(shred, SZ_INT); -} - -INSTR(RegPushMaybe) { GWDEBUG_EXE - *(m_uint*)REG(0) = gw_rand(shred->vm->rand) > (UINT32_MAX / 2); - PUSH_REG(shred, SZ_INT); -} - /* branching */ INSTR(SwitchIni) { const Vector v = (Vector)instr->m_val; diff --git a/src/parse/operator.c b/src/parse/operator.c index 2c2b7df32..fb59741d1 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); - instr->m_val = (m_uint)mo->func; + instr->m_val = (m_uint)mo->func->code; 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 60a7f7bea..a9959861c 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -224,8 +224,8 @@ ANN void vm_run(const VM* vm) { &&pushnow, &&baseint, &&basefloat, &&baseother, &&baseaddr, &®dup, - &&mempushimm, &&memsetimm, - &®pop, &®pushptr, + &&memsetimm, + &®pop, &®pushptr, &®pushme, &®pushmaybe, &&funcreturn, &&_goto, &&allocint, &&allocfloat, &&allocother, &&allocaddr, @@ -358,10 +358,6 @@ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini); *(m_uint*)reg = *(m_uint*)(reg-SZ_INT); reg += SZ_INT; DISPATCH() -mempushimm: - *(m_uint*)mem = instr->m_val; - mem += SZ_INT; - DISPATCH(); memsetimm: *(m_uint*)(mem+instr->m_val) = instr->m_val2; DISPATCH(); @@ -371,6 +367,14 @@ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini); regpushptr: *(m_uint*)(reg-SZ_INT) = instr->m_val; DISPATCH() +regpushme: + *(M_Object*)reg = shred->me; + reg += SZ_INT; + DISPATCH() +regpushmaybe: + *(m_uint*)reg = gw_rand((uint32_t*)vm->rand) > (UINT32_MAX / 2); + reg += SZ_INT; + DISPATCH(); funcreturn: pc = *(m_uint*)(mem-SZ_INT); code = *(VM_Code*)(mem-SZ_INT*2); From a9f8aa78af42f8e9f0d71fef1a2babe1490ec198 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 08:31:38 +0100 Subject: [PATCH 15/59] :art: Few fixes --- include/array.h | 1 - include/instr.h | 1 - src/emit/emit.c | 11 ++++------- src/parse/check.c | 14 ++++++-------- src/parse/scan1.c | 3 +++ 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/include/array.h b/include/array.h index 7b96e5d3a..b19786eba 100644 --- a/include/array.h +++ b/include/array.h @@ -3,7 +3,6 @@ typedef struct M_Vector_ * M_Vector; typedef struct ArrayInfo_ { m_int depth; -// Type type, base; struct Vector_ type; Type base; M_Object* data; diff --git a/include/instr.h b/include/instr.h index 3b57e5785..5c6cf8633 100644 --- a/include/instr.h +++ b/include/instr.h @@ -62,7 +62,6 @@ INSTR(VarargTop); INSTR(VarargEnd); INSTR(VarargMember); -INSTR(MemberFunction); INSTR(VecMember); INSTR(PopArrayClass); diff --git a/src/emit/emit.c b/src/emit/emit.c index 530933953..b8e60bf4c 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -91,7 +91,6 @@ ANN /*static */m_bool emit_func_def(const Emitter emit, const Func_Def func_def) ANEW static Code* new_code(const Emitter emit, const m_str name) { Code* code = mp_alloc(Code); code->name = code_name_set(name, emit->env->name); - code->stack_depth = 0; vector_init(&code->instr); vector_init(&code->stack_break); vector_init(&code->stack_cont); @@ -232,7 +231,6 @@ ANN static Instr emit_kind(Emitter emit, const m_uint size, const uint addr, con static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 }; 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 dotstatic[] = { DotStatic, DotStatic2, DotStatic3, RegPushImm }; static const f_instr dotmember[] = { DotMember, DotMember2, DotMember3, DotMember4 }; static const f_instr allocmember[] = { RegPushImm, RegPushImm2, RegPushImm3, AllocMember4 }; @@ -618,15 +616,14 @@ ANN static inline m_int push_tmpl_func(const Emitter emit, const Func f, const Type_List types) { const Value v = f->value_ref; const m_uint scope = emit_push(emit, v->owner_class, v->owner); -// CHECK_BB(traverse_func_template(emit->env, f->def, types)) - CHECK_BB(traverse_func_template(emit->env, v->d.func_ref->def, types)) + CHECK_BB(traverse_func_template(emit->env, f->def, types)) return (m_int)scope; } ANN static m_bool emit_exp_call_template(const Emitter emit, const Exp_Call* exp_call) { if(emit->env->func && emit->env->func == exp_call->m_func) return prepare_call(emit, exp_call); - m_int scope = push_tmpl_func(emit, exp_call->m_func, exp_call->tmpl->types); + const m_int scope = push_tmpl_func(emit, exp_call->m_func, exp_call->tmpl->types); CHECK_BB(scope); CHECK_BB(prepare_call(emit, exp_call)) emit_pop_type(emit); @@ -1372,7 +1369,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); - instr->m_val = (m_uint)((Func)vector_at(&v->owner_class->nspc->vtable, v->d.func_ref->vt_index))->code; + instr->m_val = (m_uint)v->d.func_ref->code; } ANN static m_bool emit_VecMember(const Emitter emit, const Exp_Dot* member) { @@ -1587,7 +1584,7 @@ ANN /*static */m_bool emit_func_def(const Emitter emit, const Func_Def func_def) const Func func = get_func(emit->env, func_def); if(func->code)return GW_OK; if(tmpl_list_base(func_def->tmpl)) { // don't check template definition - UNSET_FLAG(func_def, template);; + UNSET_FLAG(func_def, template); return GW_OK; } if(SAFE_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template)) diff --git a/src/parse/check.c b/src/parse/check.c index 1eabd258f..0a3692921 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -1004,14 +1004,12 @@ ANN static m_bool check_parent_match(const Env env, const Func_Def f) { GWDEBUG_ return match; } } -// if(SAFE_FLAG(func, member)) { // if(GET_FLAG(func, member)) { - if(func->value_ref->owner_class) { - if(!env->curr->vtable.ptr) - vector_init(&env->curr->vtable); - func->vt_index = vector_size(&env->curr->vtable); - vector_add(&env->curr->vtable, (vtype)func); - } + if(!env->curr->vtable.ptr) + vector_init(&env->curr->vtable); + func->vt_index = vector_size(&env->curr->vtable); + vector_add(&env->curr->vtable, (vtype)func); +// } return GW_OK; } @@ -1081,7 +1079,7 @@ ANN static void operator_func(Func f) { ANN m_bool check_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE const Func func = get_func(env, f); - m_bool ret = 1; + m_bool ret = GW_OK; if(tmpl_list_base(f->tmpl)) return env->class_def ? check_parent_match(env, f) : 1; CHECK_BB(check_func_def_override(env, f)) diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 7ecc459ae..57fc2bfe3 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -296,6 +296,9 @@ ANN static m_bool scan1_class_parent(const Env env, const Class_Def class_def) { CHECK_BB(scan1_exp(env, class_def->ext->array->exp)) const Type parent = class_def->type->parent = known_type(env, class_def->ext); CHECK_OB(parent) + if(parent == class_def->type) + ERR_B(class_def->ext->xid->pos, "class '%s' cannot extend itself", + class_def->type->name); if(isa(class_def->type->parent, t_object) < 0) ERR_B(class_def->ext->xid->pos, "cannot extend primitive type '%s'", class_def->type->parent->name) From bbf260fe29f20caf69c8a3ea68a3883e076fae9d Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 15:25:32 +0100 Subject: [PATCH 16/59] :art: Split VM_Shred --- include/shreduler_private.h | 4 +- include/vm.h | 31 ++++++++----- src/compile.c | 2 +- src/lib/array.c | 2 +- src/lib/event.c | 6 +-- src/lib/instr.c | 8 ++-- src/lib/object.c | 6 +-- src/lib/shred.c | 24 +++++----- src/lib/ugen.c | 4 +- src/lib/vec.c | 2 +- src/oo/nspc.c | 2 +- src/parse/scan1.c | 2 +- src/vm/shreduler.c | 70 +++++++++++++++-------------- src/vm/vm.c | 31 ++++++------- src/vm/vm_shred.c | 54 ++++++++++++----------- tests/import/Makefile | 36 +++++++++++++++ tests/import/array.c | 25 +++++++++++ tests/import/begin_class.c | 18 ++++++++ tests/import/callback.c | 80 ++++++++++++++++++++++++++++++++++ tests/import/callback.gwold | 16 +++++++ tests/import/callback2.gw | 15 +++++++ tests/import/class_template.c | 47 ++++++++++++++++++++ tests/import/class_template.gw | 15 +++++++ tests/import/coverage.c | 63 ++++++++++++++++++++++++++ tests/import/coverage.gw | 20 +++++++++ tests/import/end_class.c | 16 +++++++ tests/import/enum.c | 69 +++++++++++++++++++++++++++++ tests/import/enum.gw | 48 ++++++++++++++++++++ tests/import/extend_array.c | 23 ++++++++++ tests/import/extend_array.gw | 3 ++ tests/import/extend_event.c | 22 ++++++++++ tests/import/extend_event.gw | 2 + tests/import/extend_pair.c | 28 ++++++++++++ tests/import/extend_pair.gw | 4 ++ tests/import/global_func.c | 22 ++++++++++ tests/import/global_func.gw | 3 ++ tests/import/global_var.c | 18 ++++++++ tests/import/global_var.gw | 1 + tests/import/invalid_arg.c | 23 ++++++++++ tests/import/invalid_array.c | 37 ++++++++++++++++ tests/import/invalid_func.c | 22 ++++++++++ tests/import/invalid_type1.c | 21 +++++++++ tests/import/invalid_type2.c | 21 +++++++++ tests/import/invalid_type3.c | 22 ++++++++++ tests/import/map2.gw | 5 +++ tests/import/no_import.c | 12 +++++ tests/import/op_err.c | 17 ++++++++ tests/import/static_string.c | 17 ++++++++ tests/import/static_string.gw | 2 + tests/import/template_arg.c | 22 ++++++++++ tests/import/typedef.c | 27 ++++++++++++ tests/import/typedef.gw | 13 ++++++ tests/import/union.c | 17 ++++++++ tests/import/union.gw | 8 ++++ tests/import/variadic.c | 49 +++++++++++++++++++++ tests/import/variadic.gw | 13 ++++++ 56 files changed, 1077 insertions(+), 113 deletions(-) create mode 100644 tests/import/Makefile create mode 100644 tests/import/array.c create mode 100644 tests/import/begin_class.c create mode 100644 tests/import/callback.c create mode 100644 tests/import/callback.gwold create mode 100644 tests/import/callback2.gw create mode 100644 tests/import/class_template.c create mode 100644 tests/import/class_template.gw create mode 100644 tests/import/coverage.c create mode 100644 tests/import/coverage.gw create mode 100644 tests/import/end_class.c create mode 100644 tests/import/enum.c create mode 100644 tests/import/enum.gw create mode 100644 tests/import/extend_array.c create mode 100644 tests/import/extend_array.gw create mode 100644 tests/import/extend_event.c create mode 100644 tests/import/extend_event.gw create mode 100644 tests/import/extend_pair.c create mode 100644 tests/import/extend_pair.gw create mode 100644 tests/import/global_func.c create mode 100644 tests/import/global_func.gw create mode 100644 tests/import/global_var.c create mode 100644 tests/import/global_var.gw create mode 100644 tests/import/invalid_arg.c create mode 100644 tests/import/invalid_array.c create mode 100644 tests/import/invalid_func.c create mode 100644 tests/import/invalid_type1.c create mode 100644 tests/import/invalid_type2.c create mode 100644 tests/import/invalid_type3.c create mode 100644 tests/import/map2.gw create mode 100644 tests/import/no_import.c create mode 100644 tests/import/op_err.c create mode 100644 tests/import/static_string.c create mode 100644 tests/import/static_string.gw create mode 100644 tests/import/template_arg.c create mode 100644 tests/import/typedef.c create mode 100644 tests/import/typedef.gw create mode 100644 tests/import/union.c create mode 100644 tests/import/union.gw create mode 100644 tests/import/variadic.c create mode 100644 tests/import/variadic.gw diff --git a/include/shreduler_private.h b/include/shreduler_private.h index f5bd37d19..d6d4ad1f5 100644 --- a/include/shreduler_private.h +++ b/include/shreduler_private.h @@ -2,8 +2,8 @@ #define __SHREDULER struct Shreduler_ { VM* vm; - VM_Shred list; - VM_Shred curr; + struct ShredTick_ *list; + struct ShredTick_ *curr; struct Vector_ shreds; size_t shred_ids; m_bool loop; diff --git a/include/vm.h b/include/vm.h index 16e24d5fe..d8a4c8741 100644 --- a/include/vm.h +++ b/include/vm.h @@ -35,6 +35,24 @@ typedef struct VM_ { } VM; typedef struct VM_Shred_* VM_Shred; + +struct ShredInfo_ { + VM* vm; + struct M_Object_* me; + m_str name; + Vector args; +}; + +struct ShredTick_ { + VM_Shred self; + struct ShredTick_ *prev; + struct ShredTick_ *next; + struct ShredTick_ *parent; + struct Vector_ child; + size_t xid; + m_float wake_time; +}; + struct VM_Shred_ { VM_Code code; m_bit* reg; @@ -42,15 +60,8 @@ struct VM_Shred_ { m_bit* base; size_t pc; struct Vector_ gc; - m_bit* _reg; - VM_Shred prev, next, parent; - m_str name; - VM* vm; - Vector args; // passed pointer from compile - struct M_Object_* me; - struct Vector_ child; - size_t xid; - m_float wake_time; + struct ShredTick_ * tick; + struct ShredInfo_ * info; }; ANN2(4) ANEW VM_Code new_vm_code(const Vector instr, const m_uint stack_depth, const ae_flag, const m_str name); @@ -62,7 +73,7 @@ ANN void shreduler_add(const Shreduler s, const VM_Shred shred); ANEW ANN VM_Shred new_vm_shred(const VM_Code code) __attribute__((hot)); __attribute__((hot)) -ANN static inline void vm_shred_exit(const VM_Shred shred) { shreduler_remove(shred->vm->shreduler, shred, 1); } +ANN static inline void vm_shred_exit(const VM_Shred shred) { shreduler_remove(shred->info->vm->shreduler, shred, 1); } void free_vm_shred(const VM_Shred shred)__attribute__((hot, nonnull)); ANN void vm_run(const VM* vm) __attribute__((hot)); diff --git a/src/compile.c b/src/compile.c index 14f7f5bd4..5e3b1fba1 100644 --- a/src/compile.c +++ b/src/compile.c @@ -74,7 +74,7 @@ static m_uint compile(struct Gwion_* gwion, struct Compiler* c) { gw_err("while compiling file '%s'\n", c->base); else { const VM_Shred shred = new_vm_shred(code); - shred->args = c->args; + shred->info->args = c->args; xid = vm_add_shred(gwion->vm, shred); } compiler_clean(c); diff --git a/src/lib/array.c b/src/lib/array.c index 56ffc1a45..e38aa100a 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -324,7 +324,7 @@ INSTR(ArrayAlloc) { GWDEBUG_EXE aai.data = init_array(shred, info, &num_obj); const M_Object ref = do_alloc_array(shred, &aai); if(!ref) { - gw_err("[Gwion](VM): (note: in shred[id=%" UINT_F ":%s])\n", shred->xid, shred->name); + gw_err("[Gwion](VM): (note: in shred[id=%" UINT_F ":%s])\n", shred->tick->xid, shred->info->name); vm_shred_exit(shred); return; // TODO make exception vararg } diff --git a/src/lib/event.c b/src/lib/event.c index eaa1415b2..832f01b67 100644 --- a/src/lib/event.c +++ b/src/lib/event.c @@ -21,7 +21,7 @@ static INSTR(EventWait) { GWDEBUG_EXE const M_Object event = *(M_Object*)REG(-SZ_INT); if(!event) Except(shred, "NullEventWait"); - shreduler_remove(shred->vm->shreduler, shred, 0); + shreduler_remove(shred->info->vm->shreduler, shred, 0); const Vector v = EV_SHREDS(event); vector_add(v, (vtype)shred); *(m_int*)REG(-SZ_INT) = 1; @@ -32,7 +32,7 @@ static MFUN(event_signal) { const Vector v = EV_SHREDS(o); const VM_Shred sh = (VM_Shred)vector_front(v); if(sh) { - shredule(shred->vm->shreduler, sh, .5); + shredule(shred->info->vm->shreduler, sh, .5); vector_rem(v, 0); } } @@ -40,7 +40,7 @@ static MFUN(event_signal) { ANN void broadcast(const M_Object o) { for(m_uint i = 0; i < vector_size(EV_SHREDS(o)); i++) { const VM_Shred sh = (VM_Shred)vector_at(EV_SHREDS(o), i); - shredule(sh->vm->shreduler, sh, .5); + shredule(sh->info->vm->shreduler, sh, .5); } vector_clear(EV_SHREDS(o)); } diff --git a/src/lib/instr.c b/src/lib/instr.c index 8c928f867..4ee856b7c 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -22,13 +22,13 @@ INSTR(DTOR_EOC) { GWDEBUG_EXE o->type_ref = o->type_ref->parent; o->ref = 1; _release(o, shred); - _release(shred->me, shred); + _release(shred->info->me, shred); vm_shred_exit(shred); } INSTR(EOC2) { GWDEBUG_EXE shred->pc = 0; - shreduler_remove(shred->vm->shreduler, shred, 0); + shreduler_remove(shred->info->vm->shreduler, shred, 0); } /* branching */ @@ -144,7 +144,7 @@ INSTR(DotTmpl) { const Func f = nspc_lookup_func1(t->nspc, insert_symbol(str)); if(f) { if(!f->code) { - const Emitter emit = shred->vm->gwion->emit; + const Emitter emit = shred->info->vm->gwion->emit; emit->env->name = "runtime"; const Value v = f->value_ref; m_str start = strchr(name, '<'); @@ -172,7 +172,7 @@ f->def->func->code->stack_depth -= SZ_INT; shred->reg += SZ_INT; return; } else { - const Emitter emit = shred->vm->gwion->emit; + const Emitter emit = shred->info->vm->gwion->emit; emit->env->name = "runtime"; //m_str start = strchr(name, '<'); m_str start = name; diff --git a/src/lib/object.c b/src/lib/object.c index 7620acf19..1094b0030 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -15,7 +15,7 @@ ANN void exception(const VM_Shred shred, const m_str c) { err_msg(0, "%s: shred[id=%" UINT_F ":%s], PC=[%" UINT_F "]", - c, shred->xid, shred->name, shred->pc - 1); + c, shred->tick->xid, shred->info->name, shred->pc - 1); vm_shred_exit(shred); } @@ -63,8 +63,8 @@ ANN static void handle_dtor(const M_Object object, const VM_Shred shred) { *(M_Object*)sh->mem = object; sh->mem += SZ_INT; *(M_Object*)sh->mem = object; - vm_add_shred(shred->vm, sh); - ++sh->me->ref; + vm_add_shred(shred->info->vm, sh); + ++sh->info->me->ref; } __attribute__((hot)) diff --git a/src/lib/shred.c b/src/lib/shred.c index 2f7bdd17f..ba7225e3e 100644 --- a/src/lib/shred.c +++ b/src/lib/shred.c @@ -23,12 +23,12 @@ static MFUN(gw_shred_exit) { static MFUN(vm_shred_id) { const VM_Shred s = ME(o); - *(m_int*)RETURN = s ? (m_int)s->xid : -1; + *(m_int*)RETURN = s ? (m_int)s->tick->xid : -1; } static MFUN(vm_shred_is_running) { const VM_Shred s = ME(o); - *(m_uint*)RETURN = (s->next || s->prev) ? 1 : 0; + *(m_uint*)RETURN = (s->tick->next || s->tick->prev) ? 1 : 0; } static MFUN(vm_shred_is_done) { @@ -37,31 +37,33 @@ static MFUN(vm_shred_is_done) { static MFUN(shred_yield) { const VM_Shred s = ME(o); - const Shreduler sh = shred->vm->shreduler; + const Shreduler sh = shred->info->vm->shreduler; shredule(sh, s, .5); +// shred->mem += (m_bit*)o - shred->mem; +// shred->mem -= SZ_INT;//!!! } #include "shreduler_private.h" static SFUN(vm_shred_from_id) { const m_int index = *(m_int*)MEM(0); - const VM_Shred s = (VM_Shred)vector_at(&shred->vm->shreduler->shreds, (vtype)index); + const VM_Shred s = (VM_Shred)vector_at(&shred->info->vm->shreduler->shreds, (vtype)index); if(s) { - *(M_Object*)RETURN = s->me; - s->me->ref++; - vector_add(&shred->gc, (vtype) s->me); + *(M_Object*)RETURN = s->info->me; + s->info->me->ref++; + vector_add(&shred->gc, (vtype) s->info->me); } else *(m_uint*)RETURN = 0; } static MFUN(shred_args) { const VM_Shred s = ME(o); - *(m_uint*)RETURN = s->args ? vector_size(s->args) : 0; + *(m_uint*)RETURN = s->info->args ? vector_size(s->info->args) : 0; } static MFUN(shred_arg) { const VM_Shred s = ME(o); const m_int idx = *(m_int*)MEM(SZ_INT); - if(s->args && idx >= 0) { - const m_str str = (m_str)vector_at(s->args, *(m_uint*)MEM(SZ_INT)); + if(s->info->args && idx >= 0) { + const m_str str = (m_str)vector_at(s->info->args, *(m_uint*)MEM(SZ_INT)); *(M_Object*)RETURN = str ? new_string(shred, str) : NULL; } else *(m_uint*)RETURN = 0; @@ -81,7 +83,7 @@ static MFUN(shred##name##_dir) { \ strcpy(c, str); \ *(m_uint*)RETURN = (m_uint)new_string(shred, dirname(c)); \ } -describe_path_and_dir(, s->name) +describe_path_and_dir(, s->info->name) describe_path_and_dir(_code, s->code->name) GWION_IMPORT(shred) { diff --git a/src/lib/ugen.c b/src/lib/ugen.c index 9ca5ea819..8e84e1b2b 100644 --- a/src/lib/ugen.c +++ b/src/lib/ugen.c @@ -203,7 +203,7 @@ describe_connect_instr(Trig, Disconnect, TRIG_EX) static CTOR(ugen_ctor) { UGEN(o) = new_UGen(); - vector_add(&shred->vm->ugen, (vtype)UGEN(o)); + vector_add(&shred->info->vm->ugen, (vtype)UGEN(o)); } #define describe_release_func(src, tgt, opt) \ @@ -231,7 +231,7 @@ ANN static void release_multi(const UGen ug, const VM_Shred shred) { static DTOR(ugen_dtor) { const UGen ug = UGEN(o); - vector_rem2(&shred->vm->ugen, (vtype)ug); + vector_rem2(&shred->info->vm->ugen, (vtype)ug); if(!ug->multi) release_mono(ug); else diff --git a/src/lib/vec.c b/src/lib/vec.c index 59dcba4ed..1a5503ea0 100644 --- a/src/lib/vec.c +++ b/src/lib/vec.c @@ -61,7 +61,7 @@ static MFUN(vec3_##name) { \ } describe_vec3_x(interp, + v->x) describe_vec3_x(float, * v->z * (*(m_float*)MEM(SZ_INT)) + v->x) -describe_vec3_x(dur, * (*(m_float*)MEM(SZ_INT) / (m_float)shred->vm->bbq->sr) + v->x) +describe_vec3_x(dur, * (*(m_float*)MEM(SZ_INT) / (m_float)shred->info->vm->bbq->sr) + v->x) static MFUN(vec3_update) { m_vec3* v = *(m_vec3**)MEM(0); diff --git a/src/oo/nspc.c b/src/oo/nspc.c index bea7357ea..3ff54f1b1 100644 --- a/src/oo/nspc.c +++ b/src/oo/nspc.c @@ -25,7 +25,7 @@ ANN static void nspc_release_object(const Nspc a, Value value) { const VM_Shred s = new_vm_shred(code); const M_Object obj = value->d.ptr ? (M_Object)value->d.ptr : *(M_Object*)(a->class_data + value->offset); - s->vm = value->gwion->vm; + s->info->vm = value->gwion->vm; release(obj, s); free_vm_shred(s); } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 57fc2bfe3..166fe4463 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -297,7 +297,7 @@ ANN static m_bool scan1_class_parent(const Env env, const Class_Def class_def) { const Type parent = class_def->type->parent = known_type(env, class_def->ext); CHECK_OB(parent) if(parent == class_def->type) - ERR_B(class_def->ext->xid->pos, "class '%s' cannot extend itself", + ERR_B(class_def->ext->xid->pos, "class '%s' cannot extend itself", class_def->type->name); if(isa(class_def->type->parent, t_object) < 0) ERR_B(class_def->ext->xid->pos, "cannot extend primitive type '%s'", diff --git a/src/vm/shreduler.c b/src/vm/shreduler.c index 3d369016c..ea3ecde1c 100644 --- a/src/vm/shreduler.c +++ b/src/vm/shreduler.c @@ -12,18 +12,19 @@ ANN void shreduler_set_loop(const Shreduler s, const m_bool loop) { ANN VM_Shred shreduler_get(const Shreduler s) { VM* vm = s->vm; - const VM_Shred shred = s->list; - if(!shred) { + struct ShredTick_ *tk = s->list; + if(!tk) { if(!vector_size(&s->shreds) && !s->loop) vm->is_running = 0; return NULL; } const m_float time = (m_float)vm->bbq->pos + (m_float).5; - if(shred->wake_time <= time) { - if((s->list = shred->next)) + if(tk->wake_time <= time) { + if((s->list = tk->next)) s->list->prev = NULL; - shred->next = shred->prev = NULL; - return s->curr = shred; + tk->next = tk->prev = NULL; + s->curr = tk; + return tk->self; } return NULL; } @@ -32,7 +33,7 @@ ANN static void shreduler_parent(const VM_Shred out, const Vector v) { vector_rem2(v, (vtype)out); if(!vector_size(v)) { vector_release(v); - out->parent->child.ptr = NULL; + out->tick->parent->child.ptr = NULL; } } @@ -43,56 +44,59 @@ ANN static void shreduler_child(const Shreduler s, const Vector v) { } } -ANN static void shreduler_erase(const Shreduler s, const VM_Shred out) { - if(out->parent) - shreduler_parent(out, &out->parent->child); - if(out->child.ptr) - shreduler_child(s, &out->child); - vector_rem2(&s->shreds, (vtype)out); +ANN static void shreduler_erase(const Shreduler s, struct ShredTick_ *tk) { + if(tk->parent) + shreduler_parent(tk->self, &tk->parent->child); + if(tk->child.ptr) + shreduler_child(s, &tk->child); + vector_rem2(&s->shreds, (vtype)tk->self); } ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const m_bool erase) { - if(s->curr == out) + struct ShredTick_ *tk = out->tick; + assert(tk); + if(tk == s->curr) s->curr = NULL; - else if(out == s->list) - s->list = out->next; - if(out->prev) - out->prev->next = out->next; - if(out->next) - out->next->prev = out->prev; - out->prev = out->next = NULL; + else if(tk == s->list) + s->list = tk->next; + if(tk->prev) + tk->prev->next = tk->next; + if(tk->next) + tk->next->prev = tk->prev; + tk->prev = tk->next = NULL; if(erase) { - shreduler_erase(s, out); + shreduler_erase(s, tk); free_vm_shred(out); } } ANN void shredule(const Shreduler s, const VM_Shred shred, const m_float wake_time) { const m_float time = wake_time + (m_float)s->vm->bbq->pos; - shred->wake_time = time; + struct ShredTick_ *tk = shred->tick; + tk->wake_time = time; if(s->list) { - VM_Shred curr = s->list, prev = NULL; + struct ShredTick_ *curr = s->list, *prev = NULL; do { if(curr->wake_time > time) break; prev = curr; } while((curr = curr->next)); if(!prev) { - shred->next = s->list; - s->list = (s->list->prev = shred); + tk->next = s->list; + s->list = (s->list->prev = tk); } else { - if((shred->next = prev->next)) - prev->next->prev = shred; - shred->prev = prev; - prev->next = shred; + if((tk->next = prev->next)) + prev->next->prev = tk; + tk->prev = prev; + prev->next = tk; } } else - s->list = shred; - if(s->curr == shred) + s->list = tk; + if(tk == s->curr) s->curr = NULL; } ANN void shreduler_add(const Shreduler s, const VM_Shred shred) { - shred->xid = ++s->shred_ids; + shred->tick->xid = ++s->shred_ids; vector_add(&s->shreds, (vtype)shred); } diff --git a/src/vm/vm.c b/src/vm/vm.c index a9959861c..b51f6a632 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -62,7 +62,7 @@ void vm_remove(const VM* vm, const m_uint index) { LOOP_OPTIM for(m_uint i = vector_size(v) + 1; i--;) { const VM_Shred sh = (VM_Shred)vector_at(v, i - 1); - if(sh->xid == index) + if(sh->tick->xid == index) Except(sh, "MsgRemove"); } } @@ -78,11 +78,11 @@ ANN void free_vm(VM* vm) { } ANN m_uint vm_add_shred(const VM* vm, const VM_Shred shred) { - shred->vm = (VM*)vm; - shred->me = new_shred(shred); + shred->info->vm = (VM*)vm; + shred->info->me = new_shred(shred); shreduler_add(vm->shreduler, shred); shredule(vm->shreduler, shred, .5); - return shred->xid; + return shred->tick->xid; } __attribute__((hot)) @@ -106,8 +106,9 @@ ANN static inline void vm_ugen_init(const VM* vm) { #ifdef DEBUG_STACK #define VM_INFO \ if(s->curr) \ - gw_err("shred[%" UINT_F "] mem[%" INT_F"] reg[%" INT_F"]\n", shred->xid, \ - mem - (shred->_reg + SIZEOF_REG), reg - shred->_reg); + gw_err("shred[%" UINT_F "] mem[%" INT_F"] reg[%" INT_F"]\n", \ + shred->tick->xid, \ + mem - ((m_bit*)shred + sizeof(struct VM_Shred_) + SIZEOF_REG), reg - (m_bit*)shred + sizeof(struct VM_Shred_)); #else #define VM_INFO #endif @@ -120,18 +121,18 @@ static struct timespec exec_time; ANN static inline m_bool overflow_(const m_bit* mem, const VM_Shred c) { - return mem > ((c->_reg + SIZEOF_REG) + (SIZEOF_MEM) - (MEM_STEP)); + return mem > (((m_bit*)c + sizeof(struct VM_Shred_) + SIZEOF_REG) + (SIZEOF_MEM) - (MEM_STEP)); } ANN static inline VM_Shred init_spork_shred(const VM_Shred shred, const VM_Code code) { const VM_Shred sh = new_vm_shred(code); ADD_REF(code) - sh->parent = shred; - if(!shred->child.ptr) - vector_init(&shred->child); - vector_add(&shred->child, (vtype)sh); + sh->tick->parent = shred->tick; + if(!shred->tick->child.ptr) + vector_init(&shred->tick->child); + vector_add(&shred->tick->child, (vtype)sh); sh->base = shred->base; - vm_add_shred(shred->vm, sh); + vm_add_shred(shred->info->vm, sh); return sh; } @@ -368,7 +369,7 @@ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini); *(m_uint*)(reg-SZ_INT) = instr->m_val; DISPATCH() regpushme: - *(M_Object*)reg = shred->me; + *(M_Object*)reg = shred->info->me; reg += SZ_INT; DISPATCH() regpushmaybe: @@ -541,7 +542,7 @@ firdiv: FI_R(/) reg -= SZ_FLOAT; { register const m_float f = *(m_float*)(reg-SZ_FLOAT); - *(m_float*)(reg-SZ_FLOAT) = (shred->wake_time += f); + *(m_float*)(reg-SZ_FLOAT) = (shred->tick->wake_time += f); shredule(s, shred, f); } shred->code = code; @@ -656,7 +657,7 @@ DISPATCH(); *(m_uint*)(a.child->mem + i) = *(m_uint*)(mem+i); DISPATCH() sporkend: - *(M_Object*)(reg-SZ_INT) = a.child->me; + *(M_Object*)(reg-SZ_INT) = a.child->info->me; DISPATCH() funcptr: if(!GET_FLAG((VM_Code)a.code, builtin)) diff --git a/src/vm/vm_shred.c b/src/vm/vm_shred.c index 9325400e5..48b17473a 100644 --- a/src/vm/vm_shred.c +++ b/src/vm/vm_shred.c @@ -10,44 +10,48 @@ #include "object.h" struct Stack_ { -// VM_Shred shred; + VM_Shred shred; char c[SIZEOF_REG]; char d[SIZEOF_MEM]; }; +static inline struct ShredInfo_ *new_shredinfo(const m_str name) { + struct ShredInfo_ *info = mp_alloc(ShredInfo); + info->name = strdup(name); + return info; +} + +static inline void free_shredinfo(struct ShredInfo_ *info, const VM_Shred shred) { + free(info->name); + release(info->me, shred); + if(info->args) { + const Vector v = info->args; + LOOP_OPTIM + for(m_uint i = vector_size(v) + 1; --i;) + free((void*)vector_at(v, i - 1)); + free_vector(v); + } + mp_free(ShredInfo, info); +} + VM_Shred new_vm_shred(VM_Code c) { - const VM_Shred shred = mp_alloc(VM_Shred); - shred->_reg = mp_alloc(Stack); -// const VM_Shred shred = mp_alloc(Stack); -// shred->reg = (m_bit*)shred + sizeof(struct VM_Shred_); - shred->mem = shred->_reg + SIZEOF_REG; - shred->reg = shred->_reg; - shred->base = shred->mem; -// shred->_mem = shred->base; + const VM_Shred shred = mp_alloc(Stack); shred->code = c; - shred->name = strdup(c->name); + shred->reg = (m_bit*)shred + sizeof(struct VM_Shred_); + shred->base = shred->mem = shred->reg + SIZEOF_REG; + shred->tick = mp_alloc(ShredTick); + shred->tick->self = shred; + shred->info = new_shredinfo(c->name); vector_init(&shred->gc); return shred; } -static void vm_shred_free_args(Vector v) { - LOOP_OPTIM - for(m_uint i = vector_size(v) + 1; --i;) - free((void*)vector_at(v, i - 1)); - free_vector(v); -} - void free_vm_shred(VM_Shred shred) { for(m_uint i = vector_size(&shred->gc) + 1; --i;) release((M_Object)vector_at(&shred->gc, i - 1), shred); vector_release(&shred->gc); - release(shred->me, shred); - mp_free(Stack, shred->_reg); -// mp_free(Stack, shred->mem); REM_REF(shred->code); - free(shred->name); - if(shred->args) - vm_shred_free_args(shred->args); - mp_free(VM_Shred, shred); -// mp_free(Stack, shred); + mp_free(ShredTick, shred->tick); + free_shredinfo(shred->info, shred); + mp_free(Stack, shred); } diff --git a/tests/import/Makefile b/tests/import/Makefile new file mode 100644 index 000000000..6a5949fbb --- /dev/null +++ b/tests/import/Makefile @@ -0,0 +1,36 @@ +INC = -I../../include -I../../util/include -I../../ast/include +CC ?= gcc + +SRC = ${NAME}.c +OBJ = $(SRC:.c=.o) +CFLAGS = $(../../gwion -C 2>&1 | grep CFLAGS) ${INC} +LDFLAGS = $(../../gwion -C 2>&1 | grep LDFLAGS) + +# os specific +ifeq ($(shell uname), Linux) +LDFLAGS += -shared +else +LDFLAGS += -bundle -undefined dynamic_lookup +endif + +all: ${NAME}.so + + +${NAME}.so: ${OBJ} +ifeq (${USE_LD}, 1) + ${LD} $^ -o ${NAME}.so ${LDFLAGS} +else + ${CC} $^ -o ${NAME}.so ${LDFLAGS} +endif + +clean: + rm -f ${OBJ} ${NAME}.so + +.c.o: + ${CC} -fPIC ${CFLAGS} -c $< -o $(<:.c=.o) -g + +install: ${NAME}.so + install ${NAME}.so ${GWION_ADD_DIR} + +uninstall: + rm ${GWION_ADD_DIR}/${NAME}.so diff --git a/tests/import/array.c b/tests/import/array.c new file mode 100644 index 000000000..a256dda60 --- /dev/null +++ b/tests/import/array.c @@ -0,0 +1,25 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +MFUN(test_mfun){} + +GWION_IMPORT(array_test) { + Type t_invalid_var_name; + CHECK_BB((t_invalid_var_name = gwi_mk_type(gwi, "invalid_var_name", SZ_INT, t_object))) + CHECK_BB(gwi_class_ini(gwi, t_invalid_var_name, NULL, NULL)) + CHECK_BB(gwi_item_ini(gwi,"int[]", "int_array")) + CHECK_BB(gwi_item_end(gwi, 0, NULL)) // import array var + CHECK_BB(gwi_func_ini(gwi, "float[][]", "f", test_mfun)) + CHECK_BB(gwi_func_end(gwi, 0)) + CHECK_BB(gwi_func_ini(gwi, "float[][]", "g", test_mfun)) + CHECK_BB(gwi_func_end(gwi, 0)) + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/begin_class.c b/tests/import/begin_class.c new file mode 100644 index 000000000..e521b2ce7 --- /dev/null +++ b/tests/import/begin_class.c @@ -0,0 +1,18 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +MFUN(test_mfun){} +GWION_IMPORT(begin_class) { + Type t_invalid_var_name; + CHECK_OB((t_invalid_var_name = gwi_mk_type(gwi, "invalid_var_name", SZ_INT, t_object))) + CHECK_BB(gwi_class_ini(gwi, t_invalid_var_name, NULL, NULL)) + CHECK_BB(gwi_class_ini(gwi, t_invalid_var_name, NULL, NULL)) + return GW_OK; +} diff --git a/tests/import/callback.c b/tests/import/callback.c new file mode 100644 index 000000000..9faa39c15 --- /dev/null +++ b/tests/import/callback.c @@ -0,0 +1,80 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "instr.h" +#include "object.h" +#include "instr.h" +#include "import.h" +#include "func.h" + +struct ret_info { + Instr instr; + VM_Code code; + m_uint offset; + m_uint size; + size_t pc; +}; + +static INSTR(my_ret) { GWDEBUG_EXE + struct ret_info* info = (struct ret_info*)instr->m_val; + POP_MEM(shred, info->offset); + vector_set(shred->code->instr, shred->pc, (vtype)info->instr); + shred->code = info->code; +//*(VM_Code*)instr->ptr; + POP_REG(shred, info->size) + if(shred->mem == (m_bit*)shred + sizeof(struct VM_Shred_) + SIZEOF_REG) + POP_REG(shred, SZ_INT) + POP_REG(shred, shred->code->stack_depth); +// shred->pc = instr->m_val2; + shred->pc = info->pc; + free(info); + *(m_int*)shred->reg = 2; + PUSH_REG(shred, SZ_INT); +} + +static SFUN(cb_func) { + m_uint i; + Func f = *(Func*)MEM(0); + if(!f){ + Except(shred, "NullCallbackException"); + } + m_uint offset = shred->mem - ((m_bit*)shred + sizeof(struct VM_Shred_) + SIZEOF_REG); + PUSH_MEM(shred, offset); + Instr instr = mp_alloc(Instr); + struct ret_info* info = (struct ret_info*)xmalloc(sizeof(struct ret_info)); + info->offset = offset; + info->code = shred->code; + info->size = f->def->ret_type->size; + info->pc = shred->pc; + instr->execute = my_ret; +// *(VM_Code*)instr->ptr = shred->code; + instr->m_val = (m_uint)info; +// instr->m_val2 = shred->pc; + for(i = 0; i < vector_size(f->code->instr); i++) { + Instr in = (Instr)vector_at(f->code->instr, i); + if(in->execute == FuncReturn || + in->execute == my_ret) { + info->instr = in; + vector_set(f->code->instr, i, (vtype)instr); + } + } + *(m_int*)RETURN = 1; + shred->pc = 0; + shred->code = f->code; +} + +GWION_IMPORT(callback) { + CHECK_BB(gwi_fptr_ini(gwi, "Vec4", "PtrType")) + CHECK_BB(gwi_fptr_end(gwi, 0)) + + const Type t_callback = gwi_mk_type(gwi, "Callback", SZ_INT, t_object); + CHECK_BB(gwi_class_ini(gwi, t_callback, NULL, NULL)) + CHECK_BB(gwi_func_ini(gwi, "int", "callback", cb_func)) + CHECK_BB(gwi_func_arg(gwi, "PtrType", "func")) + CHECK_BB(gwi_func_end(gwi, ae_flag_static)) + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/callback.gwold b/tests/import/callback.gwold new file mode 100644 index 000000000..d13976067 --- /dev/null +++ b/tests/import/callback.gwold @@ -0,0 +1,16 @@ +int i; +int j; +int K; +fun Vec4 test() { <<<"test">>>; } +fun void test2(PtrType t) { Callback.callback(t); } + +test @=> PtrType t; +<<>>; +<<>>; +<<>>; +Callback.callback(t); +test2(t); +test2(t); +spork ~test2(t); +spork ~Callback.callback(t); +me.yield(); diff --git a/tests/import/callback2.gw b/tests/import/callback2.gw new file mode 100644 index 000000000..c9f0668d1 --- /dev/null +++ b/tests/import/callback2.gw @@ -0,0 +1,15 @@ +fun Vec4 test(int i) { <<<"test with arg ", i>>>; } + +//typedef Vec4 PT(); +//test @=> +PtrTypeI p; +test @=> p; +//test @=> PT ti; +<<>>; +//<<>>; +<<

>>; +//ti(); +<<<"test">>>; +p(2); +<<<"end">>>; +Callback.callback(p, 6); diff --git a/tests/import/class_template.c b/tests/import/class_template.c new file mode 100644 index 000000000..0a6a26ded --- /dev/null +++ b/tests/import/class_template.c @@ -0,0 +1,47 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +static m_int o_map_key; +static m_int o_map_value; +#define MAP_KEY(a) *((M_Object*)(a->data + o_map_key)) +#define MAP_VAL(a) *((M_Object*)(a->data + o_map_value)) +static CTOR(class_template_ctor) { + /*char* name = strdup(o->type_ref->name);*/ + /*char* tmp = strsep(&name, "@");*/ + /*char* name1 = strsep(&name, "@");*/ +/*Type t1 = nspc_lookup_type1(o->type_ref->info->parent, insert_symbol(name1));*/ + /*Type t2 = nspc_lookup_type0(shred->vm->emit->env->curr, insert_symbol(name));*/ +/*free(tmp);*/ +/**(M_Object*)(o->data) = new_array(t1->size, 0, t1->array_depth);*/ + /**(M_Object*)(o->data + SZ_INT) = new_array(t2->size, 0, t2->array_depth);*/ +} + +static MFUN(class_template_set) { + +} + +GWION_IMPORT(class_template) { + Type t_class_template; + const m_str list[2] = { "A", "B" }; + gwi_tmpl_ini(gwi, 2, list); + CHECK_OB((t_class_template = gwi_mk_type(gwi, "ClassTemplate", SZ_INT, t_object))) + CHECK_BB(gwi_class_ini(gwi, t_class_template, class_template_ctor, NULL)) + gwi_tmpl_end(gwi); + CHECK_BB(gwi_item_ini(gwi, "A[]", "key")) + CHECK_BB((o_map_key = gwi_item_end(gwi, ae_flag_member | ae_flag_template, NULL))) + CHECK_BB(gwi_item_ini(gwi, "B[]", "value")) + CHECK_BB((o_map_value = gwi_item_end(gwi, ae_flag_member, NULL))) + + + /*gwi_func_ini(gwi, "B", "set", class_template_set);*/ + /*gwi_func_end(gwi, ae_flag_member);*/ + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/class_template.gw b/tests/import/class_template.gw new file mode 100644 index 000000000..245aca581 --- /dev/null +++ b/tests/import/class_template.gw @@ -0,0 +1,15 @@ +//class child {} +//template<~A, B~> +//class C{ A key; B value; } +//<~int, int~>C c1; +//C c2; +//<<>>; +//<<>>; +//<<>>; + +<~int, int~>ClassTemplate ct; +<<>>; +//ClassTemplate ct2; +//<<>>; +//ClassTemplate ct3; +//<<>>; diff --git a/tests/import/coverage.c b/tests/import/coverage.c new file mode 100644 index 000000000..8c629229e --- /dev/null +++ b/tests/import/coverage.c @@ -0,0 +1,63 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +SFUN(coverage_int) { *(m_uint*)RETURN = 0; } +SFUN(coverage_float) { *(m_float*)RETURN = 0; } +SFUN(coverage_complex) { *(m_complex*)RETURN = 0; } +SFUN(coverage_vec3) { m_vec3 v = {0,0,0}; *(m_vec3*)RETURN = v; } +SFUN(coverage_vec4) { m_vec4 v = {0,0,0,0}; *(m_vec4*)RETURN = v; } + +GWION_IMPORT(coverage) { + Type t_coverage; + CHECK_OB((t_coverage = gwi_mk_type(gwi, "Coverage", SZ_INT, t_object))) + CHECK_BB(gwi_class_ini(gwi, t_coverage, NULL, NULL)) + CHECK_BB(gwi_func_ini(gwi, "int", "i", coverage_int)) + CHECK_BB(gwi_func_end(gwi, ae_flag_static)) + CHECK_BB(gwi_func_ini(gwi, "float", "f", coverage_float)) + CHECK_BB(gwi_func_end(gwi, ae_flag_static)) + CHECK_BB(gwi_func_ini(gwi, "complex", "c", coverage_complex)) + CHECK_BB(gwi_func_end(gwi, ae_flag_static)) + CHECK_BB(gwi_func_ini(gwi, "Vec3", "v", coverage_vec3)) + CHECK_BB(gwi_func_end(gwi, ae_flag_static)) + CHECK_BB(gwi_func_ini(gwi, "Vec4", "w", coverage_vec4)) + CHECK_BB(gwi_func_end(gwi, ae_flag_static)) + + m_uint* i = (m_uint*)xmalloc(sizeof(m_uint)); + *i = 5; + CHECK_BB(gwi_item_ini(gwi,"int", "s_i")) + CHECK_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, i)) + m_float* f = (m_float*)xmalloc(sizeof(m_float)); + *f = 2.1; + CHECK_BB(gwi_item_ini(gwi,"float", "s_f")) + CHECK_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, (void*)f)) + + m_complex* c = (m_complex*)xmalloc(sizeof(m_complex)); + *c = 2.1; + CHECK_BB(gwi_item_ini(gwi,"complex", "s_c")) + CHECK_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, (void*)c)) + + m_vec3* v = (m_vec3*)xmalloc(sizeof(m_vec3)); + v->x = 2.1; + v->y = 2.2; + v->z = 2.3; + CHECK_BB(gwi_item_ini(gwi,"Vec3", "s_v")) + CHECK_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, (void*)v)) + + m_vec4* w = (m_vec4*)xmalloc(sizeof(m_vec4)); + w->x = 2.1; + w->y = 2.2; + w->z = 2.3; + w->w = 2.4; + CHECK_BB(gwi_item_ini(gwi,"Vec4", "s_w")) + CHECK_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, (void*)w)) + + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/coverage.gw b/tests/import/coverage.gw new file mode 100644 index 000000000..d616e424a --- /dev/null +++ b/tests/import/coverage.gw @@ -0,0 +1,20 @@ +float f; +Coverage c; +c.s_i; +<<< Coverage.i() >>>; +<<< Coverage.f() >>>; +<<< Coverage.c() >>>; +<<< Coverage.v() >>>; +<<< Coverage.w() >>>; + +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; + +<<< 1 => Coverage.s_i >>>; +<<< 1.2 => Coverage.s_f >>>; +<<< #(1.2, 0.1) => Coverage.s_c >>>; +<<< @(1.2, 0.1, 2.6) => Coverage.s_v >>>; +<<< @(1.2, 0.1, 2.6, 4.6) => Coverage.s_w >>>; diff --git a/tests/import/end_class.c b/tests/import/end_class.c new file mode 100644 index 000000000..8961e0344 --- /dev/null +++ b/tests/import/end_class.c @@ -0,0 +1,16 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "absyn.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "operator.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +MFUN(test_mfun){} +GWION_IMPORT(end_class) { + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/enum.c b/tests/import/enum.c new file mode 100644 index 000000000..032d7855f --- /dev/null +++ b/tests/import/enum.c @@ -0,0 +1,69 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +GWION_IMPORT(enum_test) { + CHECK_BB(gwi_enum_ini(gwi, NULL)) + CHECK_BB(gwi_enum_add(gwi, "ENUM0", 0)) + CHECK_BB(gwi_enum_add(gwi, "ENUM1", 1)) + CHECK_BB(gwi_enum_add(gwi, "ENUM2", 2)) + CHECK_BB(gwi_enum_add(gwi, "ENUM3", 3)) + CHECK_BB(gwi_enum_add(gwi, "ENUM4", 4)) + CHECK_BB(gwi_enum_add(gwi, "ENUM5", 5)) + CHECK_BB(gwi_enum_add(gwi, "ENUM6", 6)) + CHECK_BB(gwi_enum_add(gwi, "ENUM7", 7)) + CHECK_BB(gwi_enum_add(gwi, "ENUM8", 8)) + CHECK_BB(gwi_enum_add(gwi, "ENUM9", 9)) + CHECK_BB(gwi_enum_end(gwi)) + + CHECK_BB(gwi_enum_ini(gwi, "test")) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM0", 0)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM1", 1)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM2", 2)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM3", 3)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM4", 4)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM5", 5)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM6", 6)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM7", 7)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM8", 8)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM9", 9)) + CHECK_BB(gwi_enum_end(gwi)) + + Type t_enum; + CHECK_OB((t_enum = gwi_mk_type(gwi, "Enum", 0, NULL))) + CHECK_BB(gwi_class_ini(gwi, t_enum, NULL, NULL)) + CHECK_BB(gwi_enum_ini(gwi, 0)) + CHECK_BB(gwi_enum_add(gwi, "ENUM0", 0)) + CHECK_BB(gwi_enum_add(gwi, "ENUM1", 1)) + CHECK_BB(gwi_enum_add(gwi, "ENUM2", 2)) + CHECK_BB(gwi_enum_add(gwi, "ENUM3", 3)) + CHECK_BB(gwi_enum_add(gwi, "ENUM4", 4)) + CHECK_BB(gwi_enum_add(gwi, "ENUM5", 5)) + CHECK_BB(gwi_enum_add(gwi, "ENUM6", 6)) + CHECK_BB(gwi_enum_add(gwi, "ENUM7", 7)) + CHECK_BB(gwi_enum_add(gwi, "ENUM8", 8)) + CHECK_BB(gwi_enum_add(gwi, "ENUM9", 9)) + CHECK_BB(gwi_enum_end(gwi)) + + CHECK_BB(gwi_enum_ini(gwi, "Enumtest")) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM0", 0)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM1", 1)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM2", 2)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM3", 3)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM4", 4)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM5", 5)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM6", 6)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM7", 7)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM8", 8)) + CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM9", 9)) + CHECK_BB(gwi_enum_end(gwi)) + CHECK_BB(gwi_class_end(gwi)) + + return GW_OK; +} diff --git a/tests/import/enum.gw b/tests/import/enum.gw new file mode 100644 index 000000000..85666650c --- /dev/null +++ b/tests/import/enum.gw @@ -0,0 +1,48 @@ +// untyped global enum +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; + +// typed global enum +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; + +// in class +// untyped global enum +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; + +// Enum.typed global enum +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; +<<>>; diff --git a/tests/import/extend_array.c b/tests/import/extend_array.c new file mode 100644 index 000000000..6780257b2 --- /dev/null +++ b/tests/import/extend_array.c @@ -0,0 +1,23 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "instr.h" +#include "object.h" +#include "import.h" +#include "instr.h" + +GWION_IMPORT(extend_array_test) { + Type t_array_ext; + CHECK_OB((t_array_ext = gwi_mk_type(gwi, "ArrayExt", SZ_INT, NULL))) + CHECK_BB(gwi_class_ini(gwi, t_array_ext, NULL, NULL)) + Type_Decl* td = new_type_decl(new_id_list(insert_symbol("float"), 0), 0); + Exp e = new_exp_prim_int(1, 0); + Array_Sub array = new_array_sub(e); + add_type_decl_array(td, array); + CHECK_BB(gwi_class_ext(gwi, td)) + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/extend_array.gw b/tests/import/extend_array.gw new file mode 100644 index 000000000..a3aa97020 --- /dev/null +++ b/tests/import/extend_array.gw @@ -0,0 +1,3 @@ +ArrayExt a; +<<>>; +<<>>; diff --git a/tests/import/extend_event.c b/tests/import/extend_event.c new file mode 100644 index 000000000..92a8e9e68 --- /dev/null +++ b/tests/import/extend_event.c @@ -0,0 +1,22 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "instr.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +static CTOR(ev_ctor) { printf(" %p this to test ctor\n", (void*)o); } + +GWION_IMPORT(extend_event_test) { + Type t_ev ; + CHECK_OB((t_ev = gwi_mk_type(gwi, "Ev", SZ_INT , NULL))) + CHECK_BB(gwi_class_ini(gwi, t_ev, ev_ctor, NULL)) + Type_Decl* td = new_type_decl(new_id_list(insert_symbol("Event"), 0), 0); + CHECK_BB(gwi_class_ext(gwi, td)) + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/extend_event.gw b/tests/import/extend_event.gw new file mode 100644 index 000000000..b4c6647e9 --- /dev/null +++ b/tests/import/extend_event.gw @@ -0,0 +1,2 @@ +Ev ev; +<<>>; diff --git a/tests/import/extend_pair.c b/tests/import/extend_pair.c new file mode 100644 index 000000000..304a8d32a --- /dev/null +++ b/tests/import/extend_pair.c @@ -0,0 +1,28 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "instr.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +GWION_IMPORT(extend_pair_test) { + m_str types[] = { "A", "B" }; + Type t_pair_ext ; + CHECK_OB((t_pair_ext = gwi_mk_type(gwi, "PairExt", SZ_INT , NULL))) + CHECK_BB(gwi_tmpl_ini(gwi, 2, types)) + CHECK_BB(gwi_class_ini(gwi, t_pair_ext, NULL, NULL)) + CHECK_BB(gwi_tmpl_end(gwi)) + Type_Decl* td = new_type_decl(new_id_list(insert_symbol("Pair"), 0), 0); + Type_Decl* td0 = new_type_decl(new_id_list(insert_symbol("A"), 0), 0); + Type_Decl* td1 = new_type_decl(new_id_list(insert_symbol("B"), 0), 0); + Type_List tl1 = new_type_list(td1, NULL); + Type_List tl0 = new_type_list(td0, tl1); + td->types = tl0; + CHECK_BB(gwi_class_ext(gwi, td)) + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/extend_pair.gw b/tests/import/extend_pair.gw new file mode 100644 index 000000000..f32763dc8 --- /dev/null +++ b/tests/import/extend_pair.gw @@ -0,0 +1,4 @@ +<~int, int~>PairExt p; +<<

>>; +<<>>; +<<>>; diff --git a/tests/import/global_func.c b/tests/import/global_func.c new file mode 100644 index 000000000..8bfcbc395 --- /dev/null +++ b/tests/import/global_func.c @@ -0,0 +1,22 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "instr.h" +#include "object.h" +#include "import.h" +#include "instr.h" + +SFUN(coverage_int) { + puts("test"); + *(m_int*)RETURN = *(m_int*)MEM(0); +} + +GWION_IMPORT(global_func_test) { + CHECK_BB(gwi_func_ini(gwi, "int", "test", coverage_int)) + CHECK_BB(gwi_func_arg(gwi, "int", "i")) + CHECK_BB(gwi_func_end(gwi, 0)) + return GW_OK; +} diff --git a/tests/import/global_func.gw b/tests/import/global_func.gw new file mode 100644 index 000000000..4fa22811f --- /dev/null +++ b/tests/import/global_func.gw @@ -0,0 +1,3 @@ +<<>>; +<<<1 => test>>>; + diff --git a/tests/import/global_var.c b/tests/import/global_var.c new file mode 100644 index 000000000..3f46664dd --- /dev/null +++ b/tests/import/global_var.c @@ -0,0 +1,18 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + + +GWION_IMPORT(global_var_test) { +// ALLOC_PTR(i, m_uint, 1); + M_Object i = new_string(NULL, "test"); + CHECK_BB(gwi_item_ini(gwi,"string", "i")) + CHECK_BB(gwi_item_end(gwi, 0, i)) + return GW_OK; +} diff --git a/tests/import/global_var.gw b/tests/import/global_var.gw new file mode 100644 index 000000000..a4041bca7 --- /dev/null +++ b/tests/import/global_var.gw @@ -0,0 +1 @@ +<<>>; diff --git a/tests/import/invalid_arg.c b/tests/import/invalid_arg.c new file mode 100644 index 000000000..b8178300e --- /dev/null +++ b/tests/import/invalid_arg.c @@ -0,0 +1,23 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +static MFUN(test_mfun){} +GWION_IMPORT(invalid_arg_test) { + Type t_invalid_var_type ; + CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type", + SZ_INT , NULL))) + CHECK_BB(gwi_class_ini(gwi, t_invalid_var_type, NULL, NULL)) + CHECK_BB(gwi_func_ini(gwi, "int[]", "func", test_mfun)) + CHECK_BB(gwi_func_arg(gwi, ".int", "i")) + CHECK_BB(gwi_func_end(gwi, ae_flag_static)) + + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/invalid_array.c b/tests/import/invalid_array.c new file mode 100644 index 000000000..348808689 --- /dev/null +++ b/tests/import/invalid_array.c @@ -0,0 +1,37 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +static MFUN(test_mfun){} +GWION_IMPORT(inalid_array_test) { + Type t_invalid_var_type; + CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type", + SZ_INT , NULL))) + CHECK_BB(gwi_class_ini(gwi, t_invalid_var_type, NULL, NULL)) + CHECK_BB(gwi_func_ini(gwi, "int[]", "func", test_mfun)) + CHECK_BB(gwi_func_arg(gwi, "int[][]", "i")) + CHECK_BB(gwi_func_arg(gwi, "int", "j[]")) + CHECK_BB(gwi_func_arg(gwi, "int[]", "k[]")) + CHECK_BB(gwi_func_arg(gwi, "int", "l")) + CHECK_BB(gwi_func_end(gwi, ae_flag_static)) + + CHECK_BB(gwi_func_ini(gwi, "int[]", "func", test_mfun)) + CHECK_BB(gwi_func_arg(gwi, "int", "j[][]")) + CHECK_BB(gwi_func_arg(gwi, "int[]", "+k[][][]")) + CHECK_BB(gwi_func_arg(gwi, "int", "l")) + CHECK_BB(gwi_func_end(gwi, ae_flag_static)) + + CHECK_BB(gwi_func_ini(gwi, "int[]", "func", test_mfun)) + CHECK_BB(gwi_func_arg(gwi, "+int", "j[][]")) + CHECK_BB(gwi_func_arg(gwi, "int[]", "+k[][][]")) + CHECK_BB(gwi_func_end(gwi, ae_flag_static)) + + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/invalid_func.c b/tests/import/invalid_func.c new file mode 100644 index 000000000..0eb8530b7 --- /dev/null +++ b/tests/import/invalid_func.c @@ -0,0 +1,22 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +static MFUN(test_mfun){} +GWION_IMPORT(invalid_func_test) { + Type t_invalid_var_type ; + CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type", + SZ_INT , NULL))) + CHECK_BB(gwi_class_ini(gwi, t_invalid_var_type, NULL, NULL)) + CHECK_BB(gwi_func_ini(gwi, ".int", "i", test_mfun)) + CHECK_BB(gwi_func_end(gwi, ae_flag_static)) + + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/invalid_type1.c b/tests/import/invalid_type1.c new file mode 100644 index 000000000..99bed3f15 --- /dev/null +++ b/tests/import/invalid_type1.c @@ -0,0 +1,21 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +static MFUN(test_mfun){} +GWION_IMPORT(invalid_type1_test) { + Type t_invalid_var_type; + CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type", + SZ_INT , NULL))) + CHECK_BB(gwi_class_ini(gwi, t_invalid_var_type, NULL, NULL)) + CHECK_BB(gwi_item_ini(gwi,"i|nt", "test")) + CHECK_BB(gwi_item_end(gwi, 0, NULL)) + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/invalid_type2.c b/tests/import/invalid_type2.c new file mode 100644 index 000000000..b2242ecb1 --- /dev/null +++ b/tests/import/invalid_type2.c @@ -0,0 +1,21 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +static MFUN(test_mfun){} +GWION_IMPORT(invalid_type2_test) { + Type t_invalid_var_type ; + CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type", + SZ_INT , NULL))) + CHECK_BB(gwi_class_ini(gwi, t_invalid_var_type, NULL, NULL)) + CHECK_BB(gwi_item_ini(gwi,".int", "test")) + CHECK_BB(gwi_item_end(gwi, 0, NULL)) + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/invalid_type3.c b/tests/import/invalid_type3.c new file mode 100644 index 000000000..f8e8c9fb7 --- /dev/null +++ b/tests/import/invalid_type3.c @@ -0,0 +1,22 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "absyn.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +static MFUN(test_mfun){} +GWION_IMPORT(invalid_type3_test) { + Type t_invalid_var_type ; + CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, ".invalid_var_type", + SZ_INT , NULL))) + CHECK_BB(gwi_class_ini(gwi, t_invalid_var_type, NULL, NULL)) + CHECK_BB(gwi_item_ini(gwi,".int", "test")) + CHECK_BB(gwi_item_end(gwi, 0, NULL)) + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/map2.gw b/tests/import/map2.gw new file mode 100644 index 000000000..4834e845b --- /dev/null +++ b/tests/import/map2.gw @@ -0,0 +1,5 @@ +<~int, float~>Map pp; +<<>>; +<<>>; +<<>>; +<<>>; diff --git a/tests/import/no_import.c b/tests/import/no_import.c new file mode 100644 index 000000000..9a10bead8 --- /dev/null +++ b/tests/import/no_import.c @@ -0,0 +1,12 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + + +static MFUN(test_mfun){} diff --git a/tests/import/op_err.c b/tests/import/op_err.c new file mode 100644 index 000000000..c6b2b9875 --- /dev/null +++ b/tests/import/op_err.c @@ -0,0 +1,17 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +GWION_IMPORT(op_err_test) { + gwi_oper_ini(gwi, "int", "int", "int"); // ignore the check + gwi_oper_end(gwi, 220, NULL); // ignore the check. + CHECK_BB(gwi_oper_ini(gwi, "int", "int", "int")) + CHECK_BB(gwi_oper_end(gwi, op_chuck, NULL)) + return GW_OK; +} diff --git a/tests/import/static_string.c b/tests/import/static_string.c new file mode 100644 index 000000000..63befdf8b --- /dev/null +++ b/tests/import/static_string.c @@ -0,0 +1,17 @@ +#include +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +GWION_IMPORT(static_string_test) { + CHECK_BB(gwi_item_ini(gwi, "string", "self")) + M_Object obj = new_string(NULL, "test static string"); + CHECK_BB(gwi_item_end(gwi, ae_flag_global, obj)) + return GW_OK; +} diff --git a/tests/import/static_string.gw b/tests/import/static_string.gw new file mode 100644 index 000000000..fadda99b4 --- /dev/null +++ b/tests/import/static_string.gw @@ -0,0 +1,2 @@ +//<<>>; +<<>>; diff --git a/tests/import/template_arg.c b/tests/import/template_arg.c new file mode 100644 index 000000000..e483910f8 --- /dev/null +++ b/tests/import/template_arg.c @@ -0,0 +1,22 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +static MFUN(template_arg_fun) {} + +GWION_IMPORT(template_arg_test) { + Type t_template_arg; + CHECK_OB((t_template_arg = gwi_mk_type(gwi, "TemplateArg", SZ_INT , NULL))) + CHECK_BB(gwi_class_ini(gwi, t_template_arg, NULL, NULL)) + CHECK_BB(gwi_func_ini(gwi, "int", "set", template_arg_fun)) + CHECK_BB(gwi_func_arg(gwi, "Pair,float>","test")) + CHECK_BB(gwi_func_end(gwi, 0)) + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/typedef.c b/tests/import/typedef.c new file mode 100644 index 000000000..61f228c4d --- /dev/null +++ b/tests/import/typedef.c @@ -0,0 +1,27 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +static MFUN(test_func) { puts("test"); } +GWION_IMPORT(typedef_test) { + Type t_func_typedef; + CHECK_OB((t_func_typedef = gwi_mk_type(gwi, "FuncTypedef", SZ_INT , NULL))) + CHECK_BB(gwi_fptr_ini(gwi, "void", "PtrType")) + CHECK_BB(gwi_fptr_end(gwi, 0)) + + CHECK_BB(gwi_class_ini(gwi, t_func_typedef, NULL, NULL)) + CHECK_BB(gwi_fptr_ini(gwi, "void", "PtrType")) + CHECK_BB(gwi_fptr_end(gwi, ae_flag_static)) + CHECK_BB(gwi_func_ini(gwi, "void", "test_func", test_func)) + CHECK_BB(gwi_func_end(gwi, ae_flag_static)) + CHECK_BB(gwi_item_ini(gwi, "PtrType", "ptr")) + CHECK_BB(gwi_item_end(gwi, ae_flag_static, NULL)) + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/typedef.gw b/tests/import/typedef.gw new file mode 100644 index 000000000..25282b0dc --- /dev/null +++ b/tests/import/typedef.gw @@ -0,0 +1,13 @@ +fun void test(){ <<<"test">>>; } +PtrType ptr; +test(); +test @=> ptr; +ptr(); + + +FuncTypedef.test_func(); +<< FuncTypedef.ptr>>>; + _ptr; +<<>>; +FuncTypedef.ptr(); + diff --git a/tests/import/union.c b/tests/import/union.c new file mode 100644 index 000000000..fe78166c9 --- /dev/null +++ b/tests/import/union.c @@ -0,0 +1,17 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "object.h" +#include "instr.h" +#include "import.h" + +GWION_IMPORT(union_test) { + CHECK_BB(gwi_union_ini(gwi, NULL)) + CHECK_BB(gwi_union_add(gwi,"float", "f")) + CHECK_BB(gwi_union_add(gwi,"int", "i")) + CHECK_BB(gwi_union_end(gwi, 0)) + return GW_OK; +} diff --git a/tests/import/union.gw b/tests/import/union.gw new file mode 100644 index 000000000..b838c6a66 --- /dev/null +++ b/tests/import/union.gw @@ -0,0 +1,8 @@ +Union u; +<<>>; +<<<12 => u.f>>>; +<<<1 => u.i>>>; +<<>>; +<<>>; +<<<0 => u.i>>>; +<< u.o>>>; diff --git a/tests/import/variadic.c b/tests/import/variadic.c new file mode 100644 index 000000000..edbb6bf44 --- /dev/null +++ b/tests/import/variadic.c @@ -0,0 +1,49 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "type.h" +#include "instr.h" +#include "object.h" +#include "import.h" +#include "vararg.h" + +static MFUN(m_test) { + printf("%p\n", *(M_Object*)MEM(0)); +} + +static MFUN(m_variadic) { + M_Object str_obj = *(M_Object*)MEM(SZ_INT); + if(!str_obj)return; + m_str str = STRING(str_obj); + struct Vararg_* arg = *(struct Vararg_**)MEM(SZ_INT*2); + + while(arg->i < arg->s) { + if(*str == 'i') { + printf("%" INT_F "\n", *(m_int*)(arg->d + arg->o)); + arg->o += SZ_INT; + } else if(*str == 'f') { + printf("%f\n", *(m_float*)(arg->d + arg->o)); + arg->o += SZ_FLOAT; + } else if(*str == 'o') { + printf("%p\n", (void*)*(M_Object*)(arg->d + arg->o)); + arg->o += SZ_INT; + } + arg->i++; + str++; + } + free_vararg(arg); +} + +GWION_IMPORT(variadic test) { + const Type t_variadic = gwi_mk_type(gwi, "Variadic", SZ_INT, t_object); + CHECK_BB(gwi_class_ini(gwi, t_variadic, NULL, NULL)) + CHECK_BB(gwi_func_ini(gwi, "void", "member", m_variadic)) + CHECK_BB(gwi_func_arg(gwi, "string", "format")) + CHECK_BB(gwi_func_end(gwi, ae_flag_variadic)) + CHECK_BB(gwi_func_ini(gwi, "void", "test", m_test)) + CHECK_BB(gwi_func_end(gwi, 0)) + CHECK_BB(gwi_class_end(gwi)) + return GW_OK; +} diff --git a/tests/import/variadic.gw b/tests/import/variadic.gw new file mode 100644 index 000000000..c315163f2 --- /dev/null +++ b/tests/import/variadic.gw @@ -0,0 +1,13 @@ +<<<"test builtin variadic function">>>; +Variadic v; +"iiii" => string format; +<<>>; +v.member(format, 1,2,3,4); +v.member(format, 1,2,3,4); +v.test(); +v.member(format, 1,2,3,4); +v.member(format, 1,2,3,4); +v.test(); +v.member(format, 1,2,3,4); +v.member(format, 1,2,3,4); +v.test(); From 4e36de75711ed9928de646aec042dae7065fe6c9 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 15:27:25 +0100 Subject: [PATCH 17/59] :art: Update tests --- examples/array_lit.gw | 2 +- help/lcov.sh | 11 ----- tests/sh/plugin.sh | 2 +- tests/test_plugins/Makefile | 36 -------------- tests/test_plugins/array.c | 25 ---------- tests/test_plugins/begin_class.c | 18 ------- tests/test_plugins/callback.c | 74 ---------------------------- tests/test_plugins/callback.gwold | 16 ------ tests/test_plugins/callback2.gw | 15 ------ tests/test_plugins/class_template.c | 47 ------------------ tests/test_plugins/class_template.gw | 15 ------ tests/test_plugins/coverage.c | 63 ----------------------- tests/test_plugins/coverage.gw | 20 -------- tests/test_plugins/end_class.c | 16 ------ tests/test_plugins/enum.c | 69 -------------------------- tests/test_plugins/enum.gw | 48 ------------------ tests/test_plugins/extend_array.c | 23 --------- tests/test_plugins/extend_array.gw | 3 -- tests/test_plugins/extend_event.c | 22 --------- tests/test_plugins/extend_event.gw | 2 - tests/test_plugins/extend_pair.c | 28 ----------- tests/test_plugins/extend_pair.gw | 4 -- tests/test_plugins/global_func.c | 22 --------- tests/test_plugins/global_func.gw | 1 - tests/test_plugins/global_var.c | 18 ------- tests/test_plugins/global_var.gw | 1 - tests/test_plugins/invalid_arg.c | 23 --------- tests/test_plugins/invalid_array.c | 37 -------------- tests/test_plugins/invalid_func.c | 22 --------- tests/test_plugins/invalid_type1.c | 21 -------- tests/test_plugins/invalid_type2.c | 21 -------- tests/test_plugins/invalid_type3.c | 22 --------- tests/test_plugins/map2.gw | 5 -- tests/test_plugins/no_import.c | 12 ----- tests/test_plugins/op_err.c | 17 ------- tests/test_plugins/static_string.c | 17 ------- tests/test_plugins/static_string.gw | 2 - tests/test_plugins/template_arg.c | 22 --------- tests/test_plugins/typedef.c | 27 ---------- tests/test_plugins/typedef.gw | 13 ----- tests/test_plugins/union.c | 17 ------- tests/test_plugins/union.gw | 8 --- tests/test_plugins/variadic.c | 49 ------------------ tests/test_plugins/variadic.gw | 13 ----- 44 files changed, 2 insertions(+), 947 deletions(-) delete mode 100644 tests/test_plugins/Makefile delete mode 100644 tests/test_plugins/array.c delete mode 100644 tests/test_plugins/begin_class.c delete mode 100644 tests/test_plugins/callback.c delete mode 100644 tests/test_plugins/callback.gwold delete mode 100644 tests/test_plugins/callback2.gw delete mode 100644 tests/test_plugins/class_template.c delete mode 100644 tests/test_plugins/class_template.gw delete mode 100644 tests/test_plugins/coverage.c delete mode 100644 tests/test_plugins/coverage.gw delete mode 100644 tests/test_plugins/end_class.c delete mode 100644 tests/test_plugins/enum.c delete mode 100644 tests/test_plugins/enum.gw delete mode 100644 tests/test_plugins/extend_array.c delete mode 100644 tests/test_plugins/extend_array.gw delete mode 100644 tests/test_plugins/extend_event.c delete mode 100644 tests/test_plugins/extend_event.gw delete mode 100644 tests/test_plugins/extend_pair.c delete mode 100644 tests/test_plugins/extend_pair.gw delete mode 100644 tests/test_plugins/global_func.c delete mode 100644 tests/test_plugins/global_func.gw delete mode 100644 tests/test_plugins/global_var.c delete mode 100644 tests/test_plugins/global_var.gw delete mode 100644 tests/test_plugins/invalid_arg.c delete mode 100644 tests/test_plugins/invalid_array.c delete mode 100644 tests/test_plugins/invalid_func.c delete mode 100644 tests/test_plugins/invalid_type1.c delete mode 100644 tests/test_plugins/invalid_type2.c delete mode 100644 tests/test_plugins/invalid_type3.c delete mode 100644 tests/test_plugins/map2.gw delete mode 100644 tests/test_plugins/no_import.c delete mode 100644 tests/test_plugins/op_err.c delete mode 100644 tests/test_plugins/static_string.c delete mode 100644 tests/test_plugins/static_string.gw delete mode 100644 tests/test_plugins/template_arg.c delete mode 100644 tests/test_plugins/typedef.c delete mode 100644 tests/test_plugins/typedef.gw delete mode 100644 tests/test_plugins/union.c delete mode 100644 tests/test_plugins/union.gw delete mode 100644 tests/test_plugins/variadic.c delete mode 100644 tests/test_plugins/variadic.gw diff --git a/examples/array_lit.gw b/examples/array_lit.gw index accae62d5..3db22c1a9 100644 --- a/examples/array_lit.gw +++ b/examples/array_lit.gw @@ -12,7 +12,7 @@ Object t[2][12][3][4][5]; int k[1][1]; -<<>>; +<<>>; [ 1.0, 2, 3, 4, 5 ]; [ #(0.0, 0.0) ]; diff --git a/help/lcov.sh b/help/lcov.sh index b0f181377..539768c1f 100644 --- a/help/lcov.sh +++ b/help/lcov.sh @@ -4,17 +4,6 @@ OUTFILE=lcov/lcov.info [ -d lcov ] || mkdir lcov -#[ -z "$TRAVIS_BUILD_DIR" ] || { -# BASE_DIR=$PWD -# cd tests/test_plugin || return -# for file in *.c -# do -# sed 's/\.c//' <<< "$file" -# test_test_plugin "$(sed 's/\.c//' <<< "$file")" -# done -# cd "$BASE_DIR" || return -#} - lcov --no-external --capture --directory src --output-file "$OUTFILE" [ -z "$TRAVIS_BUILD_DIR" ] || { diff --git a/tests/sh/plugin.sh b/tests/sh/plugin.sh index 41b54c477..bd14c626a 100644 --- a/tests/sh/plugin.sh +++ b/tests/sh/plugin.sh @@ -30,7 +30,7 @@ rm "empty.so" BASE_DIR="$PWD" -cd tests/test_plugins || exit +cd tests/import || exit for test_file in *.c do test_plugin "${test_file:0:-2}" done diff --git a/tests/test_plugins/Makefile b/tests/test_plugins/Makefile deleted file mode 100644 index 6a5949fbb..000000000 --- a/tests/test_plugins/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -INC = -I../../include -I../../util/include -I../../ast/include -CC ?= gcc - -SRC = ${NAME}.c -OBJ = $(SRC:.c=.o) -CFLAGS = $(../../gwion -C 2>&1 | grep CFLAGS) ${INC} -LDFLAGS = $(../../gwion -C 2>&1 | grep LDFLAGS) - -# os specific -ifeq ($(shell uname), Linux) -LDFLAGS += -shared -else -LDFLAGS += -bundle -undefined dynamic_lookup -endif - -all: ${NAME}.so - - -${NAME}.so: ${OBJ} -ifeq (${USE_LD}, 1) - ${LD} $^ -o ${NAME}.so ${LDFLAGS} -else - ${CC} $^ -o ${NAME}.so ${LDFLAGS} -endif - -clean: - rm -f ${OBJ} ${NAME}.so - -.c.o: - ${CC} -fPIC ${CFLAGS} -c $< -o $(<:.c=.o) -g - -install: ${NAME}.so - install ${NAME}.so ${GWION_ADD_DIR} - -uninstall: - rm ${GWION_ADD_DIR}/${NAME}.so diff --git a/tests/test_plugins/array.c b/tests/test_plugins/array.c deleted file mode 100644 index a256dda60..000000000 --- a/tests/test_plugins/array.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -MFUN(test_mfun){} - -GWION_IMPORT(array_test) { - Type t_invalid_var_name; - CHECK_BB((t_invalid_var_name = gwi_mk_type(gwi, "invalid_var_name", SZ_INT, t_object))) - CHECK_BB(gwi_class_ini(gwi, t_invalid_var_name, NULL, NULL)) - CHECK_BB(gwi_item_ini(gwi,"int[]", "int_array")) - CHECK_BB(gwi_item_end(gwi, 0, NULL)) // import array var - CHECK_BB(gwi_func_ini(gwi, "float[][]", "f", test_mfun)) - CHECK_BB(gwi_func_end(gwi, 0)) - CHECK_BB(gwi_func_ini(gwi, "float[][]", "g", test_mfun)) - CHECK_BB(gwi_func_end(gwi, 0)) - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/begin_class.c b/tests/test_plugins/begin_class.c deleted file mode 100644 index e521b2ce7..000000000 --- a/tests/test_plugins/begin_class.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -MFUN(test_mfun){} -GWION_IMPORT(begin_class) { - Type t_invalid_var_name; - CHECK_OB((t_invalid_var_name = gwi_mk_type(gwi, "invalid_var_name", SZ_INT, t_object))) - CHECK_BB(gwi_class_ini(gwi, t_invalid_var_name, NULL, NULL)) - CHECK_BB(gwi_class_ini(gwi, t_invalid_var_name, NULL, NULL)) - return GW_OK; -} diff --git a/tests/test_plugins/callback.c b/tests/test_plugins/callback.c deleted file mode 100644 index aeeb07595..000000000 --- a/tests/test_plugins/callback.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "instr.h" -#include "object.h" -#include "instr.h" -#include "import.h" -#include "func.h" - -struct ret_info { - Instr instr; - m_uint offset; - m_uint size; -}; - -static INSTR(my_ret) { GWDEBUG_EXE - struct ret_info* info = (struct ret_info*)instr->m_val; - POP_MEM(shred, info->offset); - vector_set(shred->code->instr, shred->pc, (vtype)info->instr); - shred->code = *(VM_Code*)instr->ptr; - POP_REG(shred, info->size) - if(shred->mem == shred->_reg + SIZEOF_REG) - POP_REG(shred, SZ_INT) - POP_REG(shred, shred->code->stack_depth); - shred->pc = instr->m_val2; - free(info); - *(m_int*)shred->reg = 2; - PUSH_REG(shred, SZ_INT); -} - -static SFUN(cb_func) { - m_uint i; - Func f = *(Func*)MEM(0); - if(!f){ - Except(shred, "NullCallbackException"); - } - m_uint offset = shred->mem - (shred->_reg + SIZEOF_REG); - PUSH_MEM(shred, offset); - Instr instr = mp_alloc(Instr); - struct ret_info* info = (struct ret_info*)xmalloc(sizeof(struct ret_info)); - info->offset = offset; - info->size = f->def->ret_type->size; - instr->execute = my_ret; - *(VM_Code*)instr->ptr = shred->code; - instr->m_val = (m_uint)info; - instr->m_val2 = shred->pc; - for(i = 0; i < vector_size(f->code->instr); i++) { - Instr in = (Instr)vector_at(f->code->instr, i); - if(in->execute == FuncReturn || - in->execute == my_ret) { - info->instr = in; - vector_set(f->code->instr, i, (vtype)instr); - } - } - *(m_int*)RETURN = 1; - shred->pc = 0; - shred->code = f->code; -} - -GWION_IMPORT(callback) { - CHECK_BB(gwi_fptr_ini(gwi, "Vec4", "PtrType")) - CHECK_BB(gwi_fptr_end(gwi, 0)) - - const Type t_callback = gwi_mk_type(gwi, "Callback", SZ_INT, t_object); - CHECK_BB(gwi_class_ini(gwi, t_callback, NULL, NULL)) - CHECK_BB(gwi_func_ini(gwi, "int", "callback", cb_func)) - CHECK_BB(gwi_func_arg(gwi, "PtrType", "func")) - CHECK_BB(gwi_func_end(gwi, ae_flag_static)) - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/callback.gwold b/tests/test_plugins/callback.gwold deleted file mode 100644 index d13976067..000000000 --- a/tests/test_plugins/callback.gwold +++ /dev/null @@ -1,16 +0,0 @@ -int i; -int j; -int K; -fun Vec4 test() { <<<"test">>>; } -fun void test2(PtrType t) { Callback.callback(t); } - -test @=> PtrType t; -<<>>; -<<>>; -<<>>; -Callback.callback(t); -test2(t); -test2(t); -spork ~test2(t); -spork ~Callback.callback(t); -me.yield(); diff --git a/tests/test_plugins/callback2.gw b/tests/test_plugins/callback2.gw deleted file mode 100644 index c9f0668d1..000000000 --- a/tests/test_plugins/callback2.gw +++ /dev/null @@ -1,15 +0,0 @@ -fun Vec4 test(int i) { <<<"test with arg ", i>>>; } - -//typedef Vec4 PT(); -//test @=> -PtrTypeI p; -test @=> p; -//test @=> PT ti; -<<>>; -//<<>>; -<<

>>; -//ti(); -<<<"test">>>; -p(2); -<<<"end">>>; -Callback.callback(p, 6); diff --git a/tests/test_plugins/class_template.c b/tests/test_plugins/class_template.c deleted file mode 100644 index 0a6a26ded..000000000 --- a/tests/test_plugins/class_template.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -static m_int o_map_key; -static m_int o_map_value; -#define MAP_KEY(a) *((M_Object*)(a->data + o_map_key)) -#define MAP_VAL(a) *((M_Object*)(a->data + o_map_value)) -static CTOR(class_template_ctor) { - /*char* name = strdup(o->type_ref->name);*/ - /*char* tmp = strsep(&name, "@");*/ - /*char* name1 = strsep(&name, "@");*/ -/*Type t1 = nspc_lookup_type1(o->type_ref->info->parent, insert_symbol(name1));*/ - /*Type t2 = nspc_lookup_type0(shred->vm->emit->env->curr, insert_symbol(name));*/ -/*free(tmp);*/ -/**(M_Object*)(o->data) = new_array(t1->size, 0, t1->array_depth);*/ - /**(M_Object*)(o->data + SZ_INT) = new_array(t2->size, 0, t2->array_depth);*/ -} - -static MFUN(class_template_set) { - -} - -GWION_IMPORT(class_template) { - Type t_class_template; - const m_str list[2] = { "A", "B" }; - gwi_tmpl_ini(gwi, 2, list); - CHECK_OB((t_class_template = gwi_mk_type(gwi, "ClassTemplate", SZ_INT, t_object))) - CHECK_BB(gwi_class_ini(gwi, t_class_template, class_template_ctor, NULL)) - gwi_tmpl_end(gwi); - CHECK_BB(gwi_item_ini(gwi, "A[]", "key")) - CHECK_BB((o_map_key = gwi_item_end(gwi, ae_flag_member | ae_flag_template, NULL))) - CHECK_BB(gwi_item_ini(gwi, "B[]", "value")) - CHECK_BB((o_map_value = gwi_item_end(gwi, ae_flag_member, NULL))) - - - /*gwi_func_ini(gwi, "B", "set", class_template_set);*/ - /*gwi_func_end(gwi, ae_flag_member);*/ - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/class_template.gw b/tests/test_plugins/class_template.gw deleted file mode 100644 index 245aca581..000000000 --- a/tests/test_plugins/class_template.gw +++ /dev/null @@ -1,15 +0,0 @@ -//class child {} -//template<~A, B~> -//class C{ A key; B value; } -//<~int, int~>C c1; -//C c2; -//<<>>; -//<<>>; -//<<>>; - -<~int, int~>ClassTemplate ct; -<<>>; -//ClassTemplate ct2; -//<<>>; -//ClassTemplate ct3; -//<<>>; diff --git a/tests/test_plugins/coverage.c b/tests/test_plugins/coverage.c deleted file mode 100644 index 8c629229e..000000000 --- a/tests/test_plugins/coverage.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -SFUN(coverage_int) { *(m_uint*)RETURN = 0; } -SFUN(coverage_float) { *(m_float*)RETURN = 0; } -SFUN(coverage_complex) { *(m_complex*)RETURN = 0; } -SFUN(coverage_vec3) { m_vec3 v = {0,0,0}; *(m_vec3*)RETURN = v; } -SFUN(coverage_vec4) { m_vec4 v = {0,0,0,0}; *(m_vec4*)RETURN = v; } - -GWION_IMPORT(coverage) { - Type t_coverage; - CHECK_OB((t_coverage = gwi_mk_type(gwi, "Coverage", SZ_INT, t_object))) - CHECK_BB(gwi_class_ini(gwi, t_coverage, NULL, NULL)) - CHECK_BB(gwi_func_ini(gwi, "int", "i", coverage_int)) - CHECK_BB(gwi_func_end(gwi, ae_flag_static)) - CHECK_BB(gwi_func_ini(gwi, "float", "f", coverage_float)) - CHECK_BB(gwi_func_end(gwi, ae_flag_static)) - CHECK_BB(gwi_func_ini(gwi, "complex", "c", coverage_complex)) - CHECK_BB(gwi_func_end(gwi, ae_flag_static)) - CHECK_BB(gwi_func_ini(gwi, "Vec3", "v", coverage_vec3)) - CHECK_BB(gwi_func_end(gwi, ae_flag_static)) - CHECK_BB(gwi_func_ini(gwi, "Vec4", "w", coverage_vec4)) - CHECK_BB(gwi_func_end(gwi, ae_flag_static)) - - m_uint* i = (m_uint*)xmalloc(sizeof(m_uint)); - *i = 5; - CHECK_BB(gwi_item_ini(gwi,"int", "s_i")) - CHECK_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, i)) - m_float* f = (m_float*)xmalloc(sizeof(m_float)); - *f = 2.1; - CHECK_BB(gwi_item_ini(gwi,"float", "s_f")) - CHECK_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, (void*)f)) - - m_complex* c = (m_complex*)xmalloc(sizeof(m_complex)); - *c = 2.1; - CHECK_BB(gwi_item_ini(gwi,"complex", "s_c")) - CHECK_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, (void*)c)) - - m_vec3* v = (m_vec3*)xmalloc(sizeof(m_vec3)); - v->x = 2.1; - v->y = 2.2; - v->z = 2.3; - CHECK_BB(gwi_item_ini(gwi,"Vec3", "s_v")) - CHECK_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, (void*)v)) - - m_vec4* w = (m_vec4*)xmalloc(sizeof(m_vec4)); - w->x = 2.1; - w->y = 2.2; - w->z = 2.3; - w->w = 2.4; - CHECK_BB(gwi_item_ini(gwi,"Vec4", "s_w")) - CHECK_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, (void*)w)) - - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/coverage.gw b/tests/test_plugins/coverage.gw deleted file mode 100644 index d616e424a..000000000 --- a/tests/test_plugins/coverage.gw +++ /dev/null @@ -1,20 +0,0 @@ -float f; -Coverage c; -c.s_i; -<<< Coverage.i() >>>; -<<< Coverage.f() >>>; -<<< Coverage.c() >>>; -<<< Coverage.v() >>>; -<<< Coverage.w() >>>; - -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; - -<<< 1 => Coverage.s_i >>>; -<<< 1.2 => Coverage.s_f >>>; -<<< #(1.2, 0.1) => Coverage.s_c >>>; -<<< @(1.2, 0.1, 2.6) => Coverage.s_v >>>; -<<< @(1.2, 0.1, 2.6, 4.6) => Coverage.s_w >>>; diff --git a/tests/test_plugins/end_class.c b/tests/test_plugins/end_class.c deleted file mode 100644 index 8961e0344..000000000 --- a/tests/test_plugins/end_class.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "absyn.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "operator.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -MFUN(test_mfun){} -GWION_IMPORT(end_class) { - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/enum.c b/tests/test_plugins/enum.c deleted file mode 100644 index 032d7855f..000000000 --- a/tests/test_plugins/enum.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -GWION_IMPORT(enum_test) { - CHECK_BB(gwi_enum_ini(gwi, NULL)) - CHECK_BB(gwi_enum_add(gwi, "ENUM0", 0)) - CHECK_BB(gwi_enum_add(gwi, "ENUM1", 1)) - CHECK_BB(gwi_enum_add(gwi, "ENUM2", 2)) - CHECK_BB(gwi_enum_add(gwi, "ENUM3", 3)) - CHECK_BB(gwi_enum_add(gwi, "ENUM4", 4)) - CHECK_BB(gwi_enum_add(gwi, "ENUM5", 5)) - CHECK_BB(gwi_enum_add(gwi, "ENUM6", 6)) - CHECK_BB(gwi_enum_add(gwi, "ENUM7", 7)) - CHECK_BB(gwi_enum_add(gwi, "ENUM8", 8)) - CHECK_BB(gwi_enum_add(gwi, "ENUM9", 9)) - CHECK_BB(gwi_enum_end(gwi)) - - CHECK_BB(gwi_enum_ini(gwi, "test")) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM0", 0)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM1", 1)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM2", 2)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM3", 3)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM4", 4)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM5", 5)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM6", 6)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM7", 7)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM8", 8)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM9", 9)) - CHECK_BB(gwi_enum_end(gwi)) - - Type t_enum; - CHECK_OB((t_enum = gwi_mk_type(gwi, "Enum", 0, NULL))) - CHECK_BB(gwi_class_ini(gwi, t_enum, NULL, NULL)) - CHECK_BB(gwi_enum_ini(gwi, 0)) - CHECK_BB(gwi_enum_add(gwi, "ENUM0", 0)) - CHECK_BB(gwi_enum_add(gwi, "ENUM1", 1)) - CHECK_BB(gwi_enum_add(gwi, "ENUM2", 2)) - CHECK_BB(gwi_enum_add(gwi, "ENUM3", 3)) - CHECK_BB(gwi_enum_add(gwi, "ENUM4", 4)) - CHECK_BB(gwi_enum_add(gwi, "ENUM5", 5)) - CHECK_BB(gwi_enum_add(gwi, "ENUM6", 6)) - CHECK_BB(gwi_enum_add(gwi, "ENUM7", 7)) - CHECK_BB(gwi_enum_add(gwi, "ENUM8", 8)) - CHECK_BB(gwi_enum_add(gwi, "ENUM9", 9)) - CHECK_BB(gwi_enum_end(gwi)) - - CHECK_BB(gwi_enum_ini(gwi, "Enumtest")) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM0", 0)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM1", 1)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM2", 2)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM3", 3)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM4", 4)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM5", 5)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM6", 6)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM7", 7)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM8", 8)) - CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM9", 9)) - CHECK_BB(gwi_enum_end(gwi)) - CHECK_BB(gwi_class_end(gwi)) - - return GW_OK; -} diff --git a/tests/test_plugins/enum.gw b/tests/test_plugins/enum.gw deleted file mode 100644 index 85666650c..000000000 --- a/tests/test_plugins/enum.gw +++ /dev/null @@ -1,48 +0,0 @@ -// untyped global enum -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; - -// typed global enum -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; - -// in class -// untyped global enum -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; - -// Enum.typed global enum -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; -<<>>; diff --git a/tests/test_plugins/extend_array.c b/tests/test_plugins/extend_array.c deleted file mode 100644 index 6780257b2..000000000 --- a/tests/test_plugins/extend_array.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "instr.h" -#include "object.h" -#include "import.h" -#include "instr.h" - -GWION_IMPORT(extend_array_test) { - Type t_array_ext; - CHECK_OB((t_array_ext = gwi_mk_type(gwi, "ArrayExt", SZ_INT, NULL))) - CHECK_BB(gwi_class_ini(gwi, t_array_ext, NULL, NULL)) - Type_Decl* td = new_type_decl(new_id_list(insert_symbol("float"), 0), 0); - Exp e = new_exp_prim_int(1, 0); - Array_Sub array = new_array_sub(e); - add_type_decl_array(td, array); - CHECK_BB(gwi_class_ext(gwi, td)) - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/extend_array.gw b/tests/test_plugins/extend_array.gw deleted file mode 100644 index a3aa97020..000000000 --- a/tests/test_plugins/extend_array.gw +++ /dev/null @@ -1,3 +0,0 @@ -ArrayExt a; -<<>>; -<<>>; diff --git a/tests/test_plugins/extend_event.c b/tests/test_plugins/extend_event.c deleted file mode 100644 index 92a8e9e68..000000000 --- a/tests/test_plugins/extend_event.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "instr.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -static CTOR(ev_ctor) { printf(" %p this to test ctor\n", (void*)o); } - -GWION_IMPORT(extend_event_test) { - Type t_ev ; - CHECK_OB((t_ev = gwi_mk_type(gwi, "Ev", SZ_INT , NULL))) - CHECK_BB(gwi_class_ini(gwi, t_ev, ev_ctor, NULL)) - Type_Decl* td = new_type_decl(new_id_list(insert_symbol("Event"), 0), 0); - CHECK_BB(gwi_class_ext(gwi, td)) - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/extend_event.gw b/tests/test_plugins/extend_event.gw deleted file mode 100644 index b4c6647e9..000000000 --- a/tests/test_plugins/extend_event.gw +++ /dev/null @@ -1,2 +0,0 @@ -Ev ev; -<<>>; diff --git a/tests/test_plugins/extend_pair.c b/tests/test_plugins/extend_pair.c deleted file mode 100644 index 304a8d32a..000000000 --- a/tests/test_plugins/extend_pair.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "instr.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -GWION_IMPORT(extend_pair_test) { - m_str types[] = { "A", "B" }; - Type t_pair_ext ; - CHECK_OB((t_pair_ext = gwi_mk_type(gwi, "PairExt", SZ_INT , NULL))) - CHECK_BB(gwi_tmpl_ini(gwi, 2, types)) - CHECK_BB(gwi_class_ini(gwi, t_pair_ext, NULL, NULL)) - CHECK_BB(gwi_tmpl_end(gwi)) - Type_Decl* td = new_type_decl(new_id_list(insert_symbol("Pair"), 0), 0); - Type_Decl* td0 = new_type_decl(new_id_list(insert_symbol("A"), 0), 0); - Type_Decl* td1 = new_type_decl(new_id_list(insert_symbol("B"), 0), 0); - Type_List tl1 = new_type_list(td1, NULL); - Type_List tl0 = new_type_list(td0, tl1); - td->types = tl0; - CHECK_BB(gwi_class_ext(gwi, td)) - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/extend_pair.gw b/tests/test_plugins/extend_pair.gw deleted file mode 100644 index f32763dc8..000000000 --- a/tests/test_plugins/extend_pair.gw +++ /dev/null @@ -1,4 +0,0 @@ -<~int, int~>PairExt p; -<<

>>; -<<>>; -<<>>; diff --git a/tests/test_plugins/global_func.c b/tests/test_plugins/global_func.c deleted file mode 100644 index 8bfcbc395..000000000 --- a/tests/test_plugins/global_func.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "instr.h" -#include "object.h" -#include "import.h" -#include "instr.h" - -SFUN(coverage_int) { - puts("test"); - *(m_int*)RETURN = *(m_int*)MEM(0); -} - -GWION_IMPORT(global_func_test) { - CHECK_BB(gwi_func_ini(gwi, "int", "test", coverage_int)) - CHECK_BB(gwi_func_arg(gwi, "int", "i")) - CHECK_BB(gwi_func_end(gwi, 0)) - return GW_OK; -} diff --git a/tests/test_plugins/global_func.gw b/tests/test_plugins/global_func.gw deleted file mode 100644 index 5b594034a..000000000 --- a/tests/test_plugins/global_func.gw +++ /dev/null @@ -1 +0,0 @@ -<<<1 => test>>>; diff --git a/tests/test_plugins/global_var.c b/tests/test_plugins/global_var.c deleted file mode 100644 index 3f46664dd..000000000 --- a/tests/test_plugins/global_var.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - - -GWION_IMPORT(global_var_test) { -// ALLOC_PTR(i, m_uint, 1); - M_Object i = new_string(NULL, "test"); - CHECK_BB(gwi_item_ini(gwi,"string", "i")) - CHECK_BB(gwi_item_end(gwi, 0, i)) - return GW_OK; -} diff --git a/tests/test_plugins/global_var.gw b/tests/test_plugins/global_var.gw deleted file mode 100644 index a4041bca7..000000000 --- a/tests/test_plugins/global_var.gw +++ /dev/null @@ -1 +0,0 @@ -<<>>; diff --git a/tests/test_plugins/invalid_arg.c b/tests/test_plugins/invalid_arg.c deleted file mode 100644 index b8178300e..000000000 --- a/tests/test_plugins/invalid_arg.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -static MFUN(test_mfun){} -GWION_IMPORT(invalid_arg_test) { - Type t_invalid_var_type ; - CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type", - SZ_INT , NULL))) - CHECK_BB(gwi_class_ini(gwi, t_invalid_var_type, NULL, NULL)) - CHECK_BB(gwi_func_ini(gwi, "int[]", "func", test_mfun)) - CHECK_BB(gwi_func_arg(gwi, ".int", "i")) - CHECK_BB(gwi_func_end(gwi, ae_flag_static)) - - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/invalid_array.c b/tests/test_plugins/invalid_array.c deleted file mode 100644 index 348808689..000000000 --- a/tests/test_plugins/invalid_array.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -static MFUN(test_mfun){} -GWION_IMPORT(inalid_array_test) { - Type t_invalid_var_type; - CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type", - SZ_INT , NULL))) - CHECK_BB(gwi_class_ini(gwi, t_invalid_var_type, NULL, NULL)) - CHECK_BB(gwi_func_ini(gwi, "int[]", "func", test_mfun)) - CHECK_BB(gwi_func_arg(gwi, "int[][]", "i")) - CHECK_BB(gwi_func_arg(gwi, "int", "j[]")) - CHECK_BB(gwi_func_arg(gwi, "int[]", "k[]")) - CHECK_BB(gwi_func_arg(gwi, "int", "l")) - CHECK_BB(gwi_func_end(gwi, ae_flag_static)) - - CHECK_BB(gwi_func_ini(gwi, "int[]", "func", test_mfun)) - CHECK_BB(gwi_func_arg(gwi, "int", "j[][]")) - CHECK_BB(gwi_func_arg(gwi, "int[]", "+k[][][]")) - CHECK_BB(gwi_func_arg(gwi, "int", "l")) - CHECK_BB(gwi_func_end(gwi, ae_flag_static)) - - CHECK_BB(gwi_func_ini(gwi, "int[]", "func", test_mfun)) - CHECK_BB(gwi_func_arg(gwi, "+int", "j[][]")) - CHECK_BB(gwi_func_arg(gwi, "int[]", "+k[][][]")) - CHECK_BB(gwi_func_end(gwi, ae_flag_static)) - - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/invalid_func.c b/tests/test_plugins/invalid_func.c deleted file mode 100644 index 0eb8530b7..000000000 --- a/tests/test_plugins/invalid_func.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -static MFUN(test_mfun){} -GWION_IMPORT(invalid_func_test) { - Type t_invalid_var_type ; - CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type", - SZ_INT , NULL))) - CHECK_BB(gwi_class_ini(gwi, t_invalid_var_type, NULL, NULL)) - CHECK_BB(gwi_func_ini(gwi, ".int", "i", test_mfun)) - CHECK_BB(gwi_func_end(gwi, ae_flag_static)) - - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/invalid_type1.c b/tests/test_plugins/invalid_type1.c deleted file mode 100644 index 99bed3f15..000000000 --- a/tests/test_plugins/invalid_type1.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -static MFUN(test_mfun){} -GWION_IMPORT(invalid_type1_test) { - Type t_invalid_var_type; - CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type", - SZ_INT , NULL))) - CHECK_BB(gwi_class_ini(gwi, t_invalid_var_type, NULL, NULL)) - CHECK_BB(gwi_item_ini(gwi,"i|nt", "test")) - CHECK_BB(gwi_item_end(gwi, 0, NULL)) - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/invalid_type2.c b/tests/test_plugins/invalid_type2.c deleted file mode 100644 index b2242ecb1..000000000 --- a/tests/test_plugins/invalid_type2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -static MFUN(test_mfun){} -GWION_IMPORT(invalid_type2_test) { - Type t_invalid_var_type ; - CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type", - SZ_INT , NULL))) - CHECK_BB(gwi_class_ini(gwi, t_invalid_var_type, NULL, NULL)) - CHECK_BB(gwi_item_ini(gwi,".int", "test")) - CHECK_BB(gwi_item_end(gwi, 0, NULL)) - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/invalid_type3.c b/tests/test_plugins/invalid_type3.c deleted file mode 100644 index f8e8c9fb7..000000000 --- a/tests/test_plugins/invalid_type3.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "absyn.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -static MFUN(test_mfun){} -GWION_IMPORT(invalid_type3_test) { - Type t_invalid_var_type ; - CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, ".invalid_var_type", - SZ_INT , NULL))) - CHECK_BB(gwi_class_ini(gwi, t_invalid_var_type, NULL, NULL)) - CHECK_BB(gwi_item_ini(gwi,".int", "test")) - CHECK_BB(gwi_item_end(gwi, 0, NULL)) - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/map2.gw b/tests/test_plugins/map2.gw deleted file mode 100644 index 4834e845b..000000000 --- a/tests/test_plugins/map2.gw +++ /dev/null @@ -1,5 +0,0 @@ -<~int, float~>Map pp; -<<>>; -<<>>; -<<>>; -<<>>; diff --git a/tests/test_plugins/no_import.c b/tests/test_plugins/no_import.c deleted file mode 100644 index 9a10bead8..000000000 --- a/tests/test_plugins/no_import.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - - -static MFUN(test_mfun){} diff --git a/tests/test_plugins/op_err.c b/tests/test_plugins/op_err.c deleted file mode 100644 index c6b2b9875..000000000 --- a/tests/test_plugins/op_err.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -GWION_IMPORT(op_err_test) { - gwi_oper_ini(gwi, "int", "int", "int"); // ignore the check - gwi_oper_end(gwi, 220, NULL); // ignore the check. - CHECK_BB(gwi_oper_ini(gwi, "int", "int", "int")) - CHECK_BB(gwi_oper_end(gwi, op_chuck, NULL)) - return GW_OK; -} diff --git a/tests/test_plugins/static_string.c b/tests/test_plugins/static_string.c deleted file mode 100644 index 63befdf8b..000000000 --- a/tests/test_plugins/static_string.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -GWION_IMPORT(static_string_test) { - CHECK_BB(gwi_item_ini(gwi, "string", "self")) - M_Object obj = new_string(NULL, "test static string"); - CHECK_BB(gwi_item_end(gwi, ae_flag_global, obj)) - return GW_OK; -} diff --git a/tests/test_plugins/static_string.gw b/tests/test_plugins/static_string.gw deleted file mode 100644 index fadda99b4..000000000 --- a/tests/test_plugins/static_string.gw +++ /dev/null @@ -1,2 +0,0 @@ -//<<>>; -<<>>; diff --git a/tests/test_plugins/template_arg.c b/tests/test_plugins/template_arg.c deleted file mode 100644 index e483910f8..000000000 --- a/tests/test_plugins/template_arg.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -static MFUN(template_arg_fun) {} - -GWION_IMPORT(template_arg_test) { - Type t_template_arg; - CHECK_OB((t_template_arg = gwi_mk_type(gwi, "TemplateArg", SZ_INT , NULL))) - CHECK_BB(gwi_class_ini(gwi, t_template_arg, NULL, NULL)) - CHECK_BB(gwi_func_ini(gwi, "int", "set", template_arg_fun)) - CHECK_BB(gwi_func_arg(gwi, "Pair,float>","test")) - CHECK_BB(gwi_func_end(gwi, 0)) - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/typedef.c b/tests/test_plugins/typedef.c deleted file mode 100644 index 61f228c4d..000000000 --- a/tests/test_plugins/typedef.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -static MFUN(test_func) { puts("test"); } -GWION_IMPORT(typedef_test) { - Type t_func_typedef; - CHECK_OB((t_func_typedef = gwi_mk_type(gwi, "FuncTypedef", SZ_INT , NULL))) - CHECK_BB(gwi_fptr_ini(gwi, "void", "PtrType")) - CHECK_BB(gwi_fptr_end(gwi, 0)) - - CHECK_BB(gwi_class_ini(gwi, t_func_typedef, NULL, NULL)) - CHECK_BB(gwi_fptr_ini(gwi, "void", "PtrType")) - CHECK_BB(gwi_fptr_end(gwi, ae_flag_static)) - CHECK_BB(gwi_func_ini(gwi, "void", "test_func", test_func)) - CHECK_BB(gwi_func_end(gwi, ae_flag_static)) - CHECK_BB(gwi_item_ini(gwi, "PtrType", "ptr")) - CHECK_BB(gwi_item_end(gwi, ae_flag_static, NULL)) - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/typedef.gw b/tests/test_plugins/typedef.gw deleted file mode 100644 index 25282b0dc..000000000 --- a/tests/test_plugins/typedef.gw +++ /dev/null @@ -1,13 +0,0 @@ -fun void test(){ <<<"test">>>; } -PtrType ptr; -test(); -test @=> ptr; -ptr(); - - -FuncTypedef.test_func(); -<< FuncTypedef.ptr>>>; - _ptr; -<<>>; -FuncTypedef.ptr(); - diff --git a/tests/test_plugins/union.c b/tests/test_plugins/union.c deleted file mode 100644 index fe78166c9..000000000 --- a/tests/test_plugins/union.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "object.h" -#include "instr.h" -#include "import.h" - -GWION_IMPORT(union_test) { - CHECK_BB(gwi_union_ini(gwi, NULL)) - CHECK_BB(gwi_union_add(gwi,"float", "f")) - CHECK_BB(gwi_union_add(gwi,"int", "i")) - CHECK_BB(gwi_union_end(gwi, 0)) - return GW_OK; -} diff --git a/tests/test_plugins/union.gw b/tests/test_plugins/union.gw deleted file mode 100644 index b838c6a66..000000000 --- a/tests/test_plugins/union.gw +++ /dev/null @@ -1,8 +0,0 @@ -Union u; -<<>>; -<<<12 => u.f>>>; -<<<1 => u.i>>>; -<<>>; -<<>>; -<<<0 => u.i>>>; -<< u.o>>>; diff --git a/tests/test_plugins/variadic.c b/tests/test_plugins/variadic.c deleted file mode 100644 index edbb6bf44..000000000 --- a/tests/test_plugins/variadic.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "vm.h" -#include "env.h" -#include "type.h" -#include "instr.h" -#include "object.h" -#include "import.h" -#include "vararg.h" - -static MFUN(m_test) { - printf("%p\n", *(M_Object*)MEM(0)); -} - -static MFUN(m_variadic) { - M_Object str_obj = *(M_Object*)MEM(SZ_INT); - if(!str_obj)return; - m_str str = STRING(str_obj); - struct Vararg_* arg = *(struct Vararg_**)MEM(SZ_INT*2); - - while(arg->i < arg->s) { - if(*str == 'i') { - printf("%" INT_F "\n", *(m_int*)(arg->d + arg->o)); - arg->o += SZ_INT; - } else if(*str == 'f') { - printf("%f\n", *(m_float*)(arg->d + arg->o)); - arg->o += SZ_FLOAT; - } else if(*str == 'o') { - printf("%p\n", (void*)*(M_Object*)(arg->d + arg->o)); - arg->o += SZ_INT; - } - arg->i++; - str++; - } - free_vararg(arg); -} - -GWION_IMPORT(variadic test) { - const Type t_variadic = gwi_mk_type(gwi, "Variadic", SZ_INT, t_object); - CHECK_BB(gwi_class_ini(gwi, t_variadic, NULL, NULL)) - CHECK_BB(gwi_func_ini(gwi, "void", "member", m_variadic)) - CHECK_BB(gwi_func_arg(gwi, "string", "format")) - CHECK_BB(gwi_func_end(gwi, ae_flag_variadic)) - CHECK_BB(gwi_func_ini(gwi, "void", "test", m_test)) - CHECK_BB(gwi_func_end(gwi, 0)) - CHECK_BB(gwi_class_end(gwi)) - return GW_OK; -} diff --git a/tests/test_plugins/variadic.gw b/tests/test_plugins/variadic.gw deleted file mode 100644 index c315163f2..000000000 --- a/tests/test_plugins/variadic.gw +++ /dev/null @@ -1,13 +0,0 @@ -<<<"test builtin variadic function">>>; -Variadic v; -"iiii" => string format; -<<>>; -v.member(format, 1,2,3,4); -v.member(format, 1,2,3,4); -v.test(); -v.member(format, 1,2,3,4); -v.member(format, 1,2,3,4); -v.test(); -v.member(format, 1,2,3,4); -v.member(format, 1,2,3,4); -v.test(); From 89f624144637126a78960998ace77706a95020af Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 15:34:51 +0100 Subject: [PATCH 18/59] :art: Remove usless vararg->ptr --- src/emit/emit.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index b8e60bf4c..2df8a2675 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1402,7 +1402,6 @@ ANN static m_bool emit_vararg_end(const Emitter emit, const m_uint offset) { GWD instr->m_val = offset; instr->m_val2 = emit->env->func->variadic->m_val2; emit->env->func->variadic->m_val2 = emit_code_size(emit); - *(m_uint*)emit->env->func->variadic->ptr = 1; return GW_OK; } @@ -1596,8 +1595,7 @@ ANN /*static */m_bool emit_func_def(const Emitter emit, const Func_Def func_def) const Func former = emit->env->func; emit->env->func = func; CHECK_BB(emit_func_def_body(emit, func_def)) - if(GET_FLAG(func_def, variadic) && (!emit->env->func->variadic || - !*(m_uint*)emit->env->func->variadic->ptr)) + if(GET_FLAG(func_def, variadic) && !emit->env->func->variadic) ERR_B(func_def->td->xid->pos, "invalid variadic use") emit_func_def_return(emit); emit_func_def_code(emit, func); From 4d8390ce2489fd71c3bb8518396f729d3c1484bb Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 15:39:03 +0100 Subject: [PATCH 19/59] :art: Allow litteral vec emit_var --- include/instr.h | 1 + src/emit/emit.c | 10 +++++++++- src/lib/vec.c | 7 +++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/instr.h b/include/instr.h index 5c6cf8633..d85353792 100644 --- a/include/instr.h +++ b/include/instr.h @@ -62,6 +62,7 @@ INSTR(VarargTop); INSTR(VarargEnd); INSTR(VarargMember); +INSTR(VecCpy); INSTR(VecMember); INSTR(PopArrayClass); diff --git a/src/emit/emit.c b/src/emit/emit.c index 2df8a2675..958514fc3 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -356,8 +356,16 @@ ANN static m_bool prim_vec(const Emitter emit, const Exp_Primary * primary) { GW CHECK_BB(emit_exp(emit, vec->exp, 0)); m_int n = (m_int)((t == ae_primary_vec ? 3 : 2) - vec->dim + 1); while(--n > 0) -// emit_add_instr(emit, PushNull2); emit_add_instr(emit, RegPushImm2); + if(primary->self->emit_var) { + emit_local(emit, primary->self->type->size, 0); + const m_uint offset = emit_local(emit, SZ_INT, 0); + const Instr cpy = emit_add_instr(emit, VecCpy); + cpy->m_val = offset; + cpy->m_val2 = primary->self->type->size; + const Instr instr = emit_add_instr(emit, RegPushMem); + instr->m_val = offset; + } return GW_OK; } diff --git a/src/lib/vec.c b/src/lib/vec.c index 1a5503ea0..045c336fd 100644 --- a/src/lib/vec.c +++ b/src/lib/vec.c @@ -8,6 +8,13 @@ #include "object.h" #include "import.h" +INSTR(VecCpy) { + POP_REG(shred, instr->m_val2); + for(m_uint i = 0; i < instr->m_val2; i += SZ_FLOAT) + *(m_float*)(shred->mem +instr->m_val-instr->m_val2+i) = *(m_float*)(shred->reg+i); + *(m_bit**)(shred->mem + instr->m_val) = (shred->mem + instr->m_val - instr->m_val2); +} + INSTR(VecMember) { GWDEBUG_EXE if(instr->m_val) *(m_float**)REG(-SZ_INT) = (m_float*)(*(m_bit**)REG(-SZ_INT) + instr->m_val2); From 8c925fd1d2ed0044f1925110fbd80a218992016f Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 15:41:59 +0100 Subject: [PATCH 20/59] :bug: Fix VM_INFO --- src/vm/vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm/vm.c b/src/vm/vm.c index b51f6a632..091de4479 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -108,7 +108,7 @@ ANN static inline void vm_ugen_init(const VM* vm) { if(s->curr) \ gw_err("shred[%" UINT_F "] mem[%" INT_F"] reg[%" INT_F"]\n", \ shred->tick->xid, \ - mem - ((m_bit*)shred + sizeof(struct VM_Shred_) + SIZEOF_REG), reg - (m_bit*)shred + sizeof(struct VM_Shred_)); + mem - ((m_bit*)shred + sizeof(struct VM_Shred_) + SIZEOF_REG), reg - ((m_bit*)shred + sizeof(struct VM_Shred_))); #else #define VM_INFO #endif From 233fb7d9101ee8e590f9d3037617cec39313e93e Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 16:06:22 +0100 Subject: [PATCH 21/59] :art: Update utils --- util | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util b/util index b485442ac..cf8206e1e 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit b485442ac6206ead4ad0faca19e853eed0528394 +Subproject commit cf8206e1ecf77e9f2f5b74d704a507b1c7b81322 From 42d3d92bb6143a1462dcea63957d507e44de9dca Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 17:10:49 +0100 Subject: [PATCH 22/59] :art: Push litteral array depth on the stack --- src/emit/emit.c | 5 +++-- src/lib/array.c | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index 958514fc3..46e7b325f 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -317,10 +317,11 @@ ANN static m_bool prim_array(const Emitter emit, const Exp_Primary * primary) { while((e = e->next)); const Type type = array->type; const Type base = array_base(type); + const Instr push = emit_add_instr(emit, RegPushImm); + push->m_val = count; const Instr instr = emit_add_instr(emit, ArrayInit); - instr->m_val = count; + instr->m_val = (m_uint)type; instr->m_val2 = base->size; - *(Type*)instr->ptr = type; return GW_OK; } diff --git a/src/lib/array.c b/src/lib/array.c index e38aa100a..bf14578ca 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -253,11 +253,11 @@ INSTR(ArrayPost) { GWDEBUG_EXE } INSTR(ArrayInit) { GWDEBUG_EXE // for litteral array - const m_uint off = instr->m_val * instr->m_val2; - const Type t = *(Type*)instr->ptr; - POP_REG(shred, off - SZ_INT); - const M_Object obj = new_array(t, instr->m_val); - vector_add(&shred->gc, (vtype)obj); + const Type t = (Type)instr->m_val; + const m_uint sz = *(m_uint*)REG(-SZ_INT); + const m_uint off = instr->m_val2 * sz; + POP_REG(shred, off /*- SZ_INT*/); + const M_Object obj = new_array(t, sz); memcpy(ARRAY(obj)->ptr + ARRAY_OFFSET, REG(-SZ_INT), off); *(M_Object*)REG(-SZ_INT) = obj; } From 6be734e61fc2c91bab41f3dcd1d6c817a14ea3fa Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 17:31:33 +0100 Subject: [PATCH 23/59] :art: array access multi depth on the stack --- src/emit/emit.c | 4 +++- src/lib/array.c | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index 46e7b325f..e0abb3893 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -322,6 +322,7 @@ ANN static m_bool prim_array(const Emitter emit, const Exp_Primary * primary) { const Instr instr = emit_add_instr(emit, ArrayInit); instr->m_val = (m_uint)type; instr->m_val2 = base->size; + emit_add_instr(emit, GcAdd); return GW_OK; } @@ -342,11 +343,12 @@ ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array* array) { G instr->m_val = is_var; instr->m_val2 = is_var ? SZ_INT : array->self->type->size; } else { + const Instr push = emit_add_instr(emit, RegPushImm); + push->m_val = depth; const Instr instr = emit_add_instr(emit, ArrayAccessMulti); instr->m_val = is_var || array->self->type->array_depth; instr->m_val2 = (is_var || array->self->type->array_depth) ? SZ_INT : array_base(array->base->type)->size; - *(m_uint*)instr->ptr = depth; } return GW_OK; } diff --git a/src/lib/array.c b/src/lib/array.c index bf14578ca..6a3bfba41 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -371,8 +371,8 @@ INSTR(ArrayAccess) { GWDEBUG_EXE #define DIM(a) gw_err("\t... at dim [%" INT_F "]\n", (a)) INSTR(ArrayAccessMulti) { GWDEBUG_EXE - const m_uint depth = *(m_uint*)instr->ptr; - POP_REG(shred, SZ_INT * (depth + 1)); + const m_uint depth = *(m_uint*)REG(-SZ_INT); + POP_REG(shred, SZ_INT * (depth + 2)) const M_Object base = *(M_Object*)REG(0); M_Object obj = base; if(!obj) From b617d1b8eab5791784a4722afc253a5f85bba475 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 17:44:34 +0100 Subject: [PATCH 24/59] :art: push switch map on the stack --- src/emit/emit.c | 3 +++ src/lib/instr.c | 7 +++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index e0abb3893..5607d957a 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1168,6 +1168,9 @@ ANN static m_bool emit_switch_instr(const Emitter emit, Instr *instr) { CHECK_BB(emit_exp(emit, e, 0)) *instr = emit_add_instr(emit, SwitchIni); (*instr)->m_val = (m_uint)switch_vec(emit->env); + } else { + const Instr instr = emit_add_instr(emit, RegPushImm); + instr->m_val = (m_uint)switch_map(emit->env); } return GW_OK; } diff --git a/src/lib/instr.c b/src/lib/instr.c index 4ee856b7c..3702658b8 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -43,10 +43,9 @@ INSTR(SwitchIni) { } INSTR(BranchSwitch) { GWDEBUG_EXE - const m_uint offset = *(m_uint*)instr->ptr; - POP_REG(shred, SZ_INT + offset); - const Map map = !offset ?(Map)instr->m_val2 : *(Map*)REG(0); - shred->pc = map_get(map, *(m_uint*)REG(offset)); + POP_REG(shred, SZ_INT*2); + const Map map = *(Map*)REG(0); + shred->pc = map_get(map, *(m_uint*)REG(SZ_INT)); if(!shred->pc) shred->pc = instr->m_val; } From 2096e78346499f4af77edd0b3d1527b03e3694bb Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 15 Feb 2019 22:30:12 +0100 Subject: [PATCH 25/59] :art: RegPushImmX now uses m_val --- include/instr.h | 6 +++--- src/emit/emit.c | 14 ++++++-------- src/vm/vm.c | 9 +++------ 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/include/instr.h b/include/instr.h index d85353792..de356a805 100644 --- a/include/instr.h +++ b/include/instr.h @@ -21,10 +21,10 @@ typedef struct Instr_ * Instr; typedef void (*f_instr)(const VM_Shred, const Instr); struct Instr_ { m_bit opcode; -// union { -// m_float f; + union { + m_float f; m_uint m_val; -// }; + }; m_uint m_val2; m_bit ptr[SZ_MINVAL]; void (*execute)(const VM_Shred shred, const Instr instr); diff --git a/src/emit/emit.c b/src/emit/emit.c index 5607d957a..b23cb43e8 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -269,13 +269,10 @@ ANN static m_bool emit_symbol_builtin(const Emitter emit, const Exp_Primary* pri instr->m_val = (m_uint)v->d.ptr; } else if(v->d.ptr) instr->m_val = *(m_uint*)v->d.ptr; -} -else if(v->d.ptr) - memcpy(instr->ptr, v->d.ptr, v->type->size); -// memcpy(&instr->m_val, v->d.ptr, v->type->size); + } else if(v->d.ptr) + memcpy(&instr->m_val, v->d.ptr, v->type->size); else - *(m_uint**)instr->ptr = v->d.ptr; -// instr->m_val = v->d.ptr; + instr->m_val = v->d.ptr; instr->m_val2 = size; } return GW_OK; @@ -399,7 +396,8 @@ ANN static m_bool prim_num(const Emitter emit, const Exp_Primary * primary) { ANN static m_bool prim_float(const Emitter emit, const Exp_Primary* primary) { const Instr instr = emit_add_instr(emit, RegPushImm2); - *(m_float*)instr->ptr = primary->d.fnum; +// *(m_float*)instr->ptr = primary->d.fnum; + instr->f = primary->d.fnum; return GW_OK; } @@ -1194,7 +1192,7 @@ ANN static m_bool emit_stmt_switch(const Emitter emit, const Stmt_Switch stmt) { instr->m_val = switch_idx(emit->env) ?: emit_code_size(emit); if(push) { emit_switch_map(push, (Map)instr->m_val2); - *(m_uint*)instr->ptr = SZ_INT; +// *(m_uint*)instr->ptr = SZ_INT; } switch_end(emit->env); pop_vector(&emit->code->stack_break, emit_code_size(emit)); diff --git a/src/vm/vm.c b/src/vm/vm.c index 091de4479..c43f0fc8d 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -299,20 +299,17 @@ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini); reg += SZ_INT; DISPATCH(); regpushfloat: -// *(m_float*)reg = instr->f; - *(m_float*)reg = *(m_float*)instr->ptr; + *(m_float*)reg = instr->f; reg += SZ_FLOAT; DISPATCH(); regpushother: LOOP_OPTIM for(m_uint i = 0; i <= instr->m_val2; i+= SZ_INT) -// *(m_bit**)(reg+i) = (m_bit*)(instr->m_val + i); - *(m_bit**)(reg+i) = (m_bit*)(instr->ptr + i); + *(m_bit**)(reg+i) = (m_bit*)(instr->m_val + i); reg += instr->m_val2; DISPATCH(); regpushaddr: -// *(m_bit**)reg = &instr->m_val; - *(m_bit**)reg = instr->ptr; + *(m_bit**)reg = &instr->m_val; reg += SZ_INT; DISPATCH() regpushmem: From e0dbbeb64457e43edc1b7347d1c94eb8600f631c Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sat, 16 Feb 2019 11:31:23 +0100 Subject: [PATCH 26/59] :fire: Remove broken constprop --- include/instr.h | 2 -- include/optim.h | 7 ----- opt/constant.c | 9 +++--- opt/optim.c | 77 ------------------------------------------------ src/emit/emit.c | 45 ++++------------------------ src/lib/instr.c | 23 --------------- src/lib/opfunc.c | 46 ----------------------------- src/oo/value.c | 3 +- 8 files changed, 10 insertions(+), 202 deletions(-) diff --git a/include/instr.h b/include/instr.h index de356a805..e13236f8e 100644 --- a/include/instr.h +++ b/include/instr.h @@ -72,8 +72,6 @@ INSTR(DotTmpl); // optimizations #ifdef OPTIMIZE INSTR(PutArgsInMem); -INSTR(ConstPropSet); -INSTR(ConstPropGet); #endif #include "opcode.h" #endif diff --git a/include/optim.h b/include/optim.h index 0cbd2a3b0..2e1987e4d 100644 --- a/include/optim.h +++ b/include/optim.h @@ -1,17 +1,10 @@ #ifndef __OPTIM #define __OPTIM #ifdef OPTIMIZE -#define OPTIMIZE_DEFAULT default: break; #define OPTIMIZE_CONST(a) CHECK_BO(optimize_const(a)) ANN m_bool optimize_const(const Exp_Binary*); ANN2(1) void constprop_prim(const Exp_Primary* p, m_uint* ptr); -#define OPTIMIZE_PRIM_CONST(a, b) \ -else if(GET_FLAG(v, ae_flag_constprop)) \ - constprop_prim(a,b); #else -#define OPTIMIZE_DEFAULT -#define OPTIMIZE_CONST(a) -#define OPTIMIZE_PRIM_CONST(a, b) #endif m_bool constant_folding(const Exp_Binary* bin); #endif diff --git a/opt/constant.c b/opt/constant.c index 668684026..f996c3020 100644 --- a/opt/constant.c +++ b/opt/constant.c @@ -5,11 +5,10 @@ #include "type.h" #include "constant.h" -#define describe_constant_xxx(name, etype, mtype) \ -ANN m_bool constant_##name(const Exp e) { \ - return (e->exp_type == ae_exp_primary && \ - e->d.exp_primary.primary_type == ae_primary_##etype) || \ - (e->exp_type == ae_exp_constprop && isa(e->type , mtype) > 0); \ +#define describe_constant_xxx(name, etype, mtype) \ +ANN m_bool constant_##name(const Exp e) { \ + return (e->exp_type == ae_exp_primary && \ + e->d.exp_primary.primary_type == ae_primary_##etype); \ } describe_constant_xxx(int, num, t_int) describe_constant_xxx(float, float, t_float) diff --git a/opt/optim.c b/opt/optim.c index dfed7639e..b5ba91593 100644 --- a/opt/optim.c +++ b/opt/optim.c @@ -7,83 +7,6 @@ #include "optim.h" #include "constant.h" -void constprop_prim(const Exp_Primary* p, m_uint* ptr) { - Exp_Primary* e = (Exp_Primary*)p; - e->primary_type = ae_primary_constprop; - e->d.num = (m_uint)ptr; // improve me -} - -ANN static m_bool is_constprop_value(const Exp e) { - if (e->exp_type == ae_exp_decl - && isa(e->d.exp_decl.list->self->value->type, t_int) > 0 && - !e->d.exp_decl.list->self->value->type->array_depth && - !e->d.exp_decl.list->self->value->owner_class && - !GET_FLAG(e->d.exp_decl.list->self->value, arg)) - return (e->exp_type == ae_exp_primary && - e->d.exp_primary.primary_type == ae_primary_id && - isa(e->type, t_int) > 0 && - !e->d.exp_primary.value->owner_class) || - e->exp_type == ae_exp_constprop2; - return 0; -} - -ANN static void constprop_exp(const Exp_Binary* bin, long num) { - const Exp e = bin->self, l = bin->lhs, r = bin->rhs; - e->exp_type = ae_exp_constprop; - e->d.exp_primary.d.num = num; - free_exp(l); - free_exp(r); -} - -ANN static void constprop_value(const Value v, const long num) { - v->d.ptr = (m_uint*)num; //fixme - SET_FLAG(v, constprop); -} - -ANN static m_bool constant_propagation(const Exp_Binary* bin) { - const Exp l = bin->lhs, r = bin->rhs; - switch(bin->op) { - case op_chuck: - if(isa(r->type, t_function) < 0) { - if(is_constprop_value(r)) { - if(constant_int(l)) { -if(r->d.exp_primary.primary_type == ae_primary_num) { - constprop_value(r->d.exp_primary.value, - l->d.exp_primary.d.num); - constprop_exp(bin, l->d.exp_primary.d.num); -} - else if(r->exp_type == ae_exp_decl) { - SET_FLAG(r->d.exp_decl.list->self->value, constprop); - *(m_uint*)r->d.exp_decl.list->self->value->d.ptr = l->d.exp_primary.d.num; - } - return GW_OK; - } - } - } /* fallthrough */ - case op_radd: - case op_rsub: - case op_rmul: - case op_rdiv: - case op_rmod: - case op_rsl: - case op_rsr: - case op_rsand: - case op_rsor: - case op_rsxor: - case op_ref: - case op_unref: - case op_trig: - case op_untrig: - if(r->exp_type == ae_exp_constprop2) { - r->d.exp_primary.value->d.ptr = 0; - UNSET_FLAG(r->d.exp_primary.value, constprop); - } - default: break; - } - return GW_OK; -} - m_bool optimize_const(const Exp_Binary* bin) { - constant_propagation(bin); return constant_folding(bin); } diff --git a/src/emit/emit.c b/src/emit/emit.c index b23cb43e8..b5856660c 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -264,11 +264,11 @@ ANN static m_bool emit_symbol_builtin(const Emitter emit, const Exp_Primary* pri const m_uint size = v->type->size; const Instr instr = emit_kind(emit, size, prim->self->emit_var, regpushimm); if(!prim->self->emit_var && size == SZ_INT) { - if(isa(v->type, t_object) > 0) { - instr->execute = RegPushImm; - instr->m_val = (m_uint)v->d.ptr; - } else if(v->d.ptr) - instr->m_val = *(m_uint*)v->d.ptr; + if(isa(v->type, t_object) > 0) { + instr->execute = RegPushImm; + instr->m_val = (m_uint)v->d.ptr; + } else if(v->d.ptr) + instr->m_val = *(m_uint*)v->d.ptr; } else if(v->d.ptr) memcpy(&instr->m_val, v->d.ptr, v->type->size); else @@ -439,23 +439,10 @@ ANN static m_bool prim_gack(const Emitter emit, const Exp_Primary* primary) { return GW_OK; } -#ifdef OPTIMIZE -ANN static m_bool prim_constprop(Emitter emit, const Exp_Primary* prim) { - const Instr instr = emit_add_instr(emit, ConstPropSet); - instr->m_val = prim->value->offset; - instr->m_val2 = prim->d.num; - *(m_bool*)instr->ptr = prim->self->emit_var; - return GW_OK; -} -#endif - static const _exp_func prim_func[] = { (_exp_func)prim_id, (_exp_func)prim_num, (_exp_func)prim_float, (_exp_func)prim_str, (_exp_func)prim_array, (_exp_func)prim_gack, (_exp_func)prim_vec, (_exp_func)prim_vec, (_exp_func)prim_vec, (_exp_func)prim_char, (_exp_func)dummy_func, -#ifdef OPTIMIZE - (_exp_func)prim_constprop -#endif }; ANN static m_bool emit_exp_primary(const Emitter emit, const Exp_Primary* prim) { GWDEBUG_EXE @@ -881,28 +868,6 @@ ANN static m_bool emit_exp_if(const Emitter emit, const Exp_If* exp_if) { GWDEBU return ret; } -#ifdef OPTIMIZE -ANN static void emit_exp_constprop(const Emitter emit, const Exp e) { - if(!e->emit_var) { - if(e->exp_type == ae_exp_constprop) { - const Instr instr = emit_add_instr(emit, RegPushMem); - instr->m_val = e->d.exp_primary.value->offset; - *(m_uint*)instr->ptr = GET_FLAG(e->d.exp_primary.value, global); - return; - } - const Instr instr = emit_add_instr(emit, ConstPropGet); - instr->m_val2 = e->d.exp_primary.value->offset; - instr->m_val = e->d.exp_primary.d.num; - *(m_uint*)instr->ptr = 1; - } else { - const Instr instr = emit_add_instr(emit, ConstPropSet); - instr->m_val = e->d.exp_primary.value->offset; - *(m_bool*)instr->ptr = 1; - instr->m_val2 = e->d.exp_primary.d.num; - } -} -#endif - DECL_EXP_FUNC(emit) ANN2(1) static m_bool emit_exp(const Emitter emit, Exp exp, const m_bool ref) { GWDEBUG_EXE diff --git a/src/lib/instr.c b/src/lib/instr.c index 3702658b8..78214c67c 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -82,29 +82,6 @@ INSTR(PutArgsInMem) { GWDEBUG_EXE POP_REG(shred, instr->m_val) memcpy(shred->mem, shred->reg, instr->m_val); } - -INSTR(ConstPropSet) { GWDEBUG_EXE - if(*(m_uint*)instr->ptr >= 2) { - *(m_int**)(shred->reg) = (m_int*)(shred->mem + instr->m_val); - PUSH_REG(shred, SZ_INT); - return; - } - *(m_int*)(shred->mem + instr->m_val) = instr->m_val2; - if(*(m_bool*)instr->ptr) - *(m_int**)(shred->reg) = (m_int*)(shred->mem + instr->m_val); - else - *(m_int*)(shred->reg) = instr->m_val2; - PUSH_REG(shred, SZ_INT); - *(m_uint*)instr->ptr = 2 + *(m_uint*)instr->ptr; -} - -INSTR(ConstPropGet) { GWDEBUG_EXE - if(!*(m_uint*)instr->ptr) - memcpy(REG(0), MEM(instr->m_val2), SZ_INT); - else - memcpy(REG(0), &instr->m_val, SZ_INT); - PUSH_REG(shred, SZ_INT); -} #endif Type_List tmpl_tl(const Env env, const m_str name) { diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index d4cde019c..4af00e998 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -50,15 +50,6 @@ OP_CHECK(opck_rassign) { OP_CHECK(opck_unary_meta) { const Exp_Unary* unary = (Exp_Unary*)data; unary->self->meta = ae_meta_value; -#ifdef OPTIMIZE - if(unary->exp->exp_type == ae_exp_constprop2) { - unary->exp->exp_type =ae_exp_primary; - unary->exp->d.exp_primary.primary_type = ae_primary_id; - unary->exp->d.exp_primary.d.num = (m_uint)unary->exp->d.exp_primary.value->d.ptr; - UNSET_FLAG(unary->exp->d.exp_primary.value, constprop); - unary->exp->d.exp_primary.value->d.ptr = 0; - } -#endif return unary->exp->type; } @@ -70,21 +61,6 @@ OP_CHECK(opck_unary) { op2str(unary->op), access(unary->exp->meta)) unary->exp->emit_var = 1; unary->self->meta = ae_meta_value; -#ifdef OPTIMIZE -if(unary->exp->exp_type == ae_exp_primary && - GET_FLAG(unary->exp->d.exp_primary.value, constprop)) { - UNSET_FLAG(unary->exp->d.exp_primary.value, constprop); - unary->exp->d.exp_primary.value->d.ptr = 0; - return unary->exp->type; -} - if(unary->exp->exp_type == ae_exp_constprop) { - unary->exp->exp_type = ae_exp_primary; - unary->exp->d.exp_primary.primary_type = ae_primary_constprop; - unary->exp->d.exp_primary.d.num = (m_uint)unary->exp->d.exp_primary.value->d.ptr; - UNSET_FLAG(unary->exp->d.exp_primary.value, constprop); - unary->exp->d.exp_primary.value->d.ptr = 0; - } -#endif return unary->exp->type; } @@ -95,28 +71,6 @@ OP_CHECK(opck_post) { op2str(post->op), access(post->exp->meta)) post->exp->emit_var = 1; post->self->meta = ae_meta_value; -#ifdef OPTIMIZE -if(post->exp->exp_type == ae_exp_primary && - GET_FLAG(post->exp->d.exp_primary.value, constprop)) { - UNSET_FLAG(post->exp->d.exp_primary.value, constprop); - post->exp->d.exp_primary.value->d.ptr = 0; - return post->exp->type; -} - if(post->exp->exp_type == ae_exp_constprop2) {exit(3); - post->exp->exp_type =ae_exp_primary; - post->exp->d.exp_primary.primary_type = ae_primary_constprop; - post->exp->d.exp_primary.d.num = (m_uint)post->exp->d.exp_primary.value->d.ptr; - UNSET_FLAG(post->exp->d.exp_primary.value, constprop); - post->exp->d.exp_primary.value->d.ptr = 0; -} - if(post->exp->exp_type == ae_exp_constprop) {exit(2); - post->exp->exp_type =ae_exp_primary; - post->exp->d.exp_primary.primary_type = ae_primary_constprop; - post->exp->d.exp_primary.d.num = (m_uint)post->exp->d.exp_primary.value->d.ptr; - UNSET_FLAG(post->exp->d.exp_primary.value, constprop); - post->exp->d.exp_primary.value->d.ptr = 0; -} -#endif return post->exp->type; } diff --git a/src/oo/value.c b/src/oo/value.c index c06b0795c..ae39b9e69 100644 --- a/src/oo/value.c +++ b/src/oo/value.c @@ -7,8 +7,7 @@ #include "type.h" ANN static void free_value(Value a) { -// if(!GET_FLAG(a, func) && !GET_FLAG(a, constprop) && a->d.ptr && isa(a->type, t_object) < 0) - if(!GET_FLAG(a, func) && !GET_FLAG(a, constprop) && a->d.ptr && + if(!GET_FLAG(a, func) && a->d.ptr && !(GET_FLAG(a, enum) && GET_FLAG(a, builtin) && a->owner_class) && isa(a->type, t_object) < 0) _mp_free(a->type->size, a->d.ptr); From 67466d752bb3c23b272d6065b26201733860b257 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sat, 16 Feb 2019 11:56:03 +0100 Subject: [PATCH 27/59] :art: FIx member template --- include/instr.h | 12 ++++++++- src/emit/emit.c | 6 ++++- src/lib/instr.c | 68 +++++++++++++++++++++++------------------------ src/parse/check.c | 30 +++++++++++---------- src/parse/scan2.c | 43 +++++++++++++++++++++++++----- 5 files changed, 102 insertions(+), 57 deletions(-) diff --git a/include/instr.h b/include/instr.h index e13236f8e..555b20f47 100644 --- a/include/instr.h +++ b/include/instr.h @@ -69,9 +69,19 @@ INSTR(PopArrayClass); INSTR(AutoLoopStart); INSTR(AutoLoopEnd); INSTR(DotTmpl); + +struct dottmpl_ { + size_t len; + m_str name; + Func_Def base; + size_t overload; // => vtindex ? + Type_List tl; +}; +ANN void free_dottmpl(struct dottmpl_*); +#endif + // optimizations #ifdef OPTIMIZE INSTR(PutArgsInMem); -#endif #include "opcode.h" #endif diff --git a/src/emit/emit.c b/src/emit/emit.c index b5856660c..7641e77b3 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -690,7 +690,11 @@ assert(_instr->execute == DotTmpl); char c[sz + 1]; strncpy(c, f->name, sz); c[sz] = '\0'; - _instr->m_val = (m_uint)s_name(insert_symbol(c)); + struct dottmpl_ *dt = mp_alloc(dottmpl); + dt->name = s_name(insert_symbol(c)); + dt->overload = f->def->tmpl->base; + dt->base = f->def; + _instr->m_val = (m_uint)dt; _instr->m_val2 = strlen(c); *(m_int*)_instr->ptr = f->def->tmpl->base; return GW_OK; diff --git a/src/lib/instr.c b/src/lib/instr.c index 78214c67c..04f70ac03 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -109,7 +109,8 @@ INSTR(PopArrayClass) { GWDEBUG_EXE #include "value.h" #include "template.h" INSTR(DotTmpl) { - const m_str name = (m_str)instr->m_val; + const struct dottmpl_ * dt = (struct dottmpl_*)instr->m_val; + const m_str name = dt->name; const M_Object o = *(M_Object*)REG(-SZ_INT); Type t = o->type_ref; do { @@ -130,19 +131,17 @@ strcpy(c, start + 1); c[strlen(start) - strlen(end) - 2] = '\0'; m_uint depth; const Type_List tl = str2tl(emit->env, c, &depth); -assert(v); -assert(v->d.func_ref->def = f->def); -env_push_type(emit->env, v->owner_class); -if(template_push_types(emit->env, f->def->tmpl->list, tl) > 0) -// if(traverse_func_def(emit->env, f->value_ref->d.func_ref->def) > 0) - if(traverse_func_def(emit->env, f->def) > 0) -emit_func_def(emit, f->def); -assert(f->code); -assert(f->code = f->def->func->code); -nspc_pop_type(emit->env->curr); -env_pop(emit->env, 0); -free_type_list(tl); -f->def->func->code->stack_depth -= SZ_INT; + m_uint scope = env_push_type(emit->env, v->owner_class); + m_bool ret = GW_ERROR; + if(traverse_func_template(emit->env, f->def, tl) > 0) { + ret = emit_func_def(emit, f->def); + nspc_pop_type(emit->env->curr); + }//} + env_pop(emit->env, scope); + free_type_list(tl); + if(ret < 0) + continue; + } *(VM_Code*)shred->reg = f->code; shred->reg += SZ_INT; @@ -156,31 +155,30 @@ m_str end = strchr(name, '<'); char c[instr->m_val2]; strcpy(c, start); c[strlen(start) - strlen(end)] = '\0'; -const Symbol sym = func_symbol(o->type_ref->name, c, "template", -*(m_uint*)instr->ptr); +const Symbol sym = func_symbol(o->type_ref->name, c, "template", dt->overload); const Value v = nspc_lookup_value1(o->type_ref->nspc, sym); + if(!v) + continue; const Func_Def base = v->d.func_ref->def; const Func_Def def = new_func_def(base->td, insert_symbol(v->name), base->arg_list, base->d.code, base->flag); - def->tmpl = new_tmpl_list(base->tmpl->list, *(m_int*)instr->ptr); + def->tmpl = new_tmpl_list(base->tmpl->list, dt->overload); SET_FLAG(def, template); - Type_List tl = tmpl_tl(emit->env, name); - env_push_type(emit->env, v->owner_class); - if(template_push_types(emit->env, def->tmpl->list, tl) > 0) - if(traverse_func_def(emit->env, def) > 0) { - emit_func_def(emit, def); - nspc_pop_type(emit->env->curr); - } -env_pop(emit->env, 0); -def->func->code->stack_depth -= SZ_INT; - *(VM_Code*)shred->reg = def->func->code; - shred->reg += SZ_INT; - return; - - - -} + Type_List tl = tmpl_tl(emit->env, name); + m_uint scope = env_push_type(emit->env, v->owner_class); + m_bool ret = GW_ERROR; + if(traverse_func_template(emit->env, def, tl) > 0) { + ret = emit_func_def(emit, def); + nspc_pop_type(emit->env->curr); + } + env_pop(emit->env, scope); + free_type_list(tl); + if(ret > 0) { + *(VM_Code*)shred->reg = def->func->code; + shred->reg += SZ_INT; + return; + } + } } while((t = t->parent)); -// should not be reached - Except(shred, "MissigTmplException[internal]"); + Except(shred, "MissigTmplException[internal]"); //unreachable } diff --git a/src/parse/check.c b/src/parse/check.c index 0a3692921..fc809229f 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -434,22 +434,20 @@ exit(77); return m_func; } ANN Func find_template_match(const Env env, const Value value, const Exp_Call* exp) { -// Value v = value; Type t = value->owner_class; const Func f = _find_template_match(env, value, exp); if(f) return f; while(t) { -//assert(t->nspc); - const Value v = nspc_lookup_value1(t->nspc, value->d.func_ref->def->name); -if(!v)goto next; - const Func f = _find_template_match(env, v, exp); - if(f) - return f; -next: -t = t->parent; -} - + Value v = nspc_lookup_value1(t->nspc, value->d.func_ref->def->name); + if(!v) + goto next; + const Func f = _find_template_match(env, v, exp); + if(f) + return f; + next: + t = t->parent; + } assert(exp->self); err_msg(exp->self->pos, "arguments do not match for template call"); return NULL; @@ -976,7 +974,9 @@ ANN static m_bool check_signature_match(const Func_Def f, const Func parent) { G c_name, f_name, p_name, c_name, GET_FLAG(f, static) ? c_name : p_name, f_name) } - return isa(f->ret_type, parent->def->ret_type); + if(!f->tmpl) // ??? + return isa(f->ret_type, parent->def->ret_type); + return GW_OK; } ANN static m_bool parent_match_actual(const Env env, const restrict Func_Def f, @@ -985,8 +985,10 @@ ANN static m_bool parent_match_actual(const Env env, const restrict Func_Def f, do { if(compat_func(f, parent_func->def) > 0) { CHECK_BB(check_signature_match(f, parent_func)) - f->func->vt_index = parent_func->vt_index; - vector_set(&env->curr->vtable, f->func->vt_index, (vtype)f->func); + if(!f->tmpl) { + f->func->vt_index = parent_func->vt_index; + vector_set(&env->curr->vtable, f->func->vt_index, (vtype)f->func); + } return GW_OK; } } while((parent_func = parent_func->next)); diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 464897003..05753c153 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -342,7 +342,7 @@ ANN2(1,2) static Value func_value(const Env env, const Func f, if(!overload) { ADD_REF(v); nspc_add_value(env->curr, f->def->name, v); - } else if(!GET_FLAG(f->def, template)) { + } else /* if(!GET_FLAG(f->def, template)) */ { f->next = overload->d.func_ref->next; overload->d.func_ref->next = f; } @@ -355,12 +355,43 @@ ANN2(1, 2) static m_bool scan2_func_def_template(const Env env, const Func_Def f const Value value = func_value(env, func, overload); SET_FLAG(value, checked | ae_flag_template); SET_FLAG(value->type, func); // the only types with func flag, name could be better - const Symbol sym = func_symbol(env->curr->name, func_name, "template", overload ? ++overload->offset : 0); + Type type = env->class_def; + Nspc nspc = env->curr; + uint i = 0; + do { + const Value v = nspc_lookup_value1(nspc, f->name); + if(v) { + Func ff = v->d.func_ref; + do { + if(ff->def == f) { + ++i; + continue; + } + m_bool ret = compat_func(ff->def, f); + if(ret > 0) { + const Symbol sym = func_symbol(env->curr->name, func_name, + "template", ff->vt_index); + nspc_add_value(env->curr, sym, value); + if(!overload) { + ADD_REF(value) + nspc_add_value(env->curr, f->name, value); + } + func->vt_index = ff->vt_index; + return GW_OK; + } + } while((ff = ff->next) && ++i); + } + } while(type && (type = type->parent) && (nspc = type->nspc)); + --i; + const Symbol sym = func_symbol(env->curr->name, func_name, "template", i); nspc_add_value(env->curr, sym, value); -if(!overload) { - ADD_REF(value) - nspc_add_value(env->curr, f->name, value); -} + nspc_add_value(env->curr, sym, value); + if(!overload) { + func->vt_index = i; + ADD_REF(value) + nspc_add_value(env->curr, f->name, value); + } else + func->vt_index = ++overload->offset; return GW_OK; } From db36d5c80fe9c74b228982911ec9f2cd4aedfdd2 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sat, 16 Feb 2019 11:57:58 +0100 Subject: [PATCH 28/59] :art: Remove Instr->ptr --- include/instr.h | 1 - src/emit/emit.c | 5 ----- 2 files changed, 6 deletions(-) diff --git a/include/instr.h b/include/instr.h index 555b20f47..cd68d0889 100644 --- a/include/instr.h +++ b/include/instr.h @@ -26,7 +26,6 @@ struct Instr_ { m_uint m_val; }; m_uint m_val2; - m_bit ptr[SZ_MINVAL]; void (*execute)(const VM_Shred shred, const Instr instr); }; diff --git a/src/emit/emit.c b/src/emit/emit.c index 7641e77b3..53445025c 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -396,7 +396,6 @@ ANN static m_bool prim_num(const Emitter emit, const Exp_Primary * primary) { ANN static m_bool prim_float(const Emitter emit, const Exp_Primary* primary) { const Instr instr = emit_add_instr(emit, RegPushImm2); -// *(m_float*)instr->ptr = primary->d.fnum; instr->f = primary->d.fnum; return GW_OK; } @@ -696,7 +695,6 @@ assert(_instr->execute == DotTmpl); dt->base = f->def; _instr->m_val = (m_uint)dt; _instr->m_val2 = strlen(c); - *(m_int*)_instr->ptr = f->def->tmpl->base; return GW_OK; } const Instr instr = emit_add_instr(emit, RegPushPtr); @@ -1161,7 +1159,6 @@ ANN static m_bool emit_stmt_switch(const Emitter emit, const Stmt_Switch stmt) { instr->m_val = switch_idx(emit->env) ?: emit_code_size(emit); if(push) { emit_switch_map(push, (Map)instr->m_val2); -// *(m_uint*)instr->ptr = SZ_INT; } switch_end(emit->env); pop_vector(&emit->code->stack_break, emit_code_size(emit)); @@ -1326,8 +1323,6 @@ ANN static m_bool emit_dot_static_import_data(const Emitter emit, const Value v, const Instr instr = emit_kind(emit, size, emit_addr, regpushimm); instr->m_val = (isa(v->type, t_object) > 0 ? (m_uint)&v->d.ptr : (m_uint)v->d.ptr); - *(m_uint**)instr->ptr = (m_uint*)(isa(v->type, t_object) > 0 ? - (m_uint*)&v->d.ptr : v->d.ptr); instr->m_val2 = size; } return GW_OK; From 8e833e8b6c1e77102e583c538e7a2acffbd24a29 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sat, 16 Feb 2019 12:42:00 +0100 Subject: [PATCH 29/59] :art: Fix switch --- src/emit/emit.c | 3 ++- src/oo/switch.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index 53445025c..41c4d3725 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1155,7 +1155,8 @@ ANN static m_bool emit_stmt_switch(const Emitter emit, const Stmt_Switch stmt) { CHECK_BB(emit_exp(emit, stmt->val, 0)) const Instr instr = emit_add_instr(emit, BranchSwitch); instr->m_val2 = (m_uint)switch_map(emit->env); - CHECK_BB(scoped_stmt(emit, stmt->stmt, 1)) +// CHECK_BB(scoped_stmt(emit, stmt->stmt, 1)) + CHECK_BB(emit_stmt(emit, stmt->stmt, 1)) instr->m_val = switch_idx(emit->env) ?: emit_code_size(emit); if(push) { emit_switch_map(push, (Map)instr->m_val2); diff --git a/src/oo/switch.c b/src/oo/switch.c index 4fa98087d..ec2389778 100644 --- a/src/oo/switch.c +++ b/src/oo/switch.c @@ -141,7 +141,7 @@ ANN Map switch_map(const Env env) { ANN Vector switch_vec(const Env env) { const Switch sw = (Switch)vector_back((Vector)&env->swi); - return sw->vec; // new_vector(); // dyn only + return vector_copy(sw->vec); // new_vector(); // dyn only } ANN m_uint switch_idx(const Env env) { From cb81b8af36423365f62f2e447991e5d89eda9a8b Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sat, 16 Feb 2019 13:08:47 +0100 Subject: [PATCH 30/59] :art: finish removibg constprop --- include/optim.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/optim.h b/include/optim.h index 2e1987e4d..2bb66d329 100644 --- a/include/optim.h +++ b/include/optim.h @@ -3,7 +3,7 @@ #ifdef OPTIMIZE #define OPTIMIZE_CONST(a) CHECK_BO(optimize_const(a)) ANN m_bool optimize_const(const Exp_Binary*); -ANN2(1) void constprop_prim(const Exp_Primary* p, m_uint* ptr); +//ANN2(1) void constprop_prim(const Exp_Primary* p, m_uint* ptr); #else #endif m_bool constant_folding(const Exp_Binary* bin); From b0b94ed83098d661914b064eca2e54c894287de9 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sun, 17 Feb 2019 06:46:48 +0100 Subject: [PATCH 31/59] :bug: Fix include --- include/instr.h | 3 +-- include/optim.h | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/instr.h b/include/instr.h index cd68d0889..fe9febbfd 100644 --- a/include/instr.h +++ b/include/instr.h @@ -77,10 +77,9 @@ struct dottmpl_ { Type_List tl; }; ANN void free_dottmpl(struct dottmpl_*); -#endif - // optimizations #ifdef OPTIMIZE INSTR(PutArgsInMem); +#endif #include "opcode.h" #endif diff --git a/include/optim.h b/include/optim.h index 2bb66d329..42e6f2e3f 100644 --- a/include/optim.h +++ b/include/optim.h @@ -5,6 +5,7 @@ ANN m_bool optimize_const(const Exp_Binary*); //ANN2(1) void constprop_prim(const Exp_Primary* p, m_uint* ptr); #else +#define OPTIMIZE_CONST(a) #endif m_bool constant_folding(const Exp_Binary* bin); #endif From 59148570ac19e473bf4edd5656e5f4fc85c8d343 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sun, 17 Feb 2019 13:44:23 +0100 Subject: [PATCH 32/59] :art: Skip vec.x emission when emit_addr --- src/emit/emit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/emit/emit.c b/src/emit/emit.c index 41c4d3725..e5e5a6ae5 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1357,6 +1357,8 @@ ANN static m_bool emit_VecMember(const Emitter emit, const Exp_Dot* member) { emit_vec_func(emit, v); return GW_OK; } + if(!v->offset && member->self->emit_var) // skip + return GW_OK; const Instr instr = emit_add_instr(emit, VecMember); instr->m_val2 = v->offset; instr->m_val = member->self->emit_var; From 330f0dafb0a0c82168a4c1d60dba4ecea147ff0d Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sun, 17 Feb 2019 15:33:16 +0100 Subject: [PATCH 33/59] :art: Fix compiler warnings --- src/emit/emit.c | 2 +- src/lib/instr.c | 9 ++++----- src/parse/check.c | 6 +++--- src/parse/scan2.c | 8 ++++---- src/vm/vm.c | 3 ++- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index e5e5a6ae5..3cd48b7ec 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -272,7 +272,7 @@ ANN static m_bool emit_symbol_builtin(const Emitter emit, const Exp_Primary* pri } else if(v->d.ptr) memcpy(&instr->m_val, v->d.ptr, v->type->size); else - instr->m_val = v->d.ptr; + instr->m_val = (m_uint)v->d.ptr; instr->m_val2 = size; } return GW_OK; diff --git a/src/lib/instr.c b/src/lib/instr.c index 04f70ac03..7f111921d 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -117,14 +117,13 @@ INSTR(DotTmpl) { char str[instr->m_val2 + strlen(t->name) + 1]; strcpy(str, name); strcpy(str + instr->m_val2, t->name); - const Value value = nspc_lookup_value1(t->nspc, insert_symbol(str)); const Func f = nspc_lookup_func1(t->nspc, insert_symbol(str)); if(f) { if(!f->code) { - const Emitter emit = shred->info->vm->gwion->emit; -emit->env->name = "runtime"; - const Value v = f->value_ref; -m_str start = strchr(name, '<'); + const Emitter emit = shred->info->vm->gwion->emit; + emit->env->name = "runtime"; + const Value v = f->value_ref; + m_str start = strchr(name, '<'); m_str end = strchr(name, '@'); char c[instr->m_val2]; strcpy(c, start + 1); diff --git a/src/parse/check.c b/src/parse/check.c index fc809229f..b6ef1b57b 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -442,9 +442,9 @@ ANN Func find_template_match(const Env env, const Value value, const Exp_Call* e Value v = nspc_lookup_value1(t->nspc, value->d.func_ref->def->name); if(!v) goto next; - const Func f = _find_template_match(env, v, exp); - if(f) - return f; + const Func f = _find_template_match(env, v, exp); + if(f) + return f; next: t = t->parent; } diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 05753c153..7ab64c34f 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -494,10 +494,10 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE const Symbol sym = func_symbol(env->curr->name, func_name, NULL, overload ? ++overload->offset : 0); func_name = s_name(sym); } else { -if(f->func) - func_name = f->func->name; -else - func_name = func_tmpl_name(env, f); + if(f->func) + func_name = f->func->name; + else + func_name = func_tmpl_name(env, f); const Func func = nspc_lookup_func1(env->curr, insert_symbol(func_name)); if(func) { f->ret_type = type_decl_resolve(env, f->td); diff --git a/src/vm/vm.c b/src/vm/vm.c index c43f0fc8d..ec67d591e 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -19,6 +19,7 @@ #include "map_private.h" #include "value.h" +#include "gack.h" static inline uint64_t splitmix64_stateless(uint64_t index) { @@ -309,7 +310,7 @@ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini); reg += instr->m_val2; DISPATCH(); regpushaddr: - *(m_bit**)reg = &instr->m_val; + *(m_uint**)reg = &instr->m_val; reg += SZ_INT; DISPATCH() regpushmem: From 35206d2255b2280cd5dc528ba648995e9b5f7fb8 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sun, 17 Feb 2019 15:48:48 +0100 Subject: [PATCH 34/59] :white_check_mark: Test vec emit_addr --- examples/vec3.gw | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/vec3.gw b/examples/vec3.gw index 764e5df5c..6119e4a87 100644 --- a/examples/vec3.gw +++ b/examples/vec3.gw @@ -34,3 +34,4 @@ w-10.; w/10.; 10.*w; w*10.; +<<<@(23).x>>>; From 5e2543e0e90a9d2221c4d606a059265a0675cbbb Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sun, 17 Feb 2019 16:10:12 +0100 Subject: [PATCH 35/59] :art: Loops in vm, emit lint --- src/emit/emit.c | 23 +++-------------------- src/vm/vm.c | 23 +++++++++++------------ 2 files changed, 14 insertions(+), 32 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index 3cd48b7ec..f5352672c 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -707,11 +707,6 @@ static m_bool emit_template_code(const Emitter emit, const Func f) { size_t scope = emit_push(emit, v->owner_class, v->owner); CHECK_BB(emit_func_def(emit, f->def)) // orig emit_pop(emit, scope); -if(!v->owner_class) { -/* no need for dynamicity */ -//assert(instr->opcode != MemSetImm); -//assert(instr->opcode == RegPushBase); -} // else push_tmpl_func return push_func_code(emit, f); } @@ -732,13 +727,8 @@ 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 if( -(f->value_ref->owner_class && is_special(f->value_ref->owner_class) > 0) || - -!f->value_ref->owner_class || GET_FLAG(f, template) -|| (f->value_ref->owner_class && GET_FLAG(f->def, op)) -) + } else if((f->value_ref->owner_class && is_special(f->value_ref->owner_class) > 0) || + !f->value_ref->owner_class || GET_FLAG(f, template)) push_func_code(emit, f); const Instr offset = emit_add_instr(emit, RegPushImm); offset->m_val = emit_code_offset(emit); @@ -821,7 +811,6 @@ ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) { GWDEBUG_ ANN static m_bool spork_code(const Emitter emit, const Stmt stmt) { GWDEBUG_EXE emit_add_instr(emit, RegPushImm); push_spork_code(emit, SPORK_CODE_PREFIX, stmt->pos); -// if(emit->env->class_def && !SAFE_FLAG(emit->env->func, static)) if(!SAFE_FLAG(emit->env->func, member)) stack_alloc_this(emit); CHECK_BB(scoped_stmt(emit, stmt, 0)) @@ -852,10 +841,8 @@ ANN static m_bool emit_implicit_cast(const Emitter emit, ANN static Instr emit_flow(const Emitter emit, const Type type, const f_instr f1, const f_instr f2) { GWDEBUG_EXE if(isa(type, t_float) > 0) { -// emit_add_instr(emit, RegPushImm2); return emit_add_instr(emit, f2); } -// emit_add_instr(emit, RegPushImm); return emit_add_instr(emit, f1); } @@ -1083,7 +1070,6 @@ ANN static m_bool emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt) { GWD const Instr deref = emit_add_instr(emit, DotStatic); deref->m_val = (m_uint)counter; deref->m_val2 = SZ_INT; -// emit_add_instr(emit, RegPushImm); const Instr op = emit_add_instr(emit, BranchEqInt); const Instr dec = emit_add_instr(emit, DecIntAddr); dec->m_val = (m_uint)counter; @@ -1155,7 +1141,6 @@ ANN static m_bool emit_stmt_switch(const Emitter emit, const Stmt_Switch stmt) { CHECK_BB(emit_exp(emit, stmt->val, 0)) const Instr instr = emit_add_instr(emit, BranchSwitch); instr->m_val2 = (m_uint)switch_map(emit->env); -// CHECK_BB(scoped_stmt(emit, stmt->stmt, 1)) CHECK_BB(emit_stmt(emit, stmt->stmt, 1)) instr->m_val = switch_idx(emit->env) ?: emit_code_size(emit); if(push) { @@ -1247,8 +1232,6 @@ ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) { G exp->d.exp_decl.type = stmt->value->type; var_decl->value = stmt->value; CHECK_BB(emit_exp_decl(emit, &exp->d.exp_decl)) -// if(!emit->env->class_def) -// ADD_REF(stmt->value->type); free_exp(exp); if(global) { const M_Object o = new_object(NULL, stmt->value->type); @@ -1494,7 +1477,7 @@ 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); // size -> SZ_INT ? + set_mem->m_val = value->offset = emit_local(emit, SZ_INT, 0); set_mem->m_val2 = (m_uint)value->d.func_ref->code; } diff --git a/src/vm/vm.c b/src/vm/vm.c index ec67d591e..2a8bf4529 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -304,7 +304,7 @@ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini); reg += SZ_FLOAT; DISPATCH(); regpushother: - LOOP_OPTIM +// LOOP_OPTIM for(m_uint i = 0; i <= instr->m_val2; i+= SZ_INT) *(m_bit**)(reg+i) = (m_bit*)(instr->m_val + i); reg += instr->m_val2; @@ -322,7 +322,7 @@ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini); reg += SZ_FLOAT; DISPATCH(); regpushmemother: - LOOP_OPTIM +// LOOP_OPTIM for(m_uint i = 0; i <= instr->m_val2; i+= SZ_INT) *(m_uint*)(reg+i) = *(m_uint*)((mem + instr->m_val) + i); reg += instr->m_val2; @@ -344,7 +344,7 @@ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini); reg += SZ_FLOAT; DISPATCH(); baseother: - LOOP_OPTIM +// LOOP_OPTIM for(m_uint i = 0; i <= instr->m_val2; i+= SZ_INT) *(m_uint*)(reg+i) = *(m_uint*)((shred->base + instr->m_val) + i); reg += instr->m_val2; @@ -392,7 +392,7 @@ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini); reg += SZ_FLOAT; DISPATCH() allocother: - LOOP_OPTIM +// LOOP_OPTIM for(m_uint i = 0; i <= instr->m_val; i += SZ_INT) *(m_uint*)(reg+i) = (*(m_uint*)(mem+instr->m_val+i) = 0); reg += instr->m_val2; @@ -570,7 +570,7 @@ shred->pc = pc; stack_depth -= SZ_INT; } reg-=code->stack_depth; - LOOP_OPTIM +// LOOP_OPTIM for(m_uint i = 0; i < stack_depth; i+= SZ_INT) *(m_uint*)(mem+i+f) = *(m_uint*)(reg+i); } @@ -590,8 +590,7 @@ DISPATCH(); register const m_uint depth = stack_depth -SZ_INT; reg -= stack_depth; *(m_uint*)m = *(m_uint*)(reg + depth); -// for(m_uint i = 0; i < stack_depth; i+= SZ_INT) - LOOP_OPTIM +// LOOP_OPTIM for(m_uint i = 0; i < depth; i+= SZ_INT) *(m_uint*)(m+i+SZ_INT) = *(m_uint*)(reg+i); if(overflow_(m, shred)) @@ -617,7 +616,7 @@ DISPATCH(); register const m_uint stack_depth = a.code->stack_depth; if(stack_depth) { reg -= stack_depth; - LOOP_OPTIM +// LOOP_OPTIM for(m_uint i = 0; i < stack_depth; i+= SZ_INT) *(m_uint*)(m+i) = *(m_uint*)(reg+i); } @@ -640,7 +639,7 @@ DISPATCH(); a.child = init_spork_shred(shred, (VM_Code)instr->m_val); DISPATCH() sporkfunc: - LOOP_OPTIM +// LOOP_OPTIM for(m_uint i = 0; i < instr->m_val; i+= SZ_INT) *(m_uint*)(a.child->reg + i) = *(m_uint*)(reg + i - SZ_INT); a.child->reg += instr->m_val; @@ -650,7 +649,7 @@ DISPATCH(); a.child->reg += SZ_INT; DISPATCH() sporkexp: - LOOP_OPTIM +// LOOP_OPTIM for(m_uint i = 0; i < instr->m_val; i+= SZ_INT) *(m_uint*)(a.child->mem + i) = *(m_uint*)(mem+i); DISPATCH() @@ -732,7 +731,7 @@ DISPATCH(); reg += SZ_FLOAT - SZ_INT; DISPATCH() dotother: - LOOP_OPTIM +// LOOP_OPTIM for(m_uint i = 0; i <= instr->m_val2; i += SZ_INT) *(m_uint*)(reg+i-SZ_INT) = *(m_uint*)((a.obj->data + instr->m_val) + i); reg += instr->m_val2 - SZ_INT; @@ -749,7 +748,7 @@ DISPATCH(); reg += SZ_FLOAT; DISPATCH() staticother: - LOOP_OPTIM +// LOOP_OPTIM for(m_uint i = 0; i <= instr->m_val2; i += SZ_INT) *(m_uint*)(reg+i) = *(m_uint*)(instr->m_val + i); reg += instr->m_val2; From bb0a548e5ac88c9a5de4c9373a051b8f1b92cf71 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Mon, 18 Feb 2019 12:57:53 +0100 Subject: [PATCH 36/59] :art: Start Working on templates --- include/instr.h | 2 +- src/emit/emit.c | 10 ++++++ src/lib/instr.c | 90 +++++++++++++++++------------------------------- src/vm/vm_code.c | 6 +++- 4 files changed, 48 insertions(+), 60 deletions(-) diff --git a/include/instr.h b/include/instr.h index fe9febbfd..e349f4ba5 100644 --- a/include/instr.h +++ b/include/instr.h @@ -72,7 +72,7 @@ INSTR(DotTmpl); struct dottmpl_ { size_t len; m_str name; - Func_Def base; + Func_Def base, def; size_t overload; // => vtindex ? Type_List tl; }; diff --git a/src/emit/emit.c b/src/emit/emit.c index f5352672c..7c1860730 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -679,6 +679,15 @@ ANN static m_bool is_special(const Type t) { return GW_ERROR; } +ANN static Type_List tmpl_tl(const Env env, const m_str name) { + const m_str start = strchr(name, '<'); + const m_str end = strchr(name, '@'); + char c[strlen(name)]; + strcpy(c, start + 1); + c[strlen(start) - strlen(end) - 2] = '\0'; + m_uint depth; + return str2tl(env, c, &depth); +} static inline m_bool push_func_code(const Emitter emit, const Func f) { if(GET_FLAG(f, template) && f->value_ref->owner_class) { @@ -692,6 +701,7 @@ assert(_instr->execute == DotTmpl); struct dottmpl_ *dt = mp_alloc(dottmpl); dt->name = s_name(insert_symbol(c)); dt->overload = f->def->tmpl->base; + dt->tl = tmpl_tl(emit->env, c); dt->base = f->def; _instr->m_val = (m_uint)dt; _instr->m_val2 = strlen(c); diff --git a/src/lib/instr.c b/src/lib/instr.c index 7f111921d..c2f18f2d1 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -45,9 +45,7 @@ INSTR(SwitchIni) { INSTR(BranchSwitch) { GWDEBUG_EXE POP_REG(shred, SZ_INT*2); const Map map = *(Map*)REG(0); - shred->pc = map_get(map, *(m_uint*)REG(SZ_INT)); - if(!shred->pc) - shred->pc = instr->m_val; + shred->pc = map_get(map, *(m_uint*)REG(SZ_INT)) ?: instr->m_val; } INSTR(AutoLoopStart) { GWDEBUG_EXE @@ -84,18 +82,6 @@ INSTR(PutArgsInMem) { GWDEBUG_EXE } #endif -Type_List tmpl_tl(const Env env, const m_str name) { -// const Value v = f->value_ref; -m_str start = strchr(name, '<'); -m_str end = strchr(name, '@'); -char c[strlen(name)]; -strcpy(c, start + 1); -c[strlen(start) - strlen(end) - 2] = '\0'; -m_uint depth; - return str2tl(env, c, &depth); -} - - INSTR(PopArrayClass) { GWDEBUG_EXE POP_REG(shred, SZ_INT); const M_Object obj = *(M_Object*)REG(-SZ_INT); @@ -108,70 +94,58 @@ INSTR(PopArrayClass) { GWDEBUG_EXE #include "emit.h" #include "value.h" #include "template.h" + +ANN static Func_Def from_base(const struct dottmpl_ *dt, const Type t) { + const Symbol sym = func_symbol(t->name, s_name(dt->base->name), + "template", dt->overload); + const Value v = nspc_lookup_value1(t->nspc, sym); + CHECK_OO(v) + const Func_Def base = v->d.func_ref->def; + const Func_Def def = new_func_def(base->td, insert_symbol(v->name), + base->arg_list, base->d.code, base->flag); + def->tmpl = new_tmpl_list(base->tmpl->list, dt->overload); + SET_FLAG(def, template); + return def; +} + INSTR(DotTmpl) { const struct dottmpl_ * dt = (struct dottmpl_*)instr->m_val; const m_str name = dt->name; const M_Object o = *(M_Object*)REG(-SZ_INT); Type t = o->type_ref; do { + const Emitter emit = shred->info->vm->gwion->emit; + emit->env->name = "runtime"; char str[instr->m_val2 + strlen(t->name) + 1]; strcpy(str, name); strcpy(str + instr->m_val2, t->name); const Func f = nspc_lookup_func1(t->nspc, insert_symbol(str)); if(f) { if(!f->code) { - const Emitter emit = shred->info->vm->gwion->emit; - emit->env->name = "runtime"; - const Value v = f->value_ref; - m_str start = strchr(name, '<'); -m_str end = strchr(name, '@'); -char c[instr->m_val2]; -strcpy(c, start + 1); -c[strlen(start) - strlen(end) - 2] = '\0'; -m_uint depth; -const Type_List tl = str2tl(emit->env, c, &depth); - m_uint scope = env_push_type(emit->env, v->owner_class); - m_bool ret = GW_ERROR; - if(traverse_func_template(emit->env, f->def, tl) > 0) { - ret = emit_func_def(emit, f->def); - nspc_pop_type(emit->env->curr); - }//} - env_pop(emit->env, scope); - free_type_list(tl); - if(ret < 0) - continue; - -} + const m_uint scope = env_push_type(emit->env, t); + m_bool ret = GW_ERROR; + if(traverse_func_template(emit->env, f->def, dt->tl) > 0) { + ret = emit_func_def(emit, f->def); + nspc_pop_type(emit->env->curr); + } + env_pop(emit->env, scope); + if(ret < 0) + continue; + } *(VM_Code*)shred->reg = f->code; shred->reg += SZ_INT; return; } else { - const Emitter emit = shred->info->vm->gwion->emit; -emit->env->name = "runtime"; -//m_str start = strchr(name, '<'); -m_str start = name; -m_str end = strchr(name, '<'); -char c[instr->m_val2]; -strcpy(c, start); -c[strlen(start) - strlen(end)] = '\0'; -const Symbol sym = func_symbol(o->type_ref->name, c, "template", dt->overload); - const Value v = nspc_lookup_value1(o->type_ref->nspc, sym); - if(!v) - continue; - const Func_Def base = v->d.func_ref->def; - const Func_Def def = new_func_def(base->td, insert_symbol(v->name), - base->arg_list, base->d.code, base->flag); - def->tmpl = new_tmpl_list(base->tmpl->list, dt->overload); - SET_FLAG(def, template); - Type_List tl = tmpl_tl(emit->env, name); - m_uint scope = env_push_type(emit->env, v->owner_class); + const Func_Def def = from_base(dt, t); + if(!def) + continue; + const m_uint scope = env_push_type(emit->env, t); m_bool ret = GW_ERROR; - if(traverse_func_template(emit->env, def, tl) > 0) { + if(traverse_func_template(emit->env, def, dt->tl) > 0) { ret = emit_func_def(emit, def); nspc_pop_type(emit->env->curr); } env_pop(emit->env, scope); - free_type_list(tl); if(ret > 0) { *(VM_Code*)shred->reg = def->func->code; shred->reg += SZ_INT; diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index be729fe0a..fbac5529f 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -36,6 +36,11 @@ ANN static void free_code_instr(const Vector v) { free_code_instr_gack(instr); else if(instr->execute == BranchSwitch) free_map((Map)instr->m_val2); + else if(instr->execute == DotTmpl) { + struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val; + free_type_list(dt->tl); + mp_free(dottmpl, dt); + } else if(instr->execute == SwitchIni) { free_vector((Vector)instr->m_val); free_map((Map)instr->m_val2); @@ -56,7 +61,6 @@ ANN static void free_vm_code(VM_Code a) { memoize_end(a->memoize); #endif if(!GET_FLAG(a, builtin)) -// if(a->instr) free_code_instr(a->instr); free(a->name); mp_free(VM_Code, a); From 87ae76cceda7e76127406a7e242cdd58695482bf Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Tue, 19 Feb 2019 11:21:32 +0100 Subject: [PATCH 37/59] :art: Add shebang --- help/opcode.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/help/opcode.sh b/help/opcode.sh index 194df2b18..35ee14dba 100644 --- a/help/opcode.sh +++ b/help/opcode.sh @@ -1,3 +1,4 @@ +#!/bin/bash echo "#ifndef __GWION_OPCODES__" echo "#define __GWION_OPCODES__" From 9b3c60d05a9a40e670b4a6232ca11e5d93a48ea8 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Tue, 19 Feb 2019 11:21:56 +0100 Subject: [PATCH 38/59] :art: Fix dyn_switch --- examples/dyn_switch.gw | 11 +++++++++ examples/template_dyn.gw | 52 ++++++++++++++++++++++++++++++++++++++++ src/emit/emit.c | 4 ++-- src/lib/instr.c | 2 +- 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 examples/dyn_switch.gw create mode 100644 examples/template_dyn.gw diff --git a/examples/dyn_switch.gw b/examples/dyn_switch.gw new file mode 100644 index 000000000..805136714 --- /dev/null +++ b/examples/dyn_switch.gw @@ -0,0 +1,11 @@ +3 => +const int i; +2 => const int y; +switch(i) { + case 1: <<<1>>>;break; + case 3: <<<3>>>;break; + case y: <<<2>>>;break; + default: + <<<"0">>>; +} +<<>>; diff --git a/examples/template_dyn.gw b/examples/template_dyn.gw new file mode 100644 index 000000000..ebfa2514a --- /dev/null +++ b/examples/template_dyn.gw @@ -0,0 +1,52 @@ +fun void test(C cc) { <<< cc.test(2) >>>; } + +fun void test(C cc, int i) { <<<1>>>; <<>>; } + + +class C { + template<~A~> + fun int test(A a) { <<<" A ", a>>>; } + template<~A~> + fun int test(A a, int i) { <<<" ", a >>>; } + template<~A~> + fun int test(A a, int i, int j) { <<>>; } +} +class D extends C { + template<~A~> + fun int test(A a, int i) { <<>>; } +} +class E extends D { + template<~A~> + fun int test(A a, int i) { <<>>; } +} + + +<<>>; +<<>>; +<<>>; + +test(c); +test(d); +test(e); +test(c,1); +test(d,2); +test(e,3); +<<>>; + + +c.test(1); +c.test(123,1); +c.test(1, 2, 3); + +d.test(2); +d.test(123,3); +d.test(2, 2, 3); + +e.test(3); +e.test(123,3); +e.test(3, 2, 3); + +fun void _test() {<<<"test">>>; } +fun void test() { _test(); } +test(); + diff --git a/src/emit/emit.c b/src/emit/emit.c index 7c1860730..298d33821 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1128,7 +1128,6 @@ ANN static m_bool emit_switch_instr(const Emitter emit, Instr *instr) { while((e = switch_expget(emit->env))) CHECK_BB(emit_exp(emit, e, 0)) *instr = emit_add_instr(emit, SwitchIni); - (*instr)->m_val = (m_uint)switch_vec(emit->env); } else { const Instr instr = emit_add_instr(emit, RegPushImm); instr->m_val = (m_uint)switch_map(emit->env); @@ -1139,7 +1138,7 @@ ANN static m_bool emit_switch_instr(const Emitter emit, Instr *instr) { ANN static void emit_switch_map(const Instr instr, const Map map) { const Map m = new_map(); for(m_uint i = map_size(map) + 1; --i;) - map_set(m, VKEY(map, i), VVAL(map, i -1)); + map_set(m, VKEY(map, i-1), VVAL(map, i -1)); instr->m_val2 = (m_uint)m; } @@ -1155,6 +1154,7 @@ ANN static m_bool emit_stmt_switch(const Emitter emit, const Stmt_Switch stmt) { instr->m_val = switch_idx(emit->env) ?: emit_code_size(emit); if(push) { emit_switch_map(push, (Map)instr->m_val2); + (push)->m_val = (m_uint)switch_vec(emit->env); } switch_end(emit->env); pop_vector(&emit->code->stack_break, emit_code_size(emit)); diff --git a/src/lib/instr.c b/src/lib/instr.c index c2f18f2d1..da88ca359 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -36,7 +36,7 @@ INSTR(SwitchIni) { const Vector v = (Vector)instr->m_val; const m_uint size = vector_size(v); const Map m = (Map)instr->m_val2; - POP_REG(shred, SZ_INT * (size - 1)); + POP_REG(shred, SZ_INT * (size-1)); for(m_uint i = 0; i < size; ++i) map_set(m, *(vtype*)REG((i-1) * SZ_INT), vector_at(v, i)); *(Map*)REG(-SZ_INT) = m; From 4326fb6dd495822bcf4c6c67b5565cfa3ba75323 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Tue, 19 Feb 2019 17:17:32 +0100 Subject: [PATCH 39/59] :art: Update utils --- util | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util b/util index cf8206e1e..0abf0492f 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit cf8206e1ecf77e9f2f5b74d704a507b1c7b81322 +Subproject commit 0abf0492f81a51044f9522c70815895a1de9986e From 1a61dc8804f794f7a157c3afd2b394567d9a4ce2 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Tue, 19 Feb 2019 17:41:36 +0100 Subject: [PATCH 40/59] :art: Fixes and performance --- ast | 2 +- include/opcode.h | 2 ++ opcode.txt | 1 + src/emit/emit.c | 10 +++++----- src/emit/memoize.c | 7 ++++--- src/lib/array.c | 8 ++++---- src/vm/vm.c | 10 +++++++--- tests/error/self_extend.gw | 4 ++++ 8 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 tests/error/self_extend.gw diff --git a/ast b/ast index 8fe7b1900..305c073c7 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 8fe7b190037c09cee1b5ff6cca54b4dba88b9d1a +Subproject commit 305c073c779f3efb3b1ed344b1a924784599da29 diff --git a/include/opcode.h b/include/opcode.h index d7b01b37a..3eb434bc8 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -1,6 +1,7 @@ #ifndef __GWION_OPCODES__ #define __GWION_OPCODES__ enum { + RegSetImm, RegPushImm, RegPushImm2, RegPushImm3, @@ -156,6 +157,7 @@ enum { OP_MAX, }; +#define RegSetImm (f_instr)RegSetImm #define RegPushImm (f_instr)RegPushImm #define RegPushImm2 (f_instr)RegPushImm2 #define RegPushImm3 (f_instr)RegPushImm3 diff --git a/opcode.txt b/opcode.txt index ef5908a04..db65393b4 100644 --- a/opcode.txt +++ b/opcode.txt @@ -1,3 +1,4 @@ +RegSetImm RegPushImm RegPushImm2 RegPushImm3 diff --git a/src/emit/emit.c b/src/emit/emit.c index 298d33821..08a75f5a0 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -188,7 +188,7 @@ 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); push_f->m_val = (m_uint)code; - const Instr offset = emit_add_instr(emit, RegPushImm); + const Instr offset = emit_add_instr(emit, RegSetImm); offset->m_val = emit_code_offset(emit); emit_add_instr(emit, !GET_FLAG(code, builtin) ? FuncUsr : FuncMember); } @@ -314,7 +314,7 @@ ANN static m_bool prim_array(const Emitter emit, const Exp_Primary * primary) { while((e = e->next)); const Type type = array->type; const Type base = array_base(type); - const Instr push = emit_add_instr(emit, RegPushImm); + const Instr push = emit_add_instr(emit, RegSetImm); push->m_val = count; const Instr instr = emit_add_instr(emit, ArrayInit); instr->m_val = (m_uint)type; @@ -340,7 +340,7 @@ ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array* array) { G instr->m_val = is_var; instr->m_val2 = is_var ? SZ_INT : array->self->type->size; } else { - const Instr push = emit_add_instr(emit, RegPushImm); + const Instr push = emit_add_instr(emit, RegSetImm); push->m_val = depth; const Instr instr = emit_add_instr(emit, ArrayAccessMulti); instr->m_val = is_var || array->self->type->array_depth; @@ -729,7 +729,7 @@ ANN static Instr emit_call(const Emitter emit, const Func f) { return emit_add_instr(emit, exec); } const Instr ex = emit_add_instr(emit, GWOP_EXCEPT); - ex->m_val = -SZ_INT*2; + ex->m_val = -SZ_INT; return emit_add_instr(emit, FuncPtr); } @@ -740,7 +740,7 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f) { GWDEBUG_EXE } else if((f->value_ref->owner_class && is_special(f->value_ref->owner_class) > 0) || !f->value_ref->owner_class || GET_FLAG(f, template)) push_func_code(emit, f); - const Instr offset = emit_add_instr(emit, RegPushImm); + const Instr offset = emit_add_instr(emit, RegSetImm); 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; diff --git a/src/emit/memoize.c b/src/emit/memoize.c index dee3664f4..08db52c03 100644 --- a/src/emit/memoize.c +++ b/src/emit/memoize.c @@ -70,15 +70,16 @@ static inline void memoize_set(Memoize m, const m_bit* arg) { } m_bool memoize_get(VM_Shred shred) { - const VM_Code code = *(VM_Code*)REG(-SZ_INT * 2); +// const VM_Code code = *(VM_Code*)REG(-SZ_INT * 2); + const VM_Code code = *(VM_Code*)REG(-SZ_INT); const Memoize m = code->memoize; - const m_bit* arg = REG(-(SZ_INT*2 + m->arg_sz + (m_uint)m->member)); + const m_bit* arg = REG(-(SZ_INT + m->arg_sz + (m_uint)m->member)); const m_uint size = vector_size(&m->v); for(m_uint i = 0; i < size; ++i) { m_bit* data = (m_bit*)vector_at(&m->v, i); if(memcmp(arg, data, m->arg_sz)) continue; - POP_REG(shred, SZ_INT*2 + (m->arg_sz - m->ret_sz) + (m_uint)m->member) + POP_REG(shred, SZ_INT + (m->arg_sz - m->ret_sz) + (m_uint)m->member) mreturn[m->kind](shred->reg-m->ret_sz, data + m->arg_sz, m->ret_sz); return GW_OK; } diff --git a/src/lib/array.c b/src/lib/array.c index 6a3bfba41..7793b9cdd 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -254,9 +254,9 @@ INSTR(ArrayPost) { GWDEBUG_EXE INSTR(ArrayInit) { GWDEBUG_EXE // for litteral array const Type t = (Type)instr->m_val; - const m_uint sz = *(m_uint*)REG(-SZ_INT); + const m_uint sz = *(m_uint*)REG(0); const m_uint off = instr->m_val2 * sz; - POP_REG(shred, off /*- SZ_INT*/); + POP_REG(shred, off - SZ_INT); const M_Object obj = new_array(t, sz); memcpy(ARRAY(obj)->ptr + ARRAY_OFFSET, REG(-SZ_INT), off); *(M_Object*)REG(-SZ_INT) = obj; @@ -371,8 +371,8 @@ INSTR(ArrayAccess) { GWDEBUG_EXE #define DIM(a) gw_err("\t... at dim [%" INT_F "]\n", (a)) INSTR(ArrayAccessMulti) { GWDEBUG_EXE - const m_uint depth = *(m_uint*)REG(-SZ_INT); - POP_REG(shred, SZ_INT * (depth + 2)) + const m_uint depth = *(m_uint*)REG(0); + POP_REG(shred, SZ_INT * (depth + 1)) const M_Object base = *(M_Object*)REG(0); M_Object obj = base; if(!obj) diff --git a/src/vm/vm.c b/src/vm/vm.c index 2a8bf4529..93686cd5d 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -221,6 +221,7 @@ __attribute__((hot)) ANN void vm_run(const VM* vm) { static const void* dispatch[] = { + &®setimm, &®pushimm, &®pushfloat, &®pushother, &®pushaddr, &®pushmem, &®pushmemfloat, &®pushmemother, &®pushmemaddr, &&pushnow, @@ -295,6 +296,9 @@ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini); #endif do { register Instr instr; DISPATCH(); +regsetimm: + *(m_uint*)reg = instr->m_val; + DISPATCH(); regpushimm: *(m_uint*)reg = instr->m_val; reg += SZ_INT; @@ -551,7 +555,7 @@ shred->pc = pc; funcusr: { - reg -= SZ_INT * 2; + reg -= SZ_INT; register const m_uint push = *(m_uint*)(reg + SZ_INT) + *(m_uint*)(mem-SZ_INT); mem += push; *(m_uint*) mem = push;mem += SZ_INT; @@ -581,7 +585,7 @@ shred->pc = pc; DISPATCH(); funcmember: { - reg -= SZ_INT * 2; + reg -= SZ_INT; a.code = *(VM_Code*)reg; register const m_uint local_depth = *(m_uint*)(reg + SZ_INT); register m_bit* m = mem + local_depth; @@ -608,7 +612,7 @@ DISPATCH(); } funcstatic: { - reg -= SZ_INT * 2; + reg -= SZ_INT; a.code = *(VM_Code*)reg; register const m_uint local_depth = *(m_uint*)(reg + SZ_INT); register m_bit* m = mem + local_depth; diff --git a/tests/error/self_extend.gw b/tests/error/self_extend.gw new file mode 100644 index 000000000..e6d5a55b4 --- /dev/null +++ b/tests/error/self_extend.gw @@ -0,0 +1,4 @@ +// [contains] cannot extend itself +class C extends C { + +} From 870d7a019577bf1ab5721b9d975e3291faa8ecb0 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Tue, 19 Feb 2019 17:57:34 +0100 Subject: [PATCH 41/59] :art: Update ast --- ast | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ast b/ast index 305c073c7..02f63505a 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 305c073c779f3efb3b1ed344b1a924784599da29 +Subproject commit 02f63505a564a3329fa07921a592b47a381d5d59 From df656cf9e909a04cd7c5aaed521296b275ca06e5 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Tue, 19 Feb 2019 18:30:54 +0100 Subject: [PATCH 42/59] :wrench: Update ast --- ast | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ast b/ast index 02f63505a..59afb20ab 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 02f63505a564a3329fa07921a592b47a381d5d59 +Subproject commit 59afb20aba44ec9a89bd3003f0481c09d2c24239 From a06ee3e752cae95c0ef17ec7f4dcf6996fc7ec49 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Thu, 21 Feb 2019 11:38:31 +0100 Subject: [PATCH 43/59] :bug: Fix global func --- src/emit/emit.c | 10 +++++----- src/oo/env.c | 8 +++----- src/oo/nspc.c | 2 +- src/oo/value.c | 10 ++++------ src/parse/check.c | 10 ++++++++++ src/parse/scan2.c | 11 +++++------ src/vm/vm.c | 3 --- 7 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index 08a75f5a0..d0bb4d58f 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -515,9 +515,8 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_de CHECK_BB(emit_instantiate_object(emit, type, array, is_ref)) f_instr *exec = (f_instr*)dotstatic; const Instr instr = emit_kind(emit, v->type->size, emit_addr, exec); -v->d.ptr = _mp_alloc(v->type->size); -// here union flag is more like 'treat as builtin' -SET_FLAG(v, builtin | ae_flag_union); + v->d.ptr = _mp_alloc(v->type->size); + SET_FLAG(v, union); instr->m_val = (m_uint)v->d.ptr; instr->m_val2 = v->type->size; if(is_obj && (is_array || !is_ref)) { @@ -525,6 +524,8 @@ SET_FLAG(v, builtin | ae_flag_union); assign->m_val = (m_uint)emit_var; if(is_array && !emit->env->scope) ADD_REF(type) + const Instr instr = emit_add_instr(emit, RegAddRef); + instr->m_val = emit_var; } return GW_OK; } @@ -1573,8 +1574,7 @@ ANN /*static */m_bool emit_func_def(const Emitter emit, const Func_Def func_def) emit_func_def_code(emit, func); emit->env->func = former; emit_pop_code(emit); -// if(!emit->env->class_def && !GET_FLAG(func_def, template)) - if(!emit->env->class_def) + if(!emit->env->class_def && !GET_FLAG(func_def, global)) emit_func_def_global(emit, func->value_ref); MEMOIZE_INI return GW_OK; diff --git a/src/oo/env.c b/src/oo/env.c index ffa8de24b..88a0da91d 100644 --- a/src/oo/env.c +++ b/src/oo/env.c @@ -23,8 +23,6 @@ Env new_env() { vector_init(&env->nspc_stack); vector_init(&env->known_ctx); env->type_xid = 0; -// scope_init(&env->swi); -// vector_pop((Vector)&env->swi); vector_init((Vector)&env->swi); map_init(&env->swi.map); @@ -48,10 +46,10 @@ ANN void env_reset(const Env env) { ANN void free_env(const Env a) { const m_uint size = vector_size(&a->known_ctx); - for(m_uint i = 0; i < size; i++) - REM_REF((Context)vector_at(&a->known_ctx, i)); - REM_REF(a->global_nspc); + for(m_uint i = size + 1; --i;) + REM_REF((Context)vector_at(&a->known_ctx, i - 1)); vector_release(&a->known_ctx); + REM_REF(a->global_nspc); vector_release(&a->nspc_stack); vector_release(&a->class_stack); vector_release(&a->breaks); diff --git a/src/oo/nspc.c b/src/oo/nspc.c index 3ff54f1b1..7d15ef373 100644 --- a/src/oo/nspc.c +++ b/src/oo/nspc.c @@ -58,9 +58,9 @@ describe_nspc_free(Func, func) describe_nspc_free(Type, type) ANN static void free_nspc(Nspc a) { - free_nspc_value(a); nspc_free_func(a); nspc_free_type(a); + free_nspc_value(a); if(a->class_data) free(a->class_data); diff --git a/src/oo/value.c b/src/oo/value.c index ae39b9e69..879b4d197 100644 --- a/src/oo/value.c +++ b/src/oo/value.c @@ -8,12 +8,10 @@ ANN static void free_value(Value a) { if(!GET_FLAG(a, func) && a->d.ptr && -!(GET_FLAG(a, enum) && GET_FLAG(a, builtin) && a->owner_class) -&& isa(a->type, t_object) < 0) - _mp_free(a->type->size, a->d.ptr); - if(isa(a->type, t_class) > 0 || isa(a->type, t_function) > 0) - REM_REF(a->type) - if(GET_FLAG(a->type, op)) + !(GET_FLAG(a, enum) && GET_FLAG(a, builtin) && a->owner_class) + && isa(a->type, t_object) < 0) + _mp_free(a->type->size, a->d.ptr); + if(isa(a->type, t_class) > 0 || isa(a->type, t_function) > 0 || GET_FLAG(a->type, op)) REM_REF(a->type) mp_free(Value, a); } diff --git a/src/parse/check.c b/src/parse/check.c index b6ef1b57b..818db81b8 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -103,6 +103,8 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE decl_member(env->curr, v); else if(GET_FLAG(decl->td, static)) decl_static(env->curr, v); + else if(global || (env->func && GET_FLAG(env->func->def, global))) + SET_FLAG(v, abstract); if(isa(decl->type, t_fptr) > 0) CHECK_BO(check_fptr_decl(env, var)) SET_FLAG(v, checked | ae_flag_used); @@ -148,6 +150,10 @@ ANN static Value check_non_res_value(const Env env, const Exp_Primary* primary) ERR_O(primary->self->pos, "non-static member '%s' used from static function.", s_name(primary->d.var)) return v; + } else if(env->func && GET_FLAG(env->func->def, global)) { + if(!SAFE_FLAG(value, abstract) && !SAFE_FLAG(value, arg)) + ERR_O(primary->self->pos, + "non-global variable '%s' used from global function.", s_name(primary->d.var)) } return value; } @@ -1087,6 +1093,8 @@ ANN m_bool check_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE CHECK_BB(check_func_def_override(env, f)) if(env->class_def) CHECK_BB(check_parent_match(env, f)) + else if(GET_FLAG(f, global)) + env_push_global(env); const Func former = env->func; env->func = func; ++env->scope; @@ -1105,6 +1113,8 @@ ANN m_bool check_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE nspc_pop_value(env->curr); --env->scope; env->func = former; + if(GET_FLAG(f, global)) + env_push_global(env); return ret; } diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 7ab64c34f..0246c64c3 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -385,7 +385,6 @@ ANN2(1, 2) static m_bool scan2_func_def_template(const Env env, const Func_Def f --i; const Symbol sym = func_symbol(env->curr->name, func_name, "template", i); nspc_add_value(env->curr, sym, value); - nspc_add_value(env->curr, sym, value); if(!overload) { func->vt_index = i; ADD_REF(value) @@ -484,6 +483,9 @@ ANN2(1,2,4) static Value func_create(const Env env, const Func_Def f, ANN m_bool scan2_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE Value value = NULL; f->stack_depth = 0; + m_uint scope = env->scope; + if(GET_FLAG(f, global)) + scope = env_push_global(env); const Value overload = nspc_lookup_value0(env->curr, f->name); m_str func_name = s_name(f->name); if(overload) @@ -506,12 +508,7 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE } const Func base = get_func(env, f); if(!base) { - m_uint scope = env->scope; - if(GET_FLAG(f, global)) - scope = env_push_global(env); CHECK_OB((value = func_create(env, f, overload, func_name))) - if(GET_FLAG(f, global)) - env_pop(env, scope); } else { f->func = base; } @@ -524,6 +521,8 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE CHECK_BB(scan2_func_def_op(env, f)) SET_FLAG(value, checked); } + if(GET_FLAG(f, global)) + env_pop(env, scope); return GW_OK; } diff --git a/src/vm/vm.c b/src/vm/vm.c index 93686cd5d..5aa5f4254 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -563,8 +563,6 @@ shred->pc = pc; *(m_uint*) mem = pc; mem += SZ_INT; pc = 0; code = *(VM_Code*)reg; -//puts(code->name); -// assert(code); ip = code->instr->ptr + OFFSET; m_uint stack_depth = code->stack_depth; if(stack_depth) { @@ -581,7 +579,6 @@ shred->pc = pc; if(overflow_(mem, shred)) Except(shred, "StackOverflow"); } -//puts(code->name); DISPATCH(); funcmember: { From 3b3eae455d588764b5efe363cad8fa7f6c32150b Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Thu, 21 Feb 2019 11:48:47 +0100 Subject: [PATCH 44/59] :art: Use RegSetImm for switches --- examples/dyn_switch.gw | 3 +-- src/emit/emit.c | 4 ++-- src/lib/instr.c | 12 ++++++------ src/vm/vm.c | 6 ++---- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/examples/dyn_switch.gw b/examples/dyn_switch.gw index 805136714..0209d2d26 100644 --- a/examples/dyn_switch.gw +++ b/examples/dyn_switch.gw @@ -1,5 +1,4 @@ -3 => -const int i; +3 => const int i; 2 => const int y; switch(i) { case 1: <<<1>>>;break; diff --git a/src/emit/emit.c b/src/emit/emit.c index d0bb4d58f..876dd3140 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1130,7 +1130,7 @@ ANN static m_bool emit_switch_instr(const Emitter emit, Instr *instr) { CHECK_BB(emit_exp(emit, e, 0)) *instr = emit_add_instr(emit, SwitchIni); } else { - const Instr instr = emit_add_instr(emit, RegPushImm); + const Instr instr = emit_add_instr(emit, RegSetImm); instr->m_val = (m_uint)switch_map(emit->env); } return GW_OK; @@ -1146,9 +1146,9 @@ ANN static void emit_switch_map(const Instr instr, const Map map) { ANN static m_bool emit_stmt_switch(const Emitter emit, const Stmt_Switch stmt) { GWDEBUG_EXE switch_get(emit->env, stmt); Instr push = NULL; + CHECK_BB(emit_exp(emit, stmt->val, 0)) CHECK_BB(emit_switch_instr(emit, &push)) vector_add(&emit->code->stack_break, (vtype)NULL); - CHECK_BB(emit_exp(emit, stmt->val, 0)) const Instr instr = emit_add_instr(emit, BranchSwitch); instr->m_val2 = (m_uint)switch_map(emit->env); CHECK_BB(emit_stmt(emit, stmt->stmt, 1)) diff --git a/src/lib/instr.c b/src/lib/instr.c index da88ca359..b56d81ab4 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -36,16 +36,16 @@ INSTR(SwitchIni) { const Vector v = (Vector)instr->m_val; const m_uint size = vector_size(v); const Map m = (Map)instr->m_val2; - POP_REG(shred, SZ_INT * (size-1)); + POP_REG(shred, SZ_INT * (size)); for(m_uint i = 0; i < size; ++i) - map_set(m, *(vtype*)REG((i-1) * SZ_INT), vector_at(v, i)); - *(Map*)REG(-SZ_INT) = m; + map_set(m, *(vtype*)REG((i) * SZ_INT), vector_at(v, i)); + *(Map*)REG(0) = m; } INSTR(BranchSwitch) { GWDEBUG_EXE - POP_REG(shred, SZ_INT*2); - const Map map = *(Map*)REG(0); - shred->pc = map_get(map, *(m_uint*)REG(SZ_INT)) ?: instr->m_val; + POP_REG(shred, SZ_INT); + const Map map = *(Map*)REG(SZ_INT); + shred->pc = map_get(map, *(m_uint*)REG(0)) ?: instr->m_val; } INSTR(AutoLoopStart) { GWDEBUG_EXE diff --git a/src/vm/vm.c b/src/vm/vm.c index 5aa5f4254..e69eb31e9 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -532,11 +532,11 @@ firmul: FI_R(*) firdiv: FI_R(/) itof: - reg -=SZ_INT - SZ_FLOAT; + reg -= SZ_INT - SZ_FLOAT; *(m_float*)(reg-SZ_FLOAT) = (m_float)*(m_int*)(reg-SZ_FLOAT); DISPATCH() ftoi: - reg -= SZ_FLOAT -SZ_INT; + reg -= SZ_FLOAT - SZ_INT; *(m_int*)(reg-SZ_INT) = (m_int)*(m_float*)(reg-SZ_INT); DISPATCH() @@ -756,11 +756,9 @@ DISPATCH(); DISPATCH() dotfunc: assert(a.obj); -// *(VM_Code*)(reg) = ((Func)vector_at(&a.obj->type_ref->nspc->vtable, instr->m_val))->code; *(VM_Code*)(reg) = ((Func)vector_at(a.obj->vtable, instr->m_val))->code; reg += SZ_INT; DISPATCH() -//dottemplate: staticcode: (*(VM_Code*)reg = ((Func)instr->m_val)->code); reg += SZ_INT; From 4d1c40582c7a2b8d45597ac7df910325a2f28e27 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Thu, 21 Feb 2019 11:59:09 +0100 Subject: [PATCH 45/59] :art: Update modules --- ast | 2 +- util | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ast b/ast index 59afb20ab..787c2856a 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 59afb20aba44ec9a89bd3003f0481c09d2c24239 +Subproject commit 787c2856a8ec0e24b9d174b003e9b395d01080e7 diff --git a/util b/util index 0abf0492f..fa9f700bb 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit 0abf0492f81a51044f9522c70815895a1de9986e +Subproject commit fa9f700bb617e6368150c9a29ffac4c6d5256d2d From 93a5d821d95dad9424443f24333f155f165c25ec Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Thu, 21 Feb 2019 19:52:20 +0100 Subject: [PATCH 46/59] :art: Except opcode offset now fixed --- src/emit/emit.c | 12 ++++++------ src/vm/vm.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index 876dd3140..9e0388d3d 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -729,8 +729,8 @@ ANN static Instr emit_call(const Emitter emit, const Func f) { FuncMember : FuncStatic : FuncUsr; return emit_add_instr(emit, exec); } - const Instr ex = emit_add_instr(emit, GWOP_EXCEPT); - ex->m_val = -SZ_INT; + /*const Instr ex = */emit_add_instr(emit, GWOP_EXCEPT); +// ex->m_val = -SZ_INT; return emit_add_instr(emit, FuncPtr); } @@ -1420,8 +1420,8 @@ ANN static m_bool emit_dot_static_func(const Emitter emit, const Func func) { GW ANN static m_bool emit_member_func(const Emitter emit, const Exp_Dot* member, const Func func) { GWDEBUG_EXE if(emit_exp(emit, member->base, 0) < 0) ERR_B(member->self->pos, "... in member function") // LCOV_EXCL_LINE - const Instr ex = emit_add_instr(emit, GWOP_EXCEPT); - ex->m_val = -SZ_INT; + /*const Instr ex = */emit_add_instr(emit, GWOP_EXCEPT); + //ex->m_val = -SZ_INT; if(GET_FLAG(member->base->type, force)) { const Instr func_i = emit_add_instr(emit, RegPushImm); func_i->m_val = (m_uint)func->code; @@ -1437,8 +1437,8 @@ ANN static m_bool emit_member_func(const Emitter emit, const Exp_Dot* member, co } ANN static inline void emit_member(const Emitter emit, const Value v, const uint emit_addr) { - const Instr ex = emit_add_instr(emit, GWOP_EXCEPT); - ex->m_val = -SZ_INT; + /*const Instr ex = */emit_add_instr(emit, GWOP_EXCEPT); + //ex->m_val = -SZ_INT; const m_uint size = v->type->size; const Instr instr = emit_kind(emit, size, emit_addr, dotmember); instr->m_val = v->offset; diff --git a/src/vm/vm.c b/src/vm/vm.c index e69eb31e9..edb3e093d 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -716,7 +716,7 @@ DISPATCH(); release(*(M_Object*)(mem + instr->m_val), shred); DISPATCH() except: - if(!(a.obj = *(M_Object*)(reg+instr->m_val))) + if(!(a.obj = *(M_Object*)(reg-SZ_INT))) Except(shred, "NullPtrException"); DISPATCH(); allocmemberaddr: From 3368fccdeeb98a25d8fc7fd306b746fe436282ca Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Thu, 21 Feb 2019 20:34:33 +0100 Subject: [PATCH 47/59] :art: Improve func call type check, enforce expression type --- include/opcode.h | 2 -- opcode.txt | 1 - src/emit/emit.c | 12 +++++++++--- src/parse/check.c | 4 +++- src/vm/vm.c | 5 +---- tests/{tree => error}/template_ternary.gw | 1 + 6 files changed, 14 insertions(+), 11 deletions(-) rename tests/{tree => error}/template_ternary.gw (56%) diff --git a/include/opcode.h b/include/opcode.h index 3eb434bc8..b10319aae 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -18,7 +18,6 @@ enum { RegDup, MemSetImm, RegPop, - RegPushPtr, RegPushMe, RegPushMaybe, FuncReturn, @@ -174,7 +173,6 @@ enum { #define RegDup (f_instr)RegDup #define MemSetImm (f_instr)MemSetImm #define RegPop (f_instr)RegPop -#define RegPushPtr (f_instr)RegPushPtr #define RegPushMe (f_instr)RegPushMe #define RegPushMaybe (f_instr)RegPushMaybe #define FuncReturn (f_instr)FuncReturn diff --git a/opcode.txt b/opcode.txt index db65393b4..bd7150838 100644 --- a/opcode.txt +++ b/opcode.txt @@ -15,7 +15,6 @@ RegPushBase4 RegDup MemSetImm RegPop -RegPushPtr RegPushMe RegPushMaybe FuncReturn diff --git a/src/emit/emit.c b/src/emit/emit.c index 9e0388d3d..0351e09e8 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -708,9 +708,15 @@ assert(_instr->execute == DotTmpl); _instr->m_val2 = strlen(c); return GW_OK; } - const Instr instr = emit_add_instr(emit, RegPushPtr); - return !!(instr->m_val = (m_uint)f->code); + const Instr _instr = (Instr)vector_back(&emit->code->instr); + if(_instr->opcode == (m_bit)(m_uint)RegPushImm) + return !!(_instr->m_val = (m_uint)f->code); + assert(_instr->opcode == (m_bit)(m_uint)RegPushBase); + _instr->m_val = (m_uint)f->code; + _instr->opcode = (m_bit)(m_uint)RegPushImm; + return GW_OK; } + static m_bool emit_template_code(const Emitter emit, const Func f) { if(GET_FLAG(f, ref)) CHECK_BB(traverse_template(emit->env, f->value_ref->owner_class->def)) @@ -1574,7 +1580,7 @@ ANN /*static */m_bool emit_func_def(const Emitter emit, const Func_Def func_def) emit_func_def_code(emit, func); emit->env->func = former; emit_pop_code(emit); - if(!emit->env->class_def && !GET_FLAG(func_def, global)) + if(!emit->env->class_def && !GET_FLAG(func_def, global) && !func_def->tmpl) emit_func_def_global(emit, func->value_ref); MEMOIZE_INI return GW_OK; diff --git a/src/parse/check.c b/src/parse/check.c index 818db81b8..f9a6ab580 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -364,6 +364,9 @@ ANN2(1, 2) static Func find_func_match(const Env env, const Func up, const Exp e } ANN static m_bool check_call(const Env env, const Exp_Call* exp) { + ae_exp_t et = exp->func->exp_type; + if(et != ae_exp_primary && et != ae_exp_dot && et != ae_exp_cast) + ERR_B(exp->func->pos, "invalid expression for function call.") CHECK_OB(check_exp(env, exp->func)) return exp->args ? !!check_exp(env, exp->args) : -1; } @@ -553,7 +556,6 @@ ANN static Type check_exp_call_template(const Env env, const Exp_Call *exp) { Tmpl_Call tmpl = { .types=tl[0] }; const Exp_Call tmp_func = { .func=call, .args=args, .tmpl=&tmpl, .self=base }; const Func func = get_template_func(env, &tmp_func, base, value); -//exit(2); if(base->exp_type == ae_exp_call) base->d.exp_call.m_func = func; else // if(base->exp_type == ae_exp_binary) diff --git a/src/vm/vm.c b/src/vm/vm.c index edb3e093d..bb1a78e74 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -228,7 +228,7 @@ ANN void vm_run(const VM* vm) { &&baseint, &&basefloat, &&baseother, &&baseaddr, &®dup, &&memsetimm, - &®pop, &®pushptr, &®pushme, &®pushmaybe, + &®pop, &®pushme, &®pushmaybe, &&funcreturn, &&_goto, &&allocint, &&allocfloat, &&allocother, &&allocaddr, @@ -367,9 +367,6 @@ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini); regpop: reg -= instr->m_val; DISPATCH(); -regpushptr: - *(m_uint*)(reg-SZ_INT) = instr->m_val; - DISPATCH() regpushme: *(M_Object*)reg = shred->info->me; reg += SZ_INT; diff --git a/tests/tree/template_ternary.gw b/tests/error/template_ternary.gw similarity index 56% rename from tests/tree/template_ternary.gw rename to tests/error/template_ternary.gw index 606877145..792855329 100644 --- a/tests/tree/template_ternary.gw +++ b/tests/error/template_ternary.gw @@ -1,3 +1,4 @@ +// [contains] invalid expression for function call template<~A~> function void test(A a){} From dd68a1138b948a36f2b000f44354c4ff1c2e4e8a Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 22 Feb 2019 14:03:18 +0100 Subject: [PATCH 48/59] :art: Initial module commit :smile: --- include/arg.h | 1 + include/gwion.h | 3 + include/module.h | 17 +++++ include/plug.h | 13 +++- src/arg.c | 8 +- src/main.c | 8 +- src/plug.c | 76 ++++++++++++++++--- tests/import/basic_module.c | 23 ++++++ tests/sh/plugin.sh | 2 +- .../switch_in.gw => tree/nested_switch.gw} | 2 - 10 files changed, 133 insertions(+), 20 deletions(-) create mode 100644 include/module.h create mode 100644 tests/import/basic_module.c rename tests/{error/switch_in.gw => tree/nested_switch.gw} (72%) diff --git a/include/arg.h b/include/arg.h index 09c4179ac..2e4d19dfe 100644 --- a/include/arg.h +++ b/include/arg.h @@ -6,6 +6,7 @@ typedef struct { struct Vector_ add; struct Vector_ rem; struct Vector_ lib; + struct Vector_ mod; Vector ref; m_bool loop; unsigned quit : 1; diff --git a/include/gwion.h b/include/gwion.h index 6f68675cd..604195344 100644 --- a/include/gwion.h +++ b/include/gwion.h @@ -2,6 +2,9 @@ #define __GWION typedef struct Gwion_* Gwion; struct Gwion_ { +// Vector args +// PlugInfo +// => Vector v[GWION_NVEC]; // sym // mem // rnd diff --git a/include/module.h b/include/module.h new file mode 100644 index 000000000..f6a533840 --- /dev/null +++ b/include/module.h @@ -0,0 +1,17 @@ +#ifndef __MODULE +#define __MODULE +#define GWMODNAME_NAME "gwmodname" +#define GWMODINI_NAME "gwmodini" +#define GWMODEND_NAME "gwmodend" +#define GWMODNAME_FUNC gwmodname +#define GWMODINI_FUNC gwmodini +#define GWMODEND_FUNC gwmodend +#define GWMODNAME(a) m_str GWMODNAME_FUNC() { return a; } +#define GWMODINI(a) ANN void* GWMODINI_FUNC(const Gwion gwion, const Vector args) +#define GWMODEND(a) ANN void GWMODEND_FUNC(const Gwion gwion, void* self) + +//typedef void* (*f_gwmodname)(void); +typedef void* (*f_gwmodini)(const Gwion, const Vector); +typedef void* (*f_gwmodend)(const Gwion, void*); +void module_ini(const Gwion gwion, Vector v, Vector); +#endif diff --git a/include/plug.h b/include/plug.h index 2d09d313d..fb437a0f7 100644 --- a/include/plug.h +++ b/include/plug.h @@ -1,7 +1,14 @@ #ifndef __PLUG #define __PLUG -#define NPLUG_VEC 2 -typedef struct Vector_ PlugInfo[NPLUG_VEC]; + +enum plug_t { + GWPLUG_DL, + GWPLUG_IMPORT, + GWPLUG_MODULE, + GWPLUG_LAST +}; + +typedef struct Vector_ PlugInfo[GWPLUG_LAST]; void plug_ini(PlugInfo, Vector); -void plug_end(PlugInfo); +void plug_end(const Gwion gwion, PlugInfo); #endif diff --git a/src/arg.c b/src/arg.c index ba4ceff98..9564d8eb9 100644 --- a/src/arg.c +++ b/src/arg.c @@ -14,6 +14,7 @@ ANN void arg_init(Arg* arg) { vector_init(&arg->add); vector_init(&arg->rem); vector_init(&arg->lib); + vector_init(&arg->mod); vector_add(&arg->lib, (vtype)GWPLUG_DIR); arg->ref = &arg->add; } @@ -22,6 +23,7 @@ ANN void arg_release(Arg* arg) { vector_release(&arg->add); vector_release(&arg->rem); vector_release(&arg->lib); + vector_release(&arg->mod); } static const struct option long_option[] = { @@ -48,6 +50,7 @@ static const struct option long_option[] = { { "help", 0, NULL, '?' }, { "version", 0, NULL, 'v' }, { "config", 0, NULL, 'C' }, + { "module", 0, NULL, 'm' }, /* { "status" , 0, NULL, '%' },*/ { NULL, 0, NULL, 0 } }; @@ -136,7 +139,7 @@ ANN static void arg_drvr(DriverInfo* di, const int i) { ANN void parse_args(Arg* arg, DriverInfo* di) { int i, index; - while((i = getopt_long(arg->argc, arg->argv, "?vqh:p:i:o:n:b:e:s:d:l:g:-:rc:f:P:C ", + while((i = getopt_long(arg->argc, arg->argv, "?vqh:p:i:o:n:b:e:s:d:l:g:-:rc:f:m:P:C ", long_option, &index)) != -1) { switch(i) { case '?': @@ -155,6 +158,9 @@ ANN void parse_args(Arg* arg, DriverInfo* di) { case 'P': vector_add(&arg->lib, (vtype)optarg); break; + case 'm': + vector_add(&arg->mod, (vtype)optarg); + break; default: arg_drvr(di, i); } diff --git a/src/main.c b/src/main.c index a41534be0..e577fcefe 100644 --- a/src/main.c +++ b/src/main.c @@ -29,7 +29,9 @@ #define VMBENCH_END #endif +#include "gwion.h" #include "plug.h" +#include "module.h" extern void parse_args(Arg*, DriverInfo*); static VM* some_static_vm; @@ -38,7 +40,6 @@ static void sig(int unused __attribute__((unused))) { some_static_vm->is_running = 0; } -#include "gwion.h" int main(int argc, char** argv) { Driver d = { }; Arg arg = { .argc = argc, .argv=argv, .loop=-1, .quit=0}; @@ -73,8 +74,9 @@ struct Gwion_ gwion; shreduler_set_loop(gwion.vm->shreduler, arg.loop); if(d.ini(gwion.vm, &di) < 0 || !(gwion.vm->bbq = new_bbq(&di))) goto clean; - if(type_engine_init(gwion.vm, &pi[1]) < 0) + if(type_engine_init(gwion.vm, &pi[GWPLUG_IMPORT]) < 0) goto clean; + module_ini(&gwion, &pi[GWPLUG_MODULE], &arg.mod); srand((uint)time(NULL)); for(m_uint i = 0; i < vector_size(&arg.add); i++) compile_filename(&gwion, (m_str)vector_at(&arg.add, i)); @@ -86,7 +88,7 @@ struct Gwion_ gwion; arg_release(&arg); if(d.del) d.del(gwion.vm, &di); - plug_end(pi); + plug_end(&gwion, pi); gwion_release(&gwion); return 0; } diff --git a/src/plug.c b/src/plug.c index 8728faffe..69ae120da 100644 --- a/src/plug.c +++ b/src/plug.c @@ -11,26 +11,44 @@ #include "instr.h" #include "object.h" #include "import.h" +#include "gwion.h" #include "plug.h" +#include "module.h" static inline int so_filter(const struct dirent* dir) { return strstr(dir->d_name, ".so") ? 1 : 0; } +struct Plug_ { + m_str name; + f_gwmodini ini; + f_gwmodend end; + void* self; +}; + ANN static void handle_plug(PlugInfo v, const m_str c) { void* handler = dlopen(c, RTLD_LAZY); if(handler) { - vector_add(&v[0], (vtype)handler); - m_bool(*import)(Gwi) = (m_bool(*)(Gwi))(intptr_t)dlsym(handler, "import"); + vector_add(&v[GWPLUG_DL], (vtype)handler); + m_bool (*import)(Gwi) = (m_bool(*)(Gwi))(intptr_t)dlsym(handler, "import"); if(import) - vector_add(&v[1], (vtype)import); + vector_add(&v[GWPLUG_IMPORT], (vtype)import); + const f_gwmodini ini = (f_gwmodini)(intptr_t)dlsym(handler, GWMODINI_NAME); + if(ini) { + struct Plug_ *plug = mp_alloc(Plug); + plug->ini = ini; + m_str (*name)() = (m_str(*)())(intptr_t)dlsym(handler, GWMODNAME_NAME); + plug->name = name(); + plug->end = (f_gwmodend)(intptr_t)dlsym(handler, GWMODEND_NAME); + vector_add(&v[GWPLUG_MODULE], (vtype)plug); + } } else err_msg(0, "error in %s.", dlerror()); } void plug_ini(PlugInfo v, Vector list) { - vector_init(&v[0]); - vector_init(&v[1]); + for(m_uint i = 0; i < GWPLUG_LAST; ++i) + vector_init(&v[i]); for(m_uint i = 0; i < vector_size(list); i++) { const m_str dirname = (m_str)vector_at(list, i); struct dirent **namelist; @@ -47,9 +65,47 @@ void plug_ini(PlugInfo v, Vector list) { } } -void plug_end(PlugInfo v) { - for(m_uint i = 0; i < vector_size(&v[0]); ++i) - dlclose((void*)vector_at(&v[0], i)); - vector_release(&v[0]); - vector_release(&v[1]); +void plug_end(const Gwion gwion, PlugInfo v) { + for(m_uint i = 0; i < vector_size(&v[GWPLUG_MODULE]); ++i) { + struct Plug_ *plug = (struct Plug_*)vector_at(&v[GWPLUG_MODULE], i); + if(plug->end) + plug->end(gwion, plug->self); + mp_free(Plug, plug); + } + for(m_uint i = 0; i < vector_size(&v[GWPLUG_DL]); ++i) + dlclose((void*)vector_at(&v[GWPLUG_DL], i)); + for(m_uint i = 0; i < GWPLUG_LAST; ++i) + vector_release(&v[i]); +} + +ANN static Vector get_arg(const m_str name, const Vector v) { + const size_t len = strlen(name); + for(m_uint i = vector_size(v) + 1; --i;) { + const m_str str = (m_str)vector_at(v, i - 1); + const m_str arg = strchr(str, '='); + if(!strncmp(name, str, len)) { + m_str c, d = strdup(arg+1); + c = d; + const Vector args = new_vector(); + while(d) + vector_add(args, (vtype)strdup(strsep(&d, ","))); + free(d); + free(c); + return args; + } + } + return NULL; +} + +void module_ini(const Gwion gwion, Vector v, Vector args) { + for(m_uint i = 0; i < vector_size(v); ++i) { + struct Plug_ *plug = (struct Plug_*)vector_at(v, i); + const Vector arg = get_arg(plug->name, args); + plug->self = plug->ini(gwion, arg); + if(arg) { + for(m_uint i = 0; i < vector_size(arg); ++i) + xfree((m_str)vector_at(arg, i)); + free_vector(arg); + } + } } diff --git a/tests/import/basic_module.c b/tests/import/basic_module.c new file mode 100644 index 000000000..0aa21e6ef --- /dev/null +++ b/tests/import/basic_module.c @@ -0,0 +1,23 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "oo.h" +#include "vm.h" +#include "env.h" +#include "gwion.h" +#include "plug.h" +#include "module.h" + +GWMODNAME("basic_module") + +GWMODINI(basic_module) { + puts("ini module"); + if(args) { + puts("have arguments"); + for(vtype i = 0; i < vector_size(args); ++i) + puts((m_str)vector_at(args, i)); + } +} + +GWMODEND(basic_module) { + puts("end module"); +} diff --git a/tests/sh/plugin.sh b/tests/sh/plugin.sh index bd14c626a..705a73fba 100644 --- a/tests/sh/plugin.sh +++ b/tests/sh/plugin.sh @@ -1,5 +1,5 @@ #!/bin/bash -# [test] #26 +# [test] #27 n=0 [ "$1" ] && n="$1" diff --git a/tests/error/switch_in.gw b/tests/tree/nested_switch.gw similarity index 72% rename from tests/error/switch_in.gw rename to tests/tree/nested_switch.gw index 098f0ff5c..fabddf099 100644 --- a/tests/error/switch_in.gw +++ b/tests/tree/nested_switch.gw @@ -1,5 +1,3 @@ -// [skip] -// [contains] swith inside an other switch switch(maybe) { case 1: <<<1>>>;break; case 0: From 6b2bf76e689ac6ae6655bac10fbe337ccf5b14f3 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 22 Feb 2019 14:39:28 +0100 Subject: [PATCH 49/59] :art: Remove used module argument string --- src/plug.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plug.c b/src/plug.c index 69ae120da..d00fd51dd 100644 --- a/src/plug.c +++ b/src/plug.c @@ -91,6 +91,7 @@ ANN static Vector get_arg(const m_str name, const Vector v) { vector_add(args, (vtype)strdup(strsep(&d, ","))); free(d); free(c); + vector_rem(v, i-1); return args; } } From b2a1e4b20890857233d8c4e1447723f1d3256dc4 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 22 Feb 2019 15:12:46 +0100 Subject: [PATCH 50/59] :art: Gwion contains plug info --- include/gwion.h | 6 +++-- include/module.h | 17 ------------- include/plug.h | 17 ++++++++++++- src/gwion.c | 5 +++- src/main.c | 49 +++++++++++++------------------------ src/plug.c | 7 +++--- tests/import/basic_module.c | 2 -- 7 files changed, 45 insertions(+), 58 deletions(-) delete mode 100644 include/module.h diff --git a/include/gwion.h b/include/gwion.h index 604195344..7d8c78556 100644 --- a/include/gwion.h +++ b/include/gwion.h @@ -1,10 +1,12 @@ #ifndef __GWION #define __GWION typedef struct Gwion_* Gwion; +#include "plug.h" struct Gwion_ { // Vector args // PlugInfo // => Vector v[GWION_NVEC]; + PlugInfo plug; // sym // mem // rnd @@ -13,6 +15,6 @@ struct Gwion_ { Emitter emit; VM* vm; }; -ANN void gwion_init(Gwion gwion); -ANN void gwion_release(Gwion gwion); +ANN void gwion_init(const Gwion, const Vector); +ANN void gwion_release(const Gwion gwion); #endif diff --git a/include/module.h b/include/module.h deleted file mode 100644 index f6a533840..000000000 --- a/include/module.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __MODULE -#define __MODULE -#define GWMODNAME_NAME "gwmodname" -#define GWMODINI_NAME "gwmodini" -#define GWMODEND_NAME "gwmodend" -#define GWMODNAME_FUNC gwmodname -#define GWMODINI_FUNC gwmodini -#define GWMODEND_FUNC gwmodend -#define GWMODNAME(a) m_str GWMODNAME_FUNC() { return a; } -#define GWMODINI(a) ANN void* GWMODINI_FUNC(const Gwion gwion, const Vector args) -#define GWMODEND(a) ANN void GWMODEND_FUNC(const Gwion gwion, void* self) - -//typedef void* (*f_gwmodname)(void); -typedef void* (*f_gwmodini)(const Gwion, const Vector); -typedef void* (*f_gwmodend)(const Gwion, void*); -void module_ini(const Gwion gwion, Vector v, Vector); -#endif diff --git a/include/plug.h b/include/plug.h index fb437a0f7..4ee5e4ca0 100644 --- a/include/plug.h +++ b/include/plug.h @@ -10,5 +10,20 @@ enum plug_t { typedef struct Vector_ PlugInfo[GWPLUG_LAST]; void plug_ini(PlugInfo, Vector); -void plug_end(const Gwion gwion, PlugInfo); +void plug_end(const Gwion gwion); + +#define GWMODNAME_NAME "gwmodname" +#define GWMODINI_NAME "gwmodini" +#define GWMODEND_NAME "gwmodend" +#define GWMODNAME_FUNC gwmodname +#define GWMODINI_FUNC gwmodini +#define GWMODEND_FUNC gwmodend +#define GWMODNAME(a) m_str GWMODNAME_FUNC() { return a; } +#define GWMODINI(a) ANN void* GWMODINI_FUNC(const Gwion gwion, const Vector args) +#define GWMODEND(a) ANN void GWMODEND_FUNC(const Gwion gwion, void* self) + +//typedef void* (*f_gwmodname)(void); +typedef void* (*f_gwmodini)(const Gwion, const Vector); +typedef void* (*f_gwmodend)(const Gwion, void*); +void module_ini(const Gwion gwion, Vector); #endif diff --git a/src/gwion.c b/src/gwion.c index d8ab56676..b624afd14 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -6,17 +6,20 @@ #include "instr.h" #include "emit.h" #include "gwion.h" +#include "arg.h" -ANN void gwion_init(const Gwion gwion) { +ANN void gwion_init(const Gwion gwion, const Vector args) { gwion->vm = new_vm(); gwion->emit = new_emitter(); gwion->env = new_env(); gwion->emit->env = gwion->env; gwion->vm->gwion = gwion; gwion->env->gwion = gwion; + plug_ini(gwion->plug, args); } ANN void gwion_release(const Gwion gwion) { + plug_end(gwion); free_env(gwion->env); free_emitter(gwion->emit); free_vm(gwion->vm); diff --git a/src/main.c b/src/main.c index e577fcefe..4cc65fbd8 100644 --- a/src/main.c +++ b/src/main.c @@ -1,9 +1,6 @@ #include #include #include -#include -#include // arg memset -#include #include "gwion_util.h" #include "gwion_ast.h" #include "oo.h" @@ -30,8 +27,6 @@ #endif #include "gwion.h" -#include "plug.h" -#include "module.h" extern void parse_args(Arg*, DriverInfo*); static VM* some_static_vm; @@ -42,7 +37,7 @@ static void sig(int unused __attribute__((unused))) { int main(int argc, char** argv) { Driver d = { }; - Arg arg = { .argc = argc, .argv=argv, .loop=-1, .quit=0}; + Arg arg = { .argc = argc, .argv=argv, .loop=-1 }; DriverInfo di = { 2, 2, 2, 48000, 256, 3, "default:CARD=CODEC", 0, 0, D_FUNC, vm_run, 0, 0}; @@ -55,40 +50,30 @@ int main(int argc, char** argv) { //setvbuf(stderr, buf2, _IOFBF, STD_BUFSZ); parse_args(&arg, &di); -struct Gwion_ gwion; - - if(arg.quit) - goto clean; + if(arg.quit) { + arg_release(&arg); + return 0; + } signal(SIGINT, sig); signal(SIGTERM, sig); - -// init_symbols(); - PlugInfo pi; -// gwion.pi = pi; - plug_ini(pi, &arg.lib); - - - gwion_init(&gwion); + struct Gwion_ gwion; + gwion_init(&gwion, &arg.lib); some_static_vm = gwion.vm; di.func(&d); shreduler_set_loop(gwion.vm->shreduler, arg.loop); - if(d.ini(gwion.vm, &di) < 0 || !(gwion.vm->bbq = new_bbq(&di))) - goto clean; - if(type_engine_init(gwion.vm, &pi[GWPLUG_IMPORT]) < 0) - goto clean; - module_ini(&gwion, &pi[GWPLUG_MODULE], &arg.mod); - srand((uint)time(NULL)); - for(m_uint i = 0; i < vector_size(&arg.add); i++) - compile_filename(&gwion, (m_str)vector_at(&arg.add, i)); - gwion.vm->is_running = 1; - VMBENCH_INI - d.run(gwion.vm, &di); - VMBENCH_END -clean: + if(d.ini(gwion.vm, &di) > 0 && (gwion.vm->bbq = new_bbq(&di)) && + type_engine_init(gwion.vm, &gwion.plug[GWPLUG_IMPORT]) > 0) { + module_ini(&gwion, &arg.mod); + for(m_uint i = 0; i < vector_size(&arg.add); i++) + compile_filename(&gwion, (m_str)vector_at(&arg.add, i)); + gwion.vm->is_running = 1; + VMBENCH_INI + d.run(gwion.vm, &di); + VMBENCH_END + } arg_release(&arg); if(d.del) d.del(gwion.vm, &di); - plug_end(&gwion, pi); gwion_release(&gwion); return 0; } diff --git a/src/plug.c b/src/plug.c index d00fd51dd..402f38228 100644 --- a/src/plug.c +++ b/src/plug.c @@ -13,7 +13,6 @@ #include "import.h" #include "gwion.h" #include "plug.h" -#include "module.h" static inline int so_filter(const struct dirent* dir) { return strstr(dir->d_name, ".so") ? 1 : 0; @@ -65,7 +64,8 @@ void plug_ini(PlugInfo v, Vector list) { } } -void plug_end(const Gwion gwion, PlugInfo v) { +void plug_end(const Gwion gwion) { + struct Vector_ *v = gwion->plug; for(m_uint i = 0; i < vector_size(&v[GWPLUG_MODULE]); ++i) { struct Plug_ *plug = (struct Plug_*)vector_at(&v[GWPLUG_MODULE], i); if(plug->end) @@ -98,7 +98,8 @@ ANN static Vector get_arg(const m_str name, const Vector v) { return NULL; } -void module_ini(const Gwion gwion, Vector v, Vector args) { +void module_ini(const Gwion gwion, Vector args) { + Vector v = &gwion->plug[GWPLUG_MODULE]; for(m_uint i = 0; i < vector_size(v); ++i) { struct Plug_ *plug = (struct Plug_*)vector_at(v, i); const Vector arg = get_arg(plug->name, args); diff --git a/tests/import/basic_module.c b/tests/import/basic_module.c index 0aa21e6ef..ac464588f 100644 --- a/tests/import/basic_module.c +++ b/tests/import/basic_module.c @@ -4,8 +4,6 @@ #include "vm.h" #include "env.h" #include "gwion.h" -#include "plug.h" -#include "module.h" GWMODNAME("basic_module") From 1630cfd1c0d2accaff53249d2bd499116335c49e Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 22 Feb 2019 15:13:42 +0100 Subject: [PATCH 51/59] :shirt: Remove useless header --- src/plug.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plug.c b/src/plug.c index 402f38228..4729fa364 100644 --- a/src/plug.c +++ b/src/plug.c @@ -12,7 +12,6 @@ #include "object.h" #include "import.h" #include "gwion.h" -#include "plug.h" static inline int so_filter(const struct dirent* dir) { return strstr(dir->d_name, ".so") ? 1 : 0; From 24c6db59a01b2e11e26a24924b248c65f5884379 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 22 Feb 2019 16:17:47 +0100 Subject: [PATCH 52/59] :art: Improve main and args --- include/arg.h | 4 +--- include/gwion.h | 11 +++++---- src/arg.c | 23 +++++++++--------- src/gwion.c | 40 ++++++++++++++++++++++++++++++- src/main.c | 62 +++++++++++-------------------------------------- 5 files changed, 71 insertions(+), 69 deletions(-) diff --git a/include/arg.h b/include/arg.h index 2e4d19dfe..46f488c37 100644 --- a/include/arg.h +++ b/include/arg.h @@ -7,11 +7,9 @@ typedef struct { struct Vector_ rem; struct Vector_ lib; struct Vector_ mod; - Vector ref; m_bool loop; - unsigned quit : 1; } Arg; -ANN void arg_init(Arg* arg); ANN void arg_release(Arg* arg); +ANN uint parse_args(Arg*, DriverInfo*); #endif diff --git a/include/gwion.h b/include/gwion.h index 7d8c78556..06c6eaff0 100644 --- a/include/gwion.h +++ b/include/gwion.h @@ -2,11 +2,11 @@ #define __GWION typedef struct Gwion_* Gwion; #include "plug.h" +#include "driver.h" struct Gwion_ { -// Vector args -// PlugInfo -// => Vector v[GWION_NVEC]; PlugInfo plug; + Driver* driver; +// scanner // sym // mem // rnd @@ -16,5 +16,8 @@ struct Gwion_ { VM* vm; }; ANN void gwion_init(const Gwion, const Vector); -ANN void gwion_release(const Gwion gwion); +ANN m_bool gwion_audio(const Gwion gwion, DriverInfo* di); +ANN void gwion_run(const Gwion gwion, DriverInfo* di); +ANN m_bool gwion_engine(const Gwion gwion); +ANN void gwion_release(const Gwion gwion, DriverInfo* di); #endif diff --git a/src/arg.c b/src/arg.c index 9564d8eb9..6d51f2f00 100644 --- a/src/arg.c +++ b/src/arg.c @@ -1,22 +1,17 @@ -#include -#include #include #include #include "gwion_util.h" -#include "gwion_ast.h" -#include "map_private.h" -#include "arg.h" #include "oo.h" #include "vm.h" #include "driver.h" +#include "arg.h" -ANN void arg_init(Arg* arg) { +ANN static void arg_init(Arg* arg) { vector_init(&arg->add); vector_init(&arg->rem); vector_init(&arg->lib); vector_init(&arg->mod); vector_add(&arg->lib, (vtype)GWPLUG_DIR); - arg->ref = &arg->add; } ANN void arg_release(Arg* arg) { @@ -82,16 +77,17 @@ static const char usage[] = ; ANN static void arg_add(Arg* arg) { + Vector ref = &arg->add; while(optind < arg->argc) { m_str str = arg->argv[optind++]; if(!strcmp(str, "-")) { - arg->ref = &arg->rem; + ref = &arg->rem; str = arg->argv[optind++]; } else if(!strcmp(str, "+")) { - arg->ref = &arg->add; + ref = &arg->add; str = arg->argv[optind++]; } - vector_add(arg->ref, (vtype)str); + vector_add(ref, (vtype)str); } } @@ -137,8 +133,10 @@ ANN static void arg_drvr(DriverInfo* di, const int i) { } } -ANN void parse_args(Arg* arg, DriverInfo* di) { +ANN uint parse_args(Arg* arg, DriverInfo* di) { + uint quit = 0; int i, index; + arg_init(arg); while((i = getopt_long(arg->argc, arg->argv, "?vqh:p:i:o:n:b:e:s:d:l:g:-:rc:f:m:P:C ", long_option, &index)) != -1) { switch(i) { @@ -150,7 +148,7 @@ ANN void parse_args(Arg* arg, DriverInfo* di) { exit(1); break; case 'q': - arg->quit = 1; + quit = 1; break; case 'l': arg->loop = strtol(optarg, NULL, 10) > 0 ? 1 : -1; @@ -166,4 +164,5 @@ ANN void parse_args(Arg* arg, DriverInfo* di) { } } arg_add(arg); + return quit; } diff --git a/src/gwion.c b/src/gwion.c index b624afd14..3a149cfd0 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -5,9 +5,24 @@ #include "env.h" #include "instr.h" #include "emit.h" +#include "engine.h" #include "gwion.h" #include "arg.h" + +#ifdef VMBENCH +#include +#include +#define VMBENCH_INI struct timespec ini, end, ret; \ + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ini); +#define VMBENCH_END clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); \ + timespecsub(&end, &ini, &ret); \ + printf("timespec %lu.%09lu\n", ret.tv_sec, ret.tv_nsec); +#else +#define VMBENCH_INI +#define VMBENCH_END +#endif + ANN void gwion_init(const Gwion gwion, const Vector args) { gwion->vm = new_vm(); gwion->emit = new_emitter(); @@ -15,10 +30,33 @@ ANN void gwion_init(const Gwion gwion, const Vector args) { gwion->emit->env = gwion->env; gwion->vm->gwion = gwion; gwion->env->gwion = gwion; + gwion->driver = (Driver*)xcalloc(1, sizeof(Driver)); plug_ini(gwion->plug, args); } -ANN void gwion_release(const Gwion gwion) { +ANN m_bool gwion_audio(const Gwion gwion, DriverInfo* di) { + di->func(gwion->driver); + VM* vm = gwion->vm; + return gwion->driver->ini(vm, di) > 0 && + (vm->bbq = new_bbq(di)); +} + +ANN m_bool gwion_engine(const Gwion gwion) { + return type_engine_init(gwion->vm, &gwion->plug[GWPLUG_IMPORT]) > 0; +} + +ANN void gwion_run(const Gwion gwion, DriverInfo* di) { + VM* vm = gwion->vm; + vm->is_running = 1; + VMBENCH_INI + gwion->driver->run(vm, di); + VMBENCH_END +} + +ANN void gwion_release(const Gwion gwion, DriverInfo* di) { + if(gwion->driver->del) + gwion->driver->del(gwion->vm, di); + xfree(gwion->driver); plug_end(gwion); free_env(gwion->env); free_emitter(gwion->emit); diff --git a/src/main.c b/src/main.c index 4cc65fbd8..973e95f77 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,3 @@ -#include -#include #include #include "gwion_util.h" #include "gwion_ast.h" @@ -8,72 +6,38 @@ #include "env.h" #include "compile.h" #include "driver.h" -#include "arg.h" -#include "engine.h" - -#ifdef VMBENCH -#include -#include -#define VMBENCH_INI \ - struct timespec ini, end, ret; \ - clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ini); -#define VMBENCH_END \ - clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); \ - timespecsub(&end, &ini, &ret); \ - printf("timespec %lu.%09lu\n", ret.tv_sec, ret.tv_nsec); -#else -#define VMBENCH_INI -#define VMBENCH_END -#endif - #include "gwion.h" +#include "arg.h" -extern void parse_args(Arg*, DriverInfo*); -static VM* some_static_vm; +static struct Gwion_ gwion; static void sig(int unused __attribute__((unused))) { - some_static_vm->is_running = 0; + gwion.vm->is_running = 0; } int main(int argc, char** argv) { - Driver d = { }; Arg arg = { .argc = argc, .argv=argv, .loop=-1 }; DriverInfo di = { 2, 2, 2, 48000, 256, 3, "default:CARD=CODEC", 0, 0, D_FUNC, vm_run, 0, 0}; - - arg_init(&arg); - -//#define STD_BUFSZ 10000 -//char buf[STD_BUFSZ]; -//setvbuf(stdout, buf, _IOFBF, STD_BUFSZ); -//char buf2[STD_BUFSZ]; -//setvbuf(stderr, buf2, _IOFBF, STD_BUFSZ); - - parse_args(&arg, &di); - if(arg.quit) { +//#define BUFSZ 10000 +//char outbuf[BUFSZ], errbuf[BUFSZ]; +//setvbuf(stdout, outbuf, _IOFBF, BUFSZ); +//setvbuf(stderr, errbuf, _IOFBF, BUFSZ); + if(parse_args(&arg, &di)) { arg_release(&arg); return 0; } + gwion_init(&gwion, &arg.lib); signal(SIGINT, sig); signal(SIGTERM, sig); - struct Gwion_ gwion; - gwion_init(&gwion, &arg.lib); - some_static_vm = gwion.vm; - di.func(&d); - shreduler_set_loop(gwion.vm->shreduler, arg.loop); - if(d.ini(gwion.vm, &di) > 0 && (gwion.vm->bbq = new_bbq(&di)) && - type_engine_init(gwion.vm, &gwion.plug[GWPLUG_IMPORT]) > 0) { + if(gwion_audio(&gwion, &di) && gwion_engine(&gwion)) { module_ini(&gwion, &arg.mod); for(m_uint i = 0; i < vector_size(&arg.add); i++) compile_filename(&gwion, (m_str)vector_at(&arg.add, i)); - gwion.vm->is_running = 1; - VMBENCH_INI - d.run(gwion.vm, &di); - VMBENCH_END + shreduler_set_loop(gwion.vm->shreduler, arg.loop); + gwion_run(&gwion, &di); } arg_release(&arg); - if(d.del) - d.del(gwion.vm, &di); - gwion_release(&gwion); + gwion_release(&gwion, &di); return 0; } From ce186cd9a4a52566f51c12fb6a01288821bcd583 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 22 Feb 2019 16:24:35 +0100 Subject: [PATCH 53/59] :art: Reduce variable scope --- src/plug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plug.c b/src/plug.c index 4729fa364..2593bd8c2 100644 --- a/src/plug.c +++ b/src/plug.c @@ -81,8 +81,8 @@ ANN static Vector get_arg(const m_str name, const Vector v) { const size_t len = strlen(name); for(m_uint i = vector_size(v) + 1; --i;) { const m_str str = (m_str)vector_at(v, i - 1); - const m_str arg = strchr(str, '='); if(!strncmp(name, str, len)) { + const m_str arg = strchr(str, '='); m_str c, d = strdup(arg+1); c = d; const Vector args = new_vector(); From f3960e435cce0b0e95786748eaf37f17fa20cc6f Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 22 Feb 2019 16:27:54 +0100 Subject: [PATCH 54/59] :art: Remove useless functions --- include/env.h | 1 - include/import.h | 2 -- src/lib/import.c | 5 ----- src/oo/env.c | 10 ---------- 4 files changed, 18 deletions(-) diff --git a/include/env.h b/include/env.h index 629829285..53ae30f96 100644 --- a/include/env.h +++ b/include/env.h @@ -48,7 +48,6 @@ ANN m_bool compat_func(const __restrict__ Func_Def, const __restrict__ Func_Def) ANN Type known_type(const Env env, const Type_Decl*); ANN m_bool env_access(const Env env, const ae_flag flag); ANN void env_storage(const Env env, ae_flag* flag); -ANN2(1,2) void env_add_value(const Env, const m_str, const Type, const m_bool, void*); ANN void env_add_type(const Env, const Type); ANN Type find_type(const Env, ID_List); ANN m_bool already_defined(const Env env, const Symbol s, const uint pos); diff --git a/include/import.h b/include/import.h index c27a6a1c3..a32d4591e 100644 --- a/include/import.h +++ b/include/import.h @@ -34,8 +34,6 @@ typedef struct Gwi_* Gwi; ANN VM* gwi_vm(const Gwi); ANN2(1,2) ANEW Type gwi_mk_type(const Gwi, const m_str, const m_uint, const Type); ANN m_int gwi_add_type(const Gwi gwi, Type type); -ANN2(1,2,3)m_int gwi_add_value(const Gwi gwi, const m_str name, Type type, const m_bool is_const, void* data); - ANN2(1,2)m_int gwi_class_ini(const Gwi gwi, const Type type, const f_xtor pre_ctor, const f_xtor dtor); ANN m_int gwi_class_ext(const Gwi gwi, Type_Decl* td); ANN m_int gwi_class_end(const Gwi gwi); diff --git a/src/lib/import.c b/src/lib/import.c index 233e53ece..397e6d3d6 100644 --- a/src/lib/import.c +++ b/src/lib/import.c @@ -636,8 +636,3 @@ ANN m_int gwi_enum_end(const Gwi gwi) { free_stmt(stmt); return GW_OK; } - -m_int gwi_add_value(Gwi gwi, const m_str name, Type type, const m_bool is_const, void* value) { - env_add_value(gwi->env, name, type, is_const, value); - return GW_OK; -} diff --git a/src/oo/env.c b/src/oo/env.c index 88a0da91d..de50af360 100644 --- a/src/oo/env.c +++ b/src/oo/env.c @@ -75,16 +75,6 @@ ANN void env_pop(const Env env, const m_uint scope) { env->scope = scope; } -ANN2(1,2) void env_add_value(const Env env, const m_str name, const Type type, - const m_bool is_const, void* data) { - const Value v = new_value(env->gwion, type, name); - ae_flag flag = ae_flag_checked | ae_flag_global | ae_flag_builtin | (is_const ? ae_flag_const : 0); - v->flag = flag; - v->d.ptr = data; - v->owner = env->global_nspc; - nspc_add_value(env->global_nspc, insert_symbol(name), v); -} - ANN void env_add_type(const Env env, const Type type) { const Type v_type = type_copy(t_class); v_type->d.base_type = type; From d9c754f3bec4d67c71b1a556a9d0a98a00a9516c Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 22 Feb 2019 16:38:27 +0100 Subject: [PATCH 55/59] :wrench: BCH ignore headers --- .bettercodehub.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.bettercodehub.yml b/.bettercodehub.yml index aa9927009..b32b0a522 100644 --- a/.bettercodehub.yml +++ b/.bettercodehub.yml @@ -8,6 +8,7 @@ languages: exclude: - /src/drvr/.*\.c - /src/vm/vm.c + - include/.*\.h test: include: - /tests/test_plugins/.*\.c From a89005c27cd0dd4e68d101b859f6ab978b7d1203 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 22 Feb 2019 16:42:44 +0100 Subject: [PATCH 56/59] :wrench: BCH ignore headers, for real --- .bettercodehub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bettercodehub.yml b/.bettercodehub.yml index b32b0a522..0851a90ad 100644 --- a/.bettercodehub.yml +++ b/.bettercodehub.yml @@ -8,7 +8,7 @@ languages: exclude: - /src/drvr/.*\.c - /src/vm/vm.c - - include/.*\.h + - /include/.*\.h test: include: - /tests/test_plugins/.*\.c From 1d6d8f4e2618828b7506c007e87274e2022b2cc6 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 22 Feb 2019 16:53:13 +0100 Subject: [PATCH 57/59] :wrench: BCH tests --- .bettercodehub.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.bettercodehub.yml b/.bettercodehub.yml index 0851a90ad..040c4125a 100644 --- a/.bettercodehub.yml +++ b/.bettercodehub.yml @@ -9,9 +9,10 @@ languages: - /src/drvr/.*\.c - /src/vm/vm.c - /include/.*\.h + - /tests/import/.*\.c test: include: - - /tests/test_plugins/.*\.c + - /tests/import/.*\.c - name: go production: From ce5f9fb2f36503f00f6a89d4493a57dbf1f73df6 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sat, 23 Feb 2019 09:30:39 +0100 Subject: [PATCH 58/59] :bug: Fix member dynamicity --- src/emit/emit.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/emit/emit.c b/src/emit/emit.c index 0351e09e8..6dab88398 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -747,6 +747,11 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f) { GWDEBUG_EXE } else if((f->value_ref->owner_class && is_special(f->value_ref->owner_class) > 0) || !f->value_ref->owner_class || GET_FLAG(f, template)) push_func_code(emit, f); + else { + const Instr back = (Instr)vector_back(&emit->code->instr); + if((f_instr)back->opcode == DotFunc) + back->m_val = f->vt_index; + } const Instr offset = emit_add_instr(emit, RegSetImm); offset->m_val = emit_code_offset(emit); const Instr instr = emit_call(emit, f); From c3b73f5209bda39a1c237b957e5c5fe958e7baee Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sat, 23 Feb 2019 12:57:04 +0100 Subject: [PATCH 59/59] :art: staticother --- src/vm/vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm/vm.c b/src/vm/vm.c index bb1a78e74..b297d8477 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -748,7 +748,7 @@ DISPATCH(); staticother: // LOOP_OPTIM for(m_uint i = 0; i <= instr->m_val2; i += SZ_INT) - *(m_uint*)(reg+i) = *(m_uint*)(instr->m_val + i); + *(m_uint*)(reg+i) = *(m_uint*)((m_bit*)instr->m_val + i); reg += instr->m_val2; DISPATCH() dotfunc: