-template<A> fun void test(A a) { <<<a>>>; }
+template<~A~> fun void test(A a) { <<<a>>>; }
1 => test;
1.3 => test;
test(1);
float f;
complex c;
polar p;
- Vec3 v;
- Vec4 w;
+ Vec3 v;
+ Vec4 w;
Object o;
dtor { <<<"dtor">>>; }
}
samp => now;
<<<"and now">>>;
}
- spork test();
+ spork this.test();
}
C c;
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);}
{
12 => int i;
Object o;
+<<<this>>>;
spork {
"test";
second => now;
string s;
- <<< "test spork exp." >>>;
+ <<< this, " test spork exp. " , s>>>;
+
} @=> Shred @shred;
}
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;
--- /dev/null
+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
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
--- /dev/null
+#ifndef __GACK
+#define __GACK
+ANN void gack(const m_bit*, const Instr);
+#endif
#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
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
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);
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);
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
};
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);
struct M_Object_ {
m_bit* data;
Type type_ref;
+// Nspc nspc;//
+ Vector vtable;
struct pool* p;
size_t ref;
};
#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
--- /dev/null
+#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
#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; }
};
ANEW ANN Value new_value(struct Gwion_* gwion, const Type type, const m_str name);
-ANN void free_value(Value a);
#endif
#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
};
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));
--- /dev/null
+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
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);
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);
}
}
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;
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
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;
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
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
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);
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;
}
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);
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;
}
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,
}
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);
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);
}
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;
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;
}
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;
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)) {
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
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;
}
}
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
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);
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));
}
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
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
__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;
}
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);
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;
}
}
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;
#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);
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)
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) {
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;
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))
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)
}
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");
+}
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;
}
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);
#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);
}
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)
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)
}
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);
}
}
}
#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);
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]");
+}
#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) {
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)
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)
__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) {
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); \
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) {
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))
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) = "";
}
#include <stdlib.h>
#include <stdio.h>
-//#include <stdio_ext.h>
#include <signal.h>
#include <getopt.h>
-#include <string.h>
+#include <string.h> // arg memset
#include <pthread.h>
#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"
#endif
#include "plug.h"
-#include <dlfcn.h>
-#include <dirent.h>
extern void parse_args(Arg*, DriverInfo*);
static VM* some_static_vm;
#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;
arg_release(&arg);
if(d.del)
d.del(gwion.vm, &di);
-#ifndef __linux__
- sleep(1);
-#endif
plug_end(pi);
gwion_release(&gwion);
return 0;
#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);
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);
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);
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;
+}
+++ /dev/null
-#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);
-}
#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;
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;
#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)
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;
+}
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;
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) {
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");
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)
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)
}
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);
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));
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);
#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 <string.h>
#include "env.h"
#include "type.h"
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)
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))
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;
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;
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);
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;
}
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);
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);
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;
}
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))
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);
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)
vector_release(v);
out->parent->child.ptr = NULL;
}
- out->parent = NULL;
}
ANN static void shreduler_child(const Shreduler s, const Vector v) {
#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);
shred->me = new_shred(shred);
shreduler_add(vm->shreduler, shred);
shredule(vm->shreduler, shred, .5);
- shred->instr = shred->code->instr;
return shred->xid;
}
#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
#include <bsd/sys/time.h>
#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);
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);
}
#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);
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)
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;
+}
+
-// [contains] NullFuncPtrException
+// [contains] NullPtrException
class C
{
typedef void test();
-// [contains] NullFuncPtrException
+// [contains] NullPtrException
typedef void Test()
Test test;
test();