]> Nishi Git Mirror - gwion.git/commitdiff
:art: Try vm with computed gotos
authorfennecdjay <astor.jeremie@wanadoo.fr>
Fri, 8 Feb 2019 15:16:20 +0000 (16:16 +0100)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Fri, 8 Feb 2019 15:16:20 +0000 (16:16 +0100)
45 files changed:
examples/binary_tmpl.gw
examples/class_coverage.gw
examples/class_spork_func.gw
examples/op2.gw
examples/spork_exp.gw
examples/spork_func.gw
help/opcode.sh [new file with mode: 0644]
include/context.h
include/gack.h [new file with mode: 0644]
include/import.h
include/instr.h
include/nspc.h
include/object.h
include/oo.h
include/opcode.h [new file with mode: 0644]
include/parse.h
include/value.h
include/vm.h
opcode.txt [new file with mode: 0644]
src/emit/emit.c
src/emit/emitter.c
src/lib/array.c
src/lib/float.c
src/lib/func.c
src/lib/gack.c
src/lib/import.c
src/lib/instr.c
src/lib/int.c
src/lib/object.c
src/lib/string.c
src/main.c
src/oo/context.c
src/oo/nspc.c
src/oo/oo.c [deleted file]
src/oo/type.c
src/oo/value.c
src/parse/check.c
src/parse/func.c
src/parse/scan1.c
src/parse/scan2.c
src/vm/shreduler.c
src/vm/vm.c
src/vm/vm_code.c
tests/error/empty_member_ptr.gw
tests/error/func_ptr_empty.gw

index 71a1ae83bc978207f3f459183bf2f1f9682c5a27..60253182f70a03b16d4f9969f3d9981de02920a1 100644 (file)
@@ -1,4 +1,4 @@
-template<A> fun void test(A a) { <<<a>>>; }
+template<~A~> fun void test(A a) { <<<a>>>; }
 1 => test;
 1.3 => test;
 test(1);
index 7e19954e74c14fb3d600674c08c0bd1e26cf9e1f..9bba0ea2e5e37b654a563626233fc27555a5bab1 100644 (file)
@@ -4,8 +4,8 @@ class C
        float f;
        complex c;
        polar p;
-       Vec3 v;
-       Vec4 w;
+  Vec3 v;
+  Vec4 w;
        Object o;
        dtor { <<<"dtor">>>; }
 }
index 14b0d02c33931db0be3b316272a857b7fb7e73eb..e375e598a84c7bbfb302c1065bb73be5cdedec3f 100644 (file)
@@ -5,7 +5,7 @@ class C
     samp => now;
     <<<"and now">>>;
   }
-  spork  test();
+  spork  this.test();
 }
 
 C c;
index fee33bb90781779147140c6d9b9583e46f217fe0..0f1e51a216b1f2ad2153251f5e236120633f8461 100644 (file)
@@ -12,9 +12,9 @@ operator => Vec3    (Vec3    c, C d){ <<<c.z   => d.f>>>; return @(1.2, 6.1, 2.3
 operator => Vec4    (Vec4    c, C d){ <<<"Vec4    => C: ", c.w   => d.f>>>; return @(1.2, 6.1, 2.3, 9.3);}
 
 operator => float   (C d, int     c){ <<<"int   => C: ", c => d.f>>>; return 2.0;}
-operator => float   (C d,  float   f){ <<<"float   => C: ", f     => d.f>>>; return 2.0;}
+operator => float   (C d,  float   f){ <<<"C   => float: ", f     => d.f>>>; return 2.0;}
 
-operator => float   (Vec3 v, float   f){ <<<"float   => C: ", f, v.x => f>>>; return 2.0;}
+operator => float   (Vec3 v, float   f){ <<<"vec3 => C: ", f, " ", v.x => f>>>; return 2.0;}
 
 operator => complex (C d, complex c){ <<<"complex => C: ", c.re  => d.f>>>; return #(1.2, 6.1);}
 operator => polar   (C d, polar   c){ <<<"complex => C: ", c.mod => d.f>>>; return %(2.3, 4.1);}
index 1b539b07842d8aeaa81cb4fb4273582c90d91d9e..8c3e465c9d50a1e4b92f0a880639d589f8863770 100644 (file)
@@ -2,11 +2,13 @@ class C
 {
   12 => int i;
   Object o;
+<<<this>>>;
   spork  {
     "test";
     second => now;
     string s;
-    <<<  "test spork exp." >>>;
+    <<< this,  " test spork exp. " , s>>>;
+
   } @=> Shred @shred;
 }
 
index df34c858aadb063e7c9f7cfba5385bfcec542c58..14252342ee36239d08f1d34797a46c6fb531058a 100644 (file)
@@ -1,13 +1,13 @@
 class C
 {
-  function void test() {
-    <<<"here">>>;
+  function void test(int i) {
+    <<<"here => ", i>>>;
     samp => now;
     <<<"and now">>>;
   }
 }
 
 C c;
-spork c.test();
+spork c.test(2);
 me.yield();
 4::samp => now;
diff --git a/help/opcode.sh b/help/opcode.sh
new file mode 100644 (file)
index 0000000..194df2b
--- /dev/null
@@ -0,0 +1,24 @@
+echo "#ifndef __GWION_OPCODES__"
+echo "#define __GWION_OPCODES__"
+
+list=$(grep -v "#" opcode.txt)
+COUNT=0
+echo "enum {"
+for a in ${list}
+do
+  [ -z "$a" ] || {
+    echo "  $a,"
+    COUNT=$((COUNT+1))
+  }
+done
+echo "};"
+echo ""
+
+for a in ${list}
+do
+  [ -z "$a" ] || echo "#define  $a (f_instr)$a"
+done | column -t
+
+echo "#endif"
+
+echo "generated" "$COUNT" "opcodes" >&2
index 60c42603aa5c3559c61d7c4bca9de3d4380b2264..2846abcb2d1b7247f89fa98b90021a3287add80a 100644 (file)
@@ -12,5 +12,4 @@ struct Context_ {
 ANN2(2) ANEW Context new_context(const Ast, const m_str);
 ANN void load_context(const Context, const Env);
 ANN void unload_context(const Context, const Env);
-ANN void free_context(const Context);
 #endif
diff --git a/include/gack.h b/include/gack.h
new file mode 100644 (file)
index 0000000..54fc7fc
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef __GACK
+#define __GACK
+ANN void gack(const m_bit*, const Instr);
+#endif
index 453ed9339af3e604380d0c1967981f1bffa41504..c27a6a1c3110fcdc9cf30a4aa4c10e1561ba75ff 100644 (file)
@@ -2,16 +2,22 @@
 #define __IMPORT
 #define DLARG_MAX 6
 
-typedef void (*f_xtor)(const M_Object o, const VM_Shred sh);
+typedef void (*f_xtor)(const M_Object o, const m_bit*, const VM_Shred);
+//typedef void (*f_xtor)(const M_Object o, const VM_Shred);
 typedef void (*f_mfun)(const M_Object o, const m_bit* RETURN, const VM_Shred sh);
 typedef void (*f_sfun)(const m_bit* RETURN, const VM_Shred sh);
+//typedef void (*f_sfun)(const m_bit*, const m_bit* RETURN, const VM_Shred sh);
 typedef void (*f_xfun)();
 typedef struct Gwi_* Gwi;
 
 #define MFUN(a) ANN void a(const M_Object o __attribute__((unused)), const m_bit* RETURN __attribute__((unused)), const VM_Shred shred __attribute__((unused)))
 #define SFUN(a) ANN void a(const m_bit* RETURN __attribute__((unused)), const VM_Shred shred __attribute__((unused)))
-#define CTOR(a) ANN void a(const M_Object o, const VM_Shred shred __attribute__((unused)))
-#define DTOR(a) ANN void a(const M_Object o, const VM_Shred shred __attribute__((unused)))
+//#define SFUN(a) ANN void a(const m_bit* mem __attribute__((unused)), const m_bit* RETURN 
+//__attribute__((unused)), const VM_Shred shred __attribute__((unused)))
+#define CTOR(a) ANN void a(const M_Object o, const m_bit* _ __attribute__((unused)), const VM_Shred shred __attribute__((unused)))
+//#define CTOR(a) ANN void a(const M_Object o, const VM_Shred shred __attribute__((unused)))
+#define DTOR(a) ANN void a(const M_Object o, const m_bit* _ __attribute__((unused)), const VM_Shred shred __attribute__((unused)))
+//#define DTOR(a) ANN void a(const M_Object o, const VM_Shred shred __attribute__((unused)))
 #define OP_CHECK(a) ANN Type a(const Env env __attribute__((unused)), void* data __attribute__((unused)))
 #define OP_EMIT(a)  ANN m_bool a(const Emitter emit __attribute__((unused)), void* data __attribute__((unused)))
 #ifdef GWION_BUILTIN
@@ -73,4 +79,8 @@ OP_CHECK(opck_basic_cast);
 OP_CHECK(opck_new);
 OP_EMIT(opem_basic_cast);
 OP_EMIT(opem_new);
+
+
+ANN /*static */ Type_List str2tl(const Env env, const m_str s, m_uint *depth);
+
 #endif
index 9bdbc5cd1ec7fcaf5464fbfd1b34ae1fc19fe324..8b1677be4f694dcaefbe4f6f0624eb4e0a5274c1 100644 (file)
@@ -20,9 +20,14 @@ enum Kind {
 typedef struct Instr_     * Instr;
 typedef void (*f_instr)(const VM_Shred, const Instr);
 struct Instr_ {
-  void (*execute)(const VM_Shred shred, const Instr instr);
-  m_uint m_val, m_val2;
+  m_bit opcode;
+//  union {
+//    m_float f;
+    m_uint m_val;
+//  };
+  m_uint m_val2;
   m_bit ptr[SZ_MINVAL];
+  void (*execute)(const VM_Shred shred, const Instr instr);
 };
 
 INSTR(EOC);
@@ -30,99 +35,19 @@ INSTR(DTOR_EOC);
 INSTR(DtorReturn);
 
 INSTR(RegPushMe);
-INSTR(RegPushNow);
 INSTR(RegPushMaybe);
 
-/* staking */
-INSTR(RegPop);
-INSTR(RegPushImm0);
-INSTR(RegPushImm);
-INSTR(RegPushImm2);
-INSTR(RegPushImm3);
-INSTR(RegPushImm4);
-INSTR(RegPushMemAddr);
-INSTR(MemPushImm);
-INSTR(MemSetImm);
-INSTR(RegPushMem);
-INSTR(RegPushMem2);
-INSTR(RegPushMem3);
-INSTR(RegPushMem4);
-INSTR(RegPushBase);
-INSTR(RegPushBase2);
-INSTR(RegPushBase3);
-INSTR(RegPushBase4);
-INSTR(RegPushPtr);
-INSTR(RegDup);
-INSTR(RegAddRef);
-
 /* branching */
 INSTR(BranchSwitch);
 INSTR(SwitchIni);
 INSTR(SwitchEnd);
-INSTR(BranchEqInt);
-INSTR(BranchNeqInt);
-INSTR(BranchEqFloat);
-INSTR(BranchNeqFloat);
-INSTR(InitLoopCounter);
-INSTR(RegPushDeref);
-INSTR(RegPushDeref2);
-INSTR(RegPushDeref3);
-INSTR(DecIntAddr);
-INSTR(Goto);
-
-/* casting */
-INSTR(CastI2F);
-INSTR(CastF2I);
-
-/* debugging */
-INSTR(Gack);
-
-INSTR(RegPushStr);
-
-INSTR(IntNot);
-INSTR(FloatTimes);
 
 INSTR(ComplexReal);
 INSTR(ComplexImag);
 
-INSTR(AllocWord);
-INSTR(AllocWord2);
-INSTR(AllocWord3);
-INSTR(AllocWord4);
-
 /* function */
-INSTR(SporkExp);
-INSTR(SporkFunc);
-INSTR(FuncUsr);
-INSTR(DotFunc);
-INSTR(FuncStatic);
-INSTR(FuncMember);
-INSTR(FuncPtr);
-INSTR(FuncReturn);
 INSTR(DtorReturn);
 
-/* object */
-INSTR(PreCtor);
-INSTR(ObjectInstantiate);
-INSTR(ObjectAssign);
-INSTR(PushNull);
-INSTR(PushNull2);
-INSTR(PushNull3);
-INSTR(AllocMember4);
-INSTR(DotStatic);
-INSTR(DotStatic2);
-INSTR(DotStatic3);
-INSTR(DotStatic4);
-INSTR(DotImport);
-INSTR(DotImport2);
-INSTR(DotImport3);
-INSTR(DotImport4);
-INSTR(DotMember);
-INSTR(DotMember2);
-INSTR(DotMember3);
-INSTR(DotMember4);
-INSTR(ObjectRelease);
-
 /* array */
 INSTR(ArrayTop);
 INSTR(ArrayBottom);
@@ -144,17 +69,14 @@ INSTR(MemberFunction);
 INSTR(VecMember);
 INSTR(PopArrayClass);
 
-INSTR(GcIni);
-INSTR(GcEnd);
-INSTR(GcAdd);
-
 INSTR(AutoLoopStart);
 INSTR(AutoLoopEnd);
-
+INSTR(DotTmpl);
 // optimizations
 #ifdef OPTIMIZE
 INSTR(PutArgsInMem);
 INSTR(ConstPropSet);
 INSTR(ConstPropGet);
 #endif
+#include "opcode.h"
 #endif
index ccf7d636073e7261eab7e674e81d804ac9c36dee..07c2d5dedd379d54de07d205421fcc1b93d06768 100644 (file)
@@ -17,7 +17,6 @@ struct Nspc_ {
 };
 
 extern ANEW ANN Nspc new_nspc(const m_str name);
-extern ANN void free_nspc(const Nspc a);
 
 extern ANN void nspc_commit(const Nspc);
 //extern ANN void nspc_rollback(const Nspc);
index 20afdbb1e196b45af2a8686a5d6d531673c38b9b..850a0ad6879aa36f38b04f9b95943a6ee398684d 100644 (file)
@@ -4,6 +4,8 @@ typedef struct M_Object_  * M_Object;
 struct M_Object_ {
   m_bit* data;
   Type type_ref;
+//  Nspc nspc;//
+  Vector vtable;
   struct pool* p;
   size_t ref;
 };
index 566898b33a51fe40cd6223f0f9ced679d5ad4690..ec55ede3022d0877b87f77ddfbf1e5fdb7574dba 100644 (file)
@@ -1,25 +1,23 @@
 #ifndef __OO
 #define __OO
 
-typedef struct VM_Object_ * VM_Object;
 typedef struct Type_      * Type;
 typedef struct Nspc_      * Nspc;
 typedef struct Value_     * Value;
 typedef struct Func_      * Func;
-typedef enum {
-  e_nspc_obj,  e_context_obj,
-  e_type_obj, e_value_obj, e_func_obj, e_code_obj
-} e_obj;
 
 struct VM_Object_ {
-  size_t ref_count;
-  e_obj  type;
-} __attribute__((packed));
-
+  uint16_t ref_count; // could be an unsigned short
+  void (*free)(void*);
+};
 
 #define HAS_OBJ struct VM_Object_ obj;
-#define INIT_OO(a, b) { (a)->obj.type = b; (a)->obj.ref_count = 1; }
-#define REM_REF(a)    { rem_ref(&(a)->obj, (a)); }
+#define INIT_OO(a, b) { (a)->obj.ref_count = 1; (a)->obj.free= (void(*)(void*))b; }
+ANN static inline void rem_ref(struct VM_Object_* a, void* ptr) {
+  if(--a->ref_count)
+    return;
+  a->free(ptr);
+}
 #define ADD_REF(a)    { ++(a)->obj.ref_count; }
-ANN void rem_ref(const VM_Object a, void* ptr);
+#define REM_REF(a)    { rem_ref(&(a)->obj, (a)); }
 #endif
diff --git a/include/opcode.h b/include/opcode.h
new file mode 100644 (file)
index 0000000..6af942c
--- /dev/null
@@ -0,0 +1,310 @@
+#ifndef __GWION_OPCODES__
+#define __GWION_OPCODES__
+enum {
+  RegPushImm,
+  RegPushImm2,
+  RegPushImm3,
+  RegPushImm4,
+  RegPushMem,
+  RegPushMem2,
+  RegPushMem3,
+  RegPushMem4,
+  RegPushNow,
+  RegPushBase,
+  RegPushBase2,
+  RegPushBase3,
+  RegPushBase4,
+  RegDup,
+  MemPushImm,
+  MemSetImm,
+  RegPop,
+  RegPushPtr,
+  FuncReturn,
+  Goto,
+  AllocWord,
+  AllocWord2,
+  AllocWord3,
+  AllocWord4,
+  int_plus,
+  int_minus,
+  int_mul,
+  int_div,
+  int_modulo,
+  int_eq,
+  int_neq,
+  int_and,
+  int_or,
+  int_gt,
+  int_ge,
+  int_lt,
+  int_le,
+  int_sl,
+  int_sr,
+  int_sand,
+  int_sor,
+  int_xor,
+  int_negate,
+  IntNot,
+  int_cmp,
+  int_r_assign,
+  int_r_plus,
+  int_r_minus,
+  int_r_mul,
+  int_r_div,
+  int_r_modulo,
+  int_r_sl,
+  int_r_sr,
+  int_r_sand,
+  int_r_sor,
+  int_r_sxor,
+  int_pre_inc,
+  int_pre_dec,
+  int_post_inc,
+  int_post_dec,
+  FloatPlus,
+  FloatMinus,
+  FloatTimes,
+  FloatDivide,
+  float_and,
+  float_or,
+  float_eq,
+  float_neq,
+  float_gt,
+  float_ge,
+  float_lt,
+  float_le,
+  float_negate,
+  float_not,
+  float_r_assign,
+  float_r_plus,
+  float_r_minus,
+  float_r_mul,
+  float_r_div,
+  int_float_plus,
+  int_float_minus,
+  int_float_mul,
+  int_float_div,
+  int_float_and,
+  int_float_or,
+  int_float_eq,
+  int_float_neq,
+  int_float_gt,
+  int_float_ge,
+  int_float_lt,
+  int_float_le,
+  int_float_r_assign,
+  int_float_r_plus,
+  int_float_r_minus,
+  int_float_r_mul,
+  int_float_r_div,
+  float_int_plus,
+  float_int_minus,
+  float_int_mul,
+  float_int_div,
+  float_int_and,
+  float_int_or,
+  float_int_eq,
+  float_int_neq,
+  float_int_gt,
+  float_int_ge,
+  float_int_lt,
+  float_int_le,
+  float_int_r_assign,
+  float_int_r_plus,
+  float_int_r_minus,
+  float_int_r_mul,
+  float_int_r_div,
+  CastI2F,
+  CastF2I,
+  Time_Advance,
+  FuncUsr,
+  FuncMember,
+  FuncStatic,
+  SporkIni,
+  SporkFunc,
+  SporkThis,
+  SporkExp,
+  SporkEnd,
+  FuncPtr,
+  BranchEqInt,
+  BranchNeqInt,
+  BranchEqFloat,
+  BranchNeqFloat,
+  DecIntAddr,
+  InitLoopCounter,
+  ObjectInstantiate,
+  RegAddRef,
+  ObjectAssign,
+  ObjectRelease,
+  GWOP_EXCEPT,
+  AllocMember4,
+  DotMember,
+  DotMember2,
+  DotMember3,
+  DotMember4,
+  DotStatic,
+  DotStatic2,
+  DotStatic3,
+  DotFunc,
+  PushStaticCode,
+  RegPushStr,
+  GcIni,
+  GcAdd,
+  GcEnd,
+  Gack,
+  OP_MAX,
+};
+
+#define  RegPushImm          (f_instr)RegPushImm
+#define  RegPushImm2         (f_instr)RegPushImm2
+#define  RegPushImm3         (f_instr)RegPushImm3
+#define  RegPushImm4         (f_instr)RegPushImm4
+#define  RegPushMem          (f_instr)RegPushMem
+#define  RegPushMem2         (f_instr)RegPushMem2
+#define  RegPushMem3         (f_instr)RegPushMem3
+#define  RegPushMem4         (f_instr)RegPushMem4
+#define  RegPushNow          (f_instr)RegPushNow
+#define  RegPushBase         (f_instr)RegPushBase
+#define  RegPushBase2        (f_instr)RegPushBase2
+#define  RegPushBase3        (f_instr)RegPushBase3
+#define  RegPushBase4        (f_instr)RegPushBase4
+#define  RegDup              (f_instr)RegDup
+#define  MemPushImm          (f_instr)MemPushImm
+#define  MemSetImm           (f_instr)MemSetImm
+#define  RegPop              (f_instr)RegPop
+#define  RegPushPtr          (f_instr)RegPushPtr
+#define  FuncReturn          (f_instr)FuncReturn
+#define  Goto                (f_instr)Goto
+#define  AllocWord           (f_instr)AllocWord
+#define  AllocWord2          (f_instr)AllocWord2
+#define  AllocWord3          (f_instr)AllocWord3
+#define  AllocWord4          (f_instr)AllocWord4
+#define  int_plus            (f_instr)int_plus
+#define  int_minus           (f_instr)int_minus
+#define  int_mul             (f_instr)int_mul
+#define  int_div             (f_instr)int_div
+#define  int_modulo          (f_instr)int_modulo
+#define  int_eq              (f_instr)int_eq
+#define  int_neq             (f_instr)int_neq
+#define  int_and             (f_instr)int_and
+#define  int_or              (f_instr)int_or
+#define  int_gt              (f_instr)int_gt
+#define  int_ge              (f_instr)int_ge
+#define  int_lt              (f_instr)int_lt
+#define  int_le              (f_instr)int_le
+#define  int_sl              (f_instr)int_sl
+#define  int_sr              (f_instr)int_sr
+#define  int_sand            (f_instr)int_sand
+#define  int_sor             (f_instr)int_sor
+#define  int_xor             (f_instr)int_xor
+#define  int_negate          (f_instr)int_negate
+#define  IntNot              (f_instr)IntNot
+#define  int_cmp             (f_instr)int_cmp
+#define  int_r_assign        (f_instr)int_r_assign
+#define  int_r_plus          (f_instr)int_r_plus
+#define  int_r_minus         (f_instr)int_r_minus
+#define  int_r_mul           (f_instr)int_r_mul
+#define  int_r_div           (f_instr)int_r_div
+#define  int_r_modulo        (f_instr)int_r_modulo
+#define  int_r_sl            (f_instr)int_r_sl
+#define  int_r_sr            (f_instr)int_r_sr
+#define  int_r_sand          (f_instr)int_r_sand
+#define  int_r_sor           (f_instr)int_r_sor
+#define  int_r_sxor          (f_instr)int_r_sxor
+#define  int_pre_inc         (f_instr)int_pre_inc
+#define  int_pre_dec         (f_instr)int_pre_dec
+#define  int_post_inc        (f_instr)int_post_inc
+#define  int_post_dec        (f_instr)int_post_dec
+#define  FloatPlus           (f_instr)FloatPlus
+#define  FloatMinus          (f_instr)FloatMinus
+#define  FloatTimes          (f_instr)FloatTimes
+#define  FloatDivide         (f_instr)FloatDivide
+#define  float_and           (f_instr)float_and
+#define  float_or            (f_instr)float_or
+#define  float_eq            (f_instr)float_eq
+#define  float_neq           (f_instr)float_neq
+#define  float_gt            (f_instr)float_gt
+#define  float_ge            (f_instr)float_ge
+#define  float_lt            (f_instr)float_lt
+#define  float_le            (f_instr)float_le
+#define  float_negate        (f_instr)float_negate
+#define  float_not           (f_instr)float_not
+#define  float_r_assign      (f_instr)float_r_assign
+#define  float_r_plus        (f_instr)float_r_plus
+#define  float_r_minus       (f_instr)float_r_minus
+#define  float_r_mul         (f_instr)float_r_mul
+#define  float_r_div         (f_instr)float_r_div
+#define  int_float_plus      (f_instr)int_float_plus
+#define  int_float_minus     (f_instr)int_float_minus
+#define  int_float_mul       (f_instr)int_float_mul
+#define  int_float_div       (f_instr)int_float_div
+#define  int_float_and       (f_instr)int_float_and
+#define  int_float_or        (f_instr)int_float_or
+#define  int_float_eq        (f_instr)int_float_eq
+#define  int_float_neq       (f_instr)int_float_neq
+#define  int_float_gt        (f_instr)int_float_gt
+#define  int_float_ge        (f_instr)int_float_ge
+#define  int_float_lt        (f_instr)int_float_lt
+#define  int_float_le        (f_instr)int_float_le
+#define  int_float_r_assign  (f_instr)int_float_r_assign
+#define  int_float_r_plus    (f_instr)int_float_r_plus
+#define  int_float_r_minus   (f_instr)int_float_r_minus
+#define  int_float_r_mul     (f_instr)int_float_r_mul
+#define  int_float_r_div     (f_instr)int_float_r_div
+#define  float_int_plus      (f_instr)float_int_plus
+#define  float_int_minus     (f_instr)float_int_minus
+#define  float_int_mul       (f_instr)float_int_mul
+#define  float_int_div       (f_instr)float_int_div
+#define  float_int_and       (f_instr)float_int_and
+#define  float_int_or        (f_instr)float_int_or
+#define  float_int_eq        (f_instr)float_int_eq
+#define  float_int_neq       (f_instr)float_int_neq
+#define  float_int_gt        (f_instr)float_int_gt
+#define  float_int_ge        (f_instr)float_int_ge
+#define  float_int_lt        (f_instr)float_int_lt
+#define  float_int_le        (f_instr)float_int_le
+#define  float_int_r_assign  (f_instr)float_int_r_assign
+#define  float_int_r_plus    (f_instr)float_int_r_plus
+#define  float_int_r_minus   (f_instr)float_int_r_minus
+#define  float_int_r_mul     (f_instr)float_int_r_mul
+#define  float_int_r_div     (f_instr)float_int_r_div
+#define  CastI2F             (f_instr)CastI2F
+#define  CastF2I             (f_instr)CastF2I
+#define  Time_Advance        (f_instr)Time_Advance
+#define  FuncUsr             (f_instr)FuncUsr
+#define  FuncMember          (f_instr)FuncMember
+#define  FuncStatic          (f_instr)FuncStatic
+#define  SporkIni            (f_instr)SporkIni
+#define  SporkFunc           (f_instr)SporkFunc
+#define  SporkThis           (f_instr)SporkThis
+#define  SporkExp            (f_instr)SporkExp
+#define  SporkEnd            (f_instr)SporkEnd
+#define  FuncPtr             (f_instr)FuncPtr
+#define  BranchEqInt         (f_instr)BranchEqInt
+#define  BranchNeqInt        (f_instr)BranchNeqInt
+#define  BranchEqFloat       (f_instr)BranchEqFloat
+#define  BranchNeqFloat      (f_instr)BranchNeqFloat
+#define  DecIntAddr          (f_instr)DecIntAddr
+#define  InitLoopCounter     (f_instr)InitLoopCounter
+#define  ObjectInstantiate   (f_instr)ObjectInstantiate
+#define  RegAddRef           (f_instr)RegAddRef
+#define  ObjectAssign        (f_instr)ObjectAssign
+#define  ObjectRelease       (f_instr)ObjectRelease
+#define  GWOP_EXCEPT         (f_instr)GWOP_EXCEPT
+#define  AllocMember4        (f_instr)AllocMember4
+#define  DotMember           (f_instr)DotMember
+#define  DotMember2          (f_instr)DotMember2
+#define  DotMember3          (f_instr)DotMember3
+#define  DotMember4          (f_instr)DotMember4
+#define  DotStatic           (f_instr)DotStatic
+#define  DotStatic2          (f_instr)DotStatic2
+#define  DotStatic3          (f_instr)DotStatic3
+#define  DotFunc             (f_instr)DotFunc
+#define  PushStaticCode      (f_instr)PushStaticCode
+#define  RegPushStr          (f_instr)RegPushStr
+#define  GcIni               (f_instr)GcIni
+#define  GcAdd               (f_instr)GcAdd
+#define  GcEnd               (f_instr)GcEnd
+#define  Gack                (f_instr)Gack
+#define  OP_MAX              (f_instr)OP_MAX
+#endif
index bcd18e3d78477c3b39ecd6b9f5aab54729bff8fb..8b5b554a6502a830788c44e9c7b7a029ff0a26b0 100644 (file)
@@ -1,13 +1,19 @@
 #ifndef __PARSE
 #define __PARSE
 #define RET_NSPC(exp)       \
-++env->scope;         \
+++env->scope;               \
 nspc_push_value(env->curr); \
 const m_bool ret = exp;     \
 nspc_pop_value(env->curr);  \
---env->scope;         \
+--env->scope;               \
 return ret;
 
+#define SET_ACCESS(a,b)       \
+if(GET_FLAG(a, private))      \
+  SET_FLAG(b, private);       \
+else if(GET_FLAG(a, protect)) \
+  SET_FLAG(b, protect);
+
 typedef m_bool (*_exp_func)(const void*, const void*);
 static inline m_bool dummy_func(const void*a __attribute__((unused)),
   const void*b __attribute__((unused))) { return 1; }
index 541ae20443214796722576709153a23c848ce45d..403c28548525145073ed77319ba01830d1c2a1cd 100644 (file)
@@ -16,5 +16,4 @@ struct Value_ {
 };
 
 ANEW ANN Value new_value(struct Gwion_* gwion, const Type type, const m_str name);
-ANN void free_value(Value a);
 #endif
index 628414b272e3f837ed022330046b6520679dd99d..16e24d5fe756400541bbfee836c2cdda0c856488 100644 (file)
@@ -1,18 +1,16 @@
 #ifndef __VM
 #define __VM
 
-#ifdef USE_DOUBLE
-#undef USE_DOUBLE
-#endif
-
 typedef struct VM_Code_* VM_Code;
 struct VM_Code_ {
-  Vector instr;
-  m_str name;
-  m_uint native_func;
-  void* memoize;
+  union {
+    Vector instr;
+    m_uint native_func;
+  };
   size_t stack_depth;
   ae_flag flag;
+  void* memoize;
+  m_str name;
   HAS_OBJ
 };
 
@@ -30,33 +28,31 @@ typedef struct Emitter_   * Emitter;
 typedef struct VM_ {
   Shreduler shreduler;
   struct Vector_ ugen;
-  struct Gwion_* gwion;
   struct BBQ_* bbq;
+  struct Gwion_* gwion;
   uint32_t rand[2];
   volatile unsigned is_running : 1; // => shreduler
 } VM;
 
 typedef struct VM_Shred_* VM_Shred;
 struct VM_Shred_ {
-  Vector instr;
   VM_Code code;
-  VM_Shred parent;
   m_bit* reg;
   m_bit* mem;
-  m_bit* _reg;
   m_bit* base;
+  size_t pc;
+  struct Vector_ gc;
+  m_bit* _reg;
+  VM_Shred prev, next, parent;
   m_str name;
   VM* vm;
-  VM_Shred prev, next;
   Vector args; // passed pointer from compile
   struct M_Object_* me;
   struct Vector_ child;
-  struct Vector_ gc;//, gc1;
-  size_t pc, xid;
+  size_t xid;
   m_float wake_time;
 };
-ANN2(4) ANEW VM_Code new_vm_code(const Vector instr, const m_uint stack_depth, const m_bool need_this, const m_str name);
-ANN void free_vm_code(const VM_Code a);
+ANN2(4) ANEW VM_Code new_vm_code(const Vector instr, const m_uint stack_depth, const ae_flag, const m_str name);
 
 ANN VM_Shred shreduler_get(const Shreduler s) __attribute__((hot));
 ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const m_bool erase)__attribute__((hot));
diff --git a/opcode.txt b/opcode.txt
new file mode 100644 (file)
index 0000000..35ddfcc
--- /dev/null
@@ -0,0 +1,152 @@
+RegPushImm
+RegPushImm2
+RegPushImm3
+RegPushImm4
+RegPushMem
+RegPushMem2
+RegPushMem3
+RegPushMem4
+RegPushNow
+RegPushBase
+RegPushBase2
+RegPushBase3
+RegPushBase4
+RegDup
+MemPushImm
+MemSetImm
+RegPop
+RegPushPtr
+FuncReturn
+Goto
+AllocWord
+AllocWord2
+AllocWord3
+AllocWord4
+int_plus
+int_minus
+int_mul
+int_div
+int_modulo
+int_eq
+int_neq
+int_and
+int_or
+int_gt
+int_ge
+int_lt
+int_le
+int_sl
+int_sr
+int_sand
+int_sor
+int_xor
+int_negate
+IntNot
+int_cmp
+int_r_assign
+int_r_plus
+int_r_minus
+int_r_mul
+int_r_div
+int_r_modulo
+int_r_sl
+int_r_sr
+int_r_sand
+int_r_sor
+int_r_sxor
+int_pre_inc
+int_pre_dec
+int_post_inc
+int_post_dec
+FloatPlus
+FloatMinus
+FloatTimes
+FloatDivide
+float_and
+float_or
+float_eq
+float_neq
+float_gt
+float_ge
+float_lt
+float_le
+float_negate
+float_not
+float_r_assign
+float_r_plus
+float_r_minus
+float_r_mul
+float_r_div
+int_float_plus
+int_float_minus
+int_float_mul
+int_float_div
+int_float_and
+int_float_or
+int_float_eq
+int_float_neq
+int_float_gt
+int_float_ge
+int_float_lt
+int_float_le
+int_float_r_assign
+int_float_r_plus
+int_float_r_minus
+int_float_r_mul
+int_float_r_div
+float_int_plus
+float_int_minus
+float_int_mul
+float_int_div
+float_int_and
+float_int_or
+float_int_eq
+float_int_neq
+float_int_gt
+float_int_ge
+float_int_lt
+float_int_le
+float_int_r_assign
+float_int_r_plus
+float_int_r_minus
+float_int_r_mul
+float_int_r_div
+CastI2F
+CastF2I
+Time_Advance
+FuncUsr
+FuncMember
+FuncStatic
+SporkIni
+SporkFunc
+SporkThis
+SporkExp
+SporkEnd
+FuncPtr
+BranchEqInt
+BranchNeqInt
+BranchEqFloat
+BranchNeqFloat
+DecIntAddr
+InitLoopCounter
+ObjectInstantiate
+RegAddRef
+ObjectAssign
+ObjectRelease
+GWOP_EXCEPT
+AllocMember4
+DotMember
+DotMember2
+DotMember3
+DotMember4
+DotStatic
+DotStatic2
+DotStatic3
+DotFunc
+PushStaticCode
+RegPushStr
+GcIni
+GcAdd
+GcEnd
+Gack
+OP_MAX
index 982f460aa07053e2ff5c5991ed49f844983911e3..3546e55ae7703b85ba83733678244e3926a439d2 100644 (file)
@@ -86,7 +86,7 @@ ANN static m_bool emit_exp(const Emitter emit, Exp exp, const m_bool add_ref);
 ANN static m_bool emit_stmt(const Emitter emit, const Stmt stmt, const m_bool pop);
 ANN static m_bool emit_stmt_list(const Emitter emit, Stmt_List list);
 ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot* member);
-ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def);
+ANN /*static */m_bool emit_func_def(const Emitter emit, const Func_Def func_def);
 
 ANEW static Code* new_code(const Emitter emit, const m_str name) {
   Code* code = mp_alloc(Code);
@@ -143,21 +143,15 @@ ANN static inline m_uint emit_local(const Emitter emit, const m_uint size, const
   return frame_local(emit->code->frame, size, is_obj);
 }
 
-ANN static void emit_pre_ctor_inner(const Emitter emit, const Type type) { GWDEBUG_EXE
-  const Instr instr = emit_add_instr(emit, PreCtor);
-  instr->m_val = (m_uint)type->nspc->pre_ctor;
-  instr->m_val2 = (m_uint)emit_code_offset(emit);
-}
-
 ANN static void emit_pre_ctor(const Emitter emit, const Type type) { GWDEBUG_EXE
   if(type->parent)
     emit_pre_ctor(emit, type->parent);
   if(type->nspc->pre_ctor)
-    emit_pre_ctor_inner(emit, type);
+    emit_ext_ctor(emit, type->nspc->pre_ctor);
   if(GET_FLAG(type, template) && GET_FLAG(type, builtin)) {
     const Type t = template_parent(type);
     if(t->nspc->pre_ctor)
-      emit_pre_ctor_inner(emit, t);
+      emit_ext_ctor(emit, t->nspc->pre_ctor);
   }
 }
 
@@ -183,7 +177,7 @@ ANN ArrayInfo* emit_array_extend_inner(const Emitter emit, const Type t, const E
   info->depth = (m_int)t->array_depth;
   info->base = base;
   const Instr alloc = emit_add_instr(emit, ArrayAlloc);
-  *(ArrayInfo**)alloc->ptr = info;
+  alloc->m_val = (m_uint)info;
   if(isa(base, t_object) > 0) {
     emit_pre_constructor_array(emit, base);
     info->is_obj = 1;
@@ -197,7 +191,7 @@ ANN void emit_ext_ctor(const Emitter emit, const VM_Code code) { GWDEBUG_EXE
   push_f->m_val = (m_uint)code;
   const Instr offset = emit_add_instr(emit, RegPushImm);
   offset->m_val = emit_code_offset(emit);
-  emit_add_instr(emit, FuncMember);
+  emit_add_instr(emit, !GET_FLAG(code, builtin) ? FuncUsr : FuncMember);
 }
 
 ANN m_bool emit_array_extend(const Emitter emit, const Type t, const Exp e) { GWDEBUG_EXE
@@ -209,7 +203,8 @@ ANN m_bool emit_array_extend(const Emitter emit, const Type t, const Exp e) { GW
 ANN2(1,2) m_bool emit_instantiate_object(const Emitter emit, const Type type,
     const Array_Sub array, const uint is_ref) {
   if(type->array_depth) {
-    assert(array && array->exp);
+    assert(array);
+    assert(array->exp);
     ArrayInfo* info = emit_array_extend_inner(emit, type, array->exp);
     CHECK_OB(info)
     info->is_ref = !!is_ref;
@@ -234,14 +229,13 @@ ANN static Instr emit_kind(Emitter emit, const m_uint size, const uint addr, con
   return instr;
 }
 
-static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushDeref }; // caution last
-static const f_instr regpushderef[] = { RegPushDeref, RegPushDeref2, RegPushDeref3,  RegPushDeref }; // caution last
+static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 };
 static const f_instr regpushmem[] = { RegPushMem, RegPushMem2, RegPushMem3, RegPushMem4 };
 static const f_instr regpushbase[] = { RegPushBase, RegPushBase2, RegPushBase3, RegPushBase4 };
-static const f_instr dotstatic[]  = { DotStatic, DotStatic2, DotStatic3, DotStatic4 };
-static const f_instr dotimport[]  = { DotImport, DotImport2, DotImport3, DotImport4 };
+//static const f_instr dotstatic[]  = { DotStatic, DotStatic2, DotStatic3, DotStatic4 };
+static const f_instr dotstatic[]  = { DotStatic, DotStatic2, DotStatic3, RegPushImm };
 static const f_instr dotmember[]  = { DotMember, DotMember2, DotMember3, DotMember4 };
-static const f_instr allocmember[]  = { PushNull, PushNull2, PushNull3, AllocMember4 };
+static const f_instr allocmember[]  = { RegPushImm, RegPushImm2, RegPushImm3, AllocMember4 };
 static const f_instr allocword[]  = { AllocWord, AllocWord2, AllocWord3, AllocWord4 };
 
 ANN static m_bool emit_symbol_owned(const Emitter emit, const Exp_Primary* prim) { GWDEBUG_EXE
@@ -266,18 +260,25 @@ ANN static m_bool emit_symbol_builtin(const Emitter emit, const Exp_Primary* pri
   }
   if(GET_FLAG(v, union)) {
     const m_uint size = v->type->size;
-    const Instr instr = emit_kind(emit, size, prim->self->emit_var, regpushderef);
-    *(m_uint*)instr->ptr = (m_uint)v->d.ptr;
+    const Instr instr = emit_kind(emit, size, prim->self->emit_var, dotstatic);
+    instr->m_val = (m_uint)v->d.ptr;
   } else {
     const m_uint size = v->type->size;
     const Instr instr = emit_kind(emit, size, prim->self->emit_var, regpushimm);
-    if(size == SZ_INT) {
+    if(!prim->self->emit_var && size == SZ_INT) {
+    if(isa(v->type, t_object) > 0) {
       instr->execute = RegPushImm;
       instr->m_val = (m_uint)v->d.ptr;
     } else if(v->d.ptr)
+      instr->m_val = *(m_uint*)v->d.ptr;
+}
+else if(v->d.ptr)
         memcpy(instr->ptr, v->d.ptr, v->type->size);
+//        memcpy(&instr->m_val, v->d.ptr, v->type->size);
     else
       *(m_uint**)instr->ptr = v->d.ptr;
+//      instr->m_val = v->d.ptr;
+    instr->m_val2 = size;
   }
   return GW_OK;
 }
@@ -297,7 +298,7 @@ ANN static m_bool emit_symbol(const Emitter emit, const Exp_Primary* prim) { GWD
 ANEW ANN VM_Code emit_code(const Emitter emit) { GWDEBUG_EXE
   Code* c = emit->code;
   const VM_Code code = new_vm_code(&c->instr, c->stack_depth,
-      GET_FLAG(c, member), c->name);
+      c->flag, c->name);
   free_code(c);
   return code;
 }
@@ -357,7 +358,8 @@ ANN static m_bool prim_vec(const Emitter emit, const Exp_Primary * primary) { GW
   CHECK_BB(emit_exp(emit, vec->exp, 0));
   m_int n = (m_int)((t == ae_primary_vec ? 3 : 2) - vec->dim + 1);
   while(--n > 0)
-    emit_add_instr(emit, PushNull2);
+//    emit_add_instr(emit, PushNull2);
+    emit_add_instr(emit, RegPushImm2);
   return GW_OK;
 }
 
@@ -425,8 +427,8 @@ ANN static m_bool prim_gack(const Emitter emit, const Exp_Primary* primary) {
     ERR_B(exp->pos, "\t... in 'gack' expression.")
   }
   const Instr instr = emit_add_instr(emit, Gack);
-  *(Vector*)instr->ptr = v;
   instr->m_val = offset;
+  instr->m_val2 = (m_uint)v;
   return GW_OK;
 }
 
@@ -453,12 +455,11 @@ ANN static m_bool emit_exp_primary(const Emitter emit, const Exp_Primary* prim)
   return prim_func[prim->primary_type](emit, prim);
 }
 
-ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v, const uint  emit_var) { GWDEBUG_EXE
-  const Instr push = emit_add_instr(emit, RegPushImm);
-  push->m_val = (m_uint)v->owner_class;
+ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v, const uint emit_var) { GWDEBUG_EXE
   const m_uint size = v->type->size;
   const Instr instr = emit_kind(emit, size, emit_var, dotstatic);
-  instr->m_val = v->offset;
+  instr->m_val =  (m_uint)(v->owner_class->nspc->class_data + v->offset);
+  instr->m_val2 = size;
   return GW_OK;
 }
 
@@ -494,10 +495,38 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Var_Decl va
   f_instr *exec = (f_instr*)allocmember;
   if(!GET_FLAG(v, member)) {
     v->offset = emit_local(emit, v->type->size, is_obj);
-    exec = (f_instr*)allocword;
+    exec = (f_instr*)(allocword);
   }
   const Instr instr = emit_kind(emit, v->type->size, emit_addr, exec);
   instr->m_val = v->offset;
+  instr->m_val2 = v->type->size;
+  if(is_obj && (is_array || !is_ref)) {
+    const Instr assign = emit_add_instr(emit, ObjectAssign);
+    assign->m_val = (m_uint)emit_var;
+    if(is_array && !emit->env->scope)
+      ADD_REF(type)
+  }
+  return GW_OK;
+}
+
+ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_decl,
+  const uint is_ref, const uint emit_var) { GWDEBUG_EXE
+  const Value v = var_decl->value;
+  const Type type = v->type;
+  const Array_Sub array = var_decl->array;
+  const m_bool is_array = array && array->exp;
+  const m_bool is_obj = isa(type, t_object) > 0;
+  const uint emit_addr = ((is_ref && !array) || isa(type, t_object) < 0) ?
+    emit_var : 1;
+  if(is_obj && (is_array || !is_ref))
+    CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
+  f_instr *exec = (f_instr*)dotstatic;
+  const Instr instr = emit_kind(emit, v->type->size, emit_addr, exec);
+v->d.ptr = _mp_alloc(v->type->size);
+// here union flag is more like 'treat as builtin'
+SET_FLAG(v, builtin | ae_flag_union);
+  instr->m_val = (m_uint)v->d.ptr;
+  instr->m_val2 = v->type->size;
   if(is_obj && (is_array || !is_ref)) {
     const Instr assign = emit_add_instr(emit, ObjectAssign);
     assign->m_val = (m_uint)emit_var;
@@ -536,8 +565,10 @@ ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) { GWDE
       continue;
     if(GET_FLAG(decl->td, static))
       CHECK_BB(emit_exp_decl_static(emit, list->self, r))
-    else
+    else if(!global)
       CHECK_BB(emit_exp_decl_non_static(emit, list->self, r, var))
+else
+      CHECK_BB(emit_exp_decl_global(emit, list->self, r, var))
   } while((list = list->next));
   if(global)
     emit_pop(emit, scope);
@@ -587,7 +618,8 @@ ANN static inline m_int push_tmpl_func(const Emitter emit, const Func f,
     const Type_List types) {
   const Value v = f->value_ref;
   const m_uint scope = emit_push(emit, v->owner_class, v->owner);
-  CHECK_BB(traverse_func_template(emit->env, f->def, types))
+//  CHECK_BB(traverse_func_template(emit->env, f->def, types))
+  CHECK_BB(traverse_func_template(emit->env, v->d.func_ref->def, types))
   return (m_int)scope;
 }
 
@@ -647,37 +679,71 @@ ANN static m_bool emit_exp_dur(const Emitter emit, const Exp_Dur* dur) { GWDEBUG
   return GW_OK;
 }
 
+ANN static m_bool is_special(const Type t) {
+  if(isa(t, t_complex) > 0 || isa(t, t_polar) > 0 ||
+     isa(t, t_vec3)    > 0 || isa(t, t_vec4)  > 0  ||
+     isa(t, t_vararg)  > 0)
+    return GW_OK;
+  return GW_ERROR;
+}
+
+
 static inline m_bool push_func_code(const Emitter emit, const Func f) {
-  const Instr back = (Instr)vector_back(&emit->code->instr);
-  if(back->execute == RegPushBase) {
-    back->execute = RegPushImm;
-    back->m_val = (m_uint)f->code;
+  if(GET_FLAG(f, template) && f->value_ref->owner_class) {
+  const Instr _instr = (Instr)vector_back(&emit->code->instr);
+assert(_instr->execute == DotTmpl);
+    size_t len = strlen(f->name);
+    size_t sz = len - strlen(f->value_ref->owner_class->name);
+    char c[sz + 1];
+    strncpy(c, f->name, sz);
+    c[sz] = '\0';
+    _instr->m_val = (m_uint)s_name(insert_symbol(c));
+    _instr->m_val2 = strlen(c);
+    *(m_int*)_instr->ptr = f->def->tmpl->base;
     return GW_OK;
   }
   const Instr instr = emit_add_instr(emit, RegPushPtr);
   return !!(instr->m_val = (m_uint)f->code);
 }
-
 static m_bool emit_template_code(const Emitter emit, const Func f) {
   if(GET_FLAG(f, ref))
     CHECK_BB(traverse_template(emit->env, f->value_ref->owner_class->def))
-  CHECK_BB(emit_func_def(emit, f->def))
+  const Value v = f->value_ref;
+  size_t scope = emit_push(emit, v->owner_class, v->owner);
+  CHECK_BB(emit_func_def(emit, f->def)) // orig
+  emit_pop(emit, scope);
+if(!v->owner_class) {
+/* no need for dynamicity */
+//assert(instr->opcode != MemSetImm);
+//assert(instr->opcode == RegPushBase);
+} // else push_tmpl_func
   return push_func_code(emit, f);
 }
 
 ANN static Instr emit_call(const Emitter emit, const Func f) {
   MEMOIZE_CALL
   const Type t = actual_type(f->value_ref->type);
-  const f_instr exec = isa(t, t_fptr) < 0 ? GET_FLAG(f->def, builtin) ?
-     GET_FLAG(f, member) ? FuncMember : FuncStatic : FuncUsr : FuncPtr;
-  return emit_add_instr(emit, exec);
+  if(isa(t, t_fptr) < 0) {
+    const f_instr exec = GET_FLAG(f->def, builtin) ? GET_FLAG(f, member) ?
+       FuncMember : FuncStatic : FuncUsr;
+    return emit_add_instr(emit, exec);
+  }
+  const Instr ex = emit_add_instr(emit, GWOP_EXCEPT);
+  ex->m_val = -SZ_INT*2;
+  return emit_add_instr(emit, FuncPtr);
 }
 
 ANN m_bool emit_exp_call1(const Emitter emit, const Func f) { GWDEBUG_EXE
   if(!f->code || (GET_FLAG(f, ref) && !GET_FLAG(f, builtin))) {
     if(GET_FLAG(f, template) && emit->env->func != f)
       CHECK_BB(emit_template_code(emit, f))
-  } else
+  }
+else if(
+(f->value_ref->owner_class && is_special(f->value_ref->owner_class) > 0) ||
+
+!f->value_ref->owner_class || GET_FLAG(f, template)
+|| (f->value_ref->owner_class && GET_FLAG(f->def, op))
+)
     push_func_code(emit, f);
   const Instr offset = emit_add_instr(emit, RegPushImm);
   offset->m_val = emit_code_offset(emit);
@@ -688,9 +754,25 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f) { GWDEBUG_EXE
 
 ANN2(1,2) static m_bool emit_exp_spork_finish(const Emitter emit, const VM_Code code,
     const m_uint depth, const m_bool f) {
-  const Instr spork = emit_add_instr(emit, f ? SporkExp : SporkFunc);
-  spork->m_val = depth;
-  spork->m_val2 = (m_uint)code;
+  const Instr ini = emit_add_instr(emit, SporkIni);
+  ini->m_val = (m_uint)code;
+  if(!f) {
+    const m_uint member = GET_FLAG(code, member) ? SZ_INT : 0;
+    const Instr pop = emit_add_instr(emit, RegPop);
+    pop->m_val = depth + member;
+    if(depth) {
+      const Instr spork = emit_add_instr(emit, SporkFunc);
+      spork->m_val = depth;
+    }
+    if(member) {
+      const Instr m = emit_add_instr(emit, SporkThis);
+      m->m_val = depth;
+    }
+  } else  {
+    const Instr spork = emit_add_instr(emit, SporkExp);
+    spork->m_val = depth;
+  }
+  emit_add_instr(emit, SporkEnd);
   return GW_OK;
 }
 
@@ -734,7 +816,11 @@ ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) { GWDEBUG_
     SET_FLAG(emit->code, member);
   const Instr op = emit_add_instr(emit, MemPushImm);
   op->m_val = emit->code->stack_depth;
-  emit_add_instr(emit, PushNull); // (was PushImm) should push func
+const Instr p =
+
+  emit_add_instr(emit, RegPushImm);
+  p->m_val = (m_uint)exp->m_func->code;
+
   CHECK_BB(emit_exp_call1(emit, exp->m_func))
   const VM_Code code = finalyze(emit);
   const m_uint size = exp->m_func->def->stack_depth - (GET_FLAG(exp->m_func,
@@ -743,9 +829,10 @@ ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) { GWDEBUG_
 }
 
 ANN static m_bool spork_code(const Emitter emit, const Stmt stmt) { GWDEBUG_EXE
-  emit_add_instr(emit, PushNull); // was PushImm
+  emit_add_instr(emit, RegPushImm);
   push_spork_code(emit, SPORK_CODE_PREFIX, stmt->pos);
-  if(SAFE_FLAG(emit->env->func, member))
+//  if(emit->env->class_def && !SAFE_FLAG(emit->env->func, static))
+  if(!SAFE_FLAG(emit->env->func, member))
     stack_alloc_this(emit);
   CHECK_BB(scoped_stmt(emit, stmt, 0))
   const VM_Code code = finalyze(emit);
@@ -775,10 +862,10 @@ ANN static m_bool emit_implicit_cast(const Emitter emit,
 ANN static Instr emit_flow(const Emitter emit, const Type type,
     const f_instr f1, const f_instr f2) { GWDEBUG_EXE
   if(isa(type, t_float) > 0) {
-    emit_add_instr(emit, PushNull2);
+//    emit_add_instr(emit, RegPushImm2);
     return emit_add_instr(emit, f2);
   }
-  emit_add_instr(emit, PushNull);
+//  emit_add_instr(emit, RegPushImm);
   return emit_add_instr(emit, f1);
 }
 
@@ -881,6 +968,8 @@ ANN static m_bool emit_stmt_return(const Emitter emit, const Stmt_Exp stmt) { GW
   if(stmt->val) {
     OPTIMIZE_TCO
     CHECK_BB(emit_exp(emit, stmt->val, 0))
+    if(isa(stmt->val->type, t_object) > 0)
+      emit_add_instr(emit, RegAddRef);
   }
   vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto));
   return GW_OK;
@@ -1001,13 +1090,17 @@ ANN static m_bool emit_stmt_auto(const Emitter emit, const Stmt_Auto stmt) { GWD
   s2->m_val = stmt->v->offset = offset + SZ_INT;
   CHECK_BB(emit_stmt(emit, stmt->body, 1))
   const m_uint end_pc = emit_code_size(emit);
+  if(stmt->is_ptr) {
+    const Instr release = emit_add_instr(emit, ObjectRelease);
+    release->m_val = offset + SZ_INT;
+  }
   const Instr end = emit_add_instr(emit, AutoLoopEnd);
   const Instr tgt = emit_add_instr(emit, Goto);
-  *(m_uint*)end->ptr = emit_code_size(emit);
+  end->m_val2 = emit_code_size(emit);
   tgt->m_val = ini_pc;
   s1->m_val = end->m_val = loop->m_val = offset;
   if(stmt->is_ptr)
-    end->m_val2 = loop->m_val2 = (m_uint)stmt->v->type;
+    loop->m_val2 = (m_uint)stmt->v->type;
   emit_pop_stack(emit, end_pc);
   return GW_OK;
 }
@@ -1019,10 +1112,10 @@ ANN static m_bool emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt) { GWD
   const Instr init = emit_add_instr(emit, InitLoopCounter);
   init->m_val = (m_uint)counter;
   const m_uint index = emit_code_size(emit);
-  const Instr deref = emit_add_instr(emit, RegPushDeref);
+  const Instr deref = emit_add_instr(emit, DotStatic);
+  deref->m_val = (m_uint)counter;
   deref->m_val2 = SZ_INT;
-  *(m_int**)deref->ptr = counter;
-  emit_add_instr(emit, PushNull);
+//  emit_add_instr(emit, RegPushImm);
   const Instr op = emit_add_instr(emit, BranchEqInt);
   const Instr dec = emit_add_instr(emit, DecIntAddr);
   dec->m_val = (m_uint)counter;
@@ -1250,14 +1343,6 @@ ANN static m_bool emit_stmt_list(const Emitter emit, Stmt_List l) { GWDEBUG_EXE
   return GW_OK;
 }
 
-ANN static m_bool is_special(const Type t) {
-  if(isa(t, t_complex) > 0 || isa(t, t_polar) > 0 ||
-     isa(t, t_vec3)    > 0 || isa(t, t_vec4)  > 0  ||
-     isa(t, t_vararg)  > 0)
-    return GW_OK;
-  return GW_ERROR;
-}
-
 ANN static m_bool emit_dot_static_import_data(const Emitter emit, const Value v, const uint emit_addr) { GWDEBUG_EXE
   if(v->d.ptr && GET_FLAG(v, builtin)) { // from C
     if(GET_FLAG(v, enum)) {
@@ -1265,18 +1350,16 @@ ANN static m_bool emit_dot_static_import_data(const Emitter emit, const Value v,
       func_i->m_val = (m_uint)v->d.ptr;
     } else {
       const m_uint size = v->type->size;
-      const Instr instr = emit_kind(emit, size, emit_addr, dotimport);
+      const Instr instr = emit_kind(emit, size, emit_addr, regpushimm);
       instr->m_val = (isa(v->type, t_object) > 0 ?
         (m_uint)&v->d.ptr : (m_uint)v->d.ptr);
+      *(m_uint**)instr->ptr = (m_uint*)(isa(v->type, t_object) > 0 ?
+        (m_uint*)&v->d.ptr : v->d.ptr);
+      instr->m_val2 = size;
     }
-  } else { // from code
-    const Instr push_i = emit_add_instr(emit, RegPushImm);
-    push_i->m_val = (m_uint)v->owner_class;
-    const m_uint size = v->type->size;
-    const Instr instr = emit_kind(emit, size, emit_addr, dotstatic);
-    instr->m_val =  v->offset;
+    return GW_OK;
   }
-  return GW_OK;
+  return emit_dot_static_data(emit, v, emit_addr);
 }
 
 ANN static m_bool emit_complex_member(const Emitter emit, const Exp_Dot* member) { GWDEBUG_EXE
@@ -1287,8 +1370,7 @@ ANN static m_bool emit_complex_member(const Emitter emit, const Exp_Dot* member)
         s_name(member->xid));
   if(is_complex && member->self->emit_var) // skip
     return GW_OK;
-  const Instr instr = is_complex ? emit_add_instr(emit, ComplexReal) :
-      emit_add_instr(emit, ComplexImag);
+  const Instr instr = emit_add_instr(emit, is_complex ? ComplexReal : ComplexImag);
   instr->m_val = member->self->emit_var;
   return GW_OK;
 }
@@ -1360,26 +1442,43 @@ ANN static m_bool emit_exp_dot_special(const Emitter emit, const Exp_Dot* member
 }
 
 ANN static m_bool emit_dot_static_func(const Emitter emit, const Func func) { GWDEBUG_EXE
-  const Instr func_i = emit_add_instr(emit, RegPushImm);
-  func_i->m_val = (m_uint)func->code;
+//  if(func->code) {
+//    const Instr func_i = emit_add_instr(emit, RegPushImm);
+//    func_i->m_val = (m_uint)func->code;
+//  } else {
+    // TODO: improve me
+    const Instr func_i = emit_add_instr(emit, PushStaticCode);
+    func_i->m_val = (m_uint)func;
+//  }
   return GW_OK;
 }
 
 ANN static m_bool emit_member_func(const Emitter emit, const Exp_Dot* member, const Func func) { GWDEBUG_EXE
-  if(GET_FLAG(func, member)) {
-    if(emit_exp(emit, member->base, 0) < 0)
-      ERR_B(member->self->pos, "... in member function") // LCOV_EXCL_LINE
-    emit_add_instr(emit, RegDup);
+  if(emit_exp(emit, member->base, 0) < 0)
+    ERR_B(member->self->pos, "... in member function") // LCOV_EXCL_LINE
+  const Instr ex = emit_add_instr(emit, GWOP_EXCEPT);
+  ex->m_val = -SZ_INT;
+  if(GET_FLAG(member->base->type, force)) {
+    const Instr func_i = emit_add_instr(emit, RegPushImm);
+    func_i->m_val = (m_uint)func->code;
+    return GW_OK;
+  }
+  if(!func->def->tmpl) {
     const Instr func_i = emit_add_instr(emit, DotFunc);
     func_i->m_val = func->vt_index;
+    return GW_OK;
   }
+  emit_add_instr(emit, DotTmpl);
   return GW_OK;
 }
 
 ANN static inline void emit_member(const Emitter emit, const Value v, const uint emit_addr) {
+  const Instr ex = emit_add_instr(emit, GWOP_EXCEPT);
+  ex->m_val = -SZ_INT;
   const m_uint size = v->type->size;
   const Instr instr = emit_kind(emit, size, emit_addr, dotmember);
   instr->m_val = v->offset;
+  instr->m_val2 = size;
 }
 
 ANN static m_bool emit_exp_dot_instance(const Emitter emit, const Exp_Dot* member) { GWDEBUG_EXE
@@ -1390,19 +1489,13 @@ ANN static m_bool emit_exp_dot_instance(const Emitter emit, const Exp_Dot* membe
     if(GET_FLAG(value, member)) { // member
       if(emit_exp(emit, member->base, 0) < 0)
         ERR_B(member->self->pos, "... in member function") // LCOV_EXCL_LINE
-      if(!GET_FLAG(value->type->d.func, global))
-        emit_add_instr(emit, RegDup);
       emit_member(emit, value, emit_addr);
       return GW_OK;
     } else
       return emit_dot_static_data(emit, value, emit_addr);
-  } else if(isa(member->self->type, t_function) > 0) { // function
-    const Func func = value->d.func_ref;
-    if(GET_FLAG(func, member)) {
-      return emit_member_func(emit, member, func);
-    } else
-      return emit_dot_static_func(emit, func);
-  } else { // variable
+  } else if(isa(member->self->type, t_function) > 0)
+    return emit_member_func(emit, member, value->d.func_ref);
+  else { // variable
     if(GET_FLAG(value, member)) { // member
       CHECK_BB(emit_exp(emit, member->base, 0))
       emit_member(emit, value, emit_addr);
@@ -1455,10 +1548,8 @@ ANN static void emit_func_def_args(const Emitter emit, Arg_List a) { GWDEBUG_EXE
 ANN static void emit_func_def_ensure(const Emitter emit, const Func_Def func_def) { GWDEBUG_EXE
   const m_uint size = func_def->ret_type->size;
   if(size) {
-    if(size == SZ_INT)
-       emit_add_instr(emit, PushNull);
-    else
-      emit_kind(emit, size, 0, regpushimm);
+    const Instr instr = emit_kind(emit, size, 0, regpushimm);
+    instr->m_val2 = size;
   }
   vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto));
 }
@@ -1497,7 +1588,7 @@ ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def func_def
   return GW_OK;
 }
 
-ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def) { GWDEBUG_EXE
+ANN /*static */m_bool emit_func_def(const Emitter emit, const Func_Def func_def) { GWDEBUG_EXE
   const Func func = get_func(emit->env, func_def);
   if(func->code)return GW_OK;
   if(tmpl_list_base(func_def->tmpl)) { // don't check template definition
@@ -1520,6 +1611,7 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def) { G
   emit_func_def_code(emit, func);
   emit->env->func = former;
   emit_pop_code(emit);
+//  if(!emit->env->class_def && !GET_FLAG(func_def, template))
   if(!emit->env->class_def)
     emit_func_def_global(emit, func->value_ref);
   MEMOIZE_INI
index 4c46f6430f6d02ec9b039840b593a7dd0b02f930..f84b9ab53c3faf751f26a2b935e7e3d3a1fd9bc2 100644 (file)
@@ -23,7 +23,12 @@ ANN void free_emitter(Emitter a) {
 __attribute__((returns_nonnull))
 ANN2(1) Instr emit_add_instr(const Emitter emit, const f_instr f) {
   const Instr instr = mp_alloc(Instr);
-  instr->execute = f;
+  if((m_uint)f < 255)
+    instr->opcode = (m_uint)f;
+  else {
+    instr->opcode = (m_uint)OP_MAX;
+    instr->execute = f;
+  }
   vector_add(&emit->code->instr, (vtype)instr);
   return instr;
 }
index 550fcbf0fa20c685d7384e34a1062b6a97465c8e..56ffc1a456e213931dc8aacff3b49ff97d6640a8 100644 (file)
@@ -28,12 +28,26 @@ ANN m_uint m_vector_size(const M_Vector v) {
 
 M_Vector new_m_vector(const m_uint size) {
   const M_Vector array = mp_alloc(M_Vector);
-  array->ptr   = (m_bit*)xcalloc(ARRAY_OFFSET + 2, size);
+const size_t sz = (ARRAY_OFFSET*SZ_INT) + (2*size);
+  array->ptr   = (m_bit*)xcalloc(1, sz);
   ARRAY_CAP(array)   = 2;
   ARRAY_SIZE(array)  = size;
   return array;
 }
 
+M_Vector new_m_vector2(const m_uint size, const m_uint len) {
+  const M_Vector array = mp_alloc(M_Vector);
+  const size_t sz = (ARRAY_OFFSET*SZ_INT) + (len*size);
+  array->ptr   = (m_bit*)xcalloc(1, sz);
+  m_uint cap = 1;
+  while(cap < len)
+    cap *= 2;
+  ARRAY_CAP(array)   = cap;
+  ARRAY_SIZE(array)  = size;
+  ARRAY_LEN(array) = len;
+  return array;
+}
+
 void free_m_vector(M_Vector a) {
   xfree(a->ptr);
   mp_free(M_Vector, a);
@@ -52,14 +66,9 @@ static DTOR(array_dtor) {
 
 ANN M_Object new_array(const Type t, const m_uint length) {
   const M_Object a = new_object(NULL, t);
-  m_uint cap = 1;
-  while(cap < length)
-    cap *= 2;
   const m_uint depth = t->array_depth;
   const m_uint size = depth > 1 ? SZ_INT : array_base(t)->size;
-  const M_Vector array = ARRAY(a) = new_m_vector(size);
-  ARRAY_CAP(array)   = cap;
-  ARRAY_LEN(array) = length;
+  ARRAY(a) = new_m_vector2(size,length);
   ADD_REF(t);
   return a;
 }
@@ -305,7 +314,7 @@ ANN static M_Object* init_array(const VM_Shred shred, const ArrayInfo* info, m_u
 }
 
 INSTR(ArrayAlloc) { GWDEBUG_EXE
-  const ArrayInfo* info = *(ArrayInfo**)instr->ptr;
+  const ArrayInfo* info = (ArrayInfo*)instr->m_val;
   m_uint num_obj = 1;
   m_int idx = 0;
   const m_bool is_obj = info->is_obj && !info->is_ref;
index 8f2023d1511768f19ed76f1ae12cd23ac1e26752..74a0b27af420cbdfa6eceddd738c885baff2ec75 100644 (file)
 #include "emit.h"
 #include "operator.h"
 
-#define describe(name, op) \
-INSTR(Float##name) { GWDEBUG_EXE \
-  POP_REG(shred, SZ_FLOAT); \
-  *(m_float*)REG(-SZ_FLOAT) op##= *(m_float*)REG(0); \
-}
-
-static describe(Plus, +)
-static describe(Minus, -)
-describe(Times, *)
-static describe(Divide, /)
-
-#define describe_logical(name, op) \
-static INSTR(float_##name) { GWDEBUG_EXE \
-  POP_REG(shred, SZ_FLOAT * 2 - SZ_INT); \
-  *(m_int*)REG(-SZ_INT) = (*(m_float*)REG(-SZ_INT) op *(m_float*)REG(SZ_FLOAT -SZ_INT)); \
-}
-describe_logical(and, &&)
-describe_logical(or,  ||)
-describe_logical(eq,  ==)
-describe_logical(neq, !=)
-describe_logical(gt,   >)
-describe_logical(ge,  >=)
-describe_logical(lt,   <)
-describe_logical(le,  <=)
-
-INSTR(float_negate) { GWDEBUG_EXE
-  *(m_float*)REG(-SZ_FLOAT) = -*(m_float*)REG(-SZ_FLOAT);
-}
-
-
 OP_CHECK(opck_unary_meta2) {
   const Exp_Unary* unary = (Exp_Unary*)data;
   unary->self->meta = ae_meta_value;
   return t_int;
 }
 
-INSTR(float_not) { GWDEBUG_EXE
-  POP_REG(shred, SZ_FLOAT - SZ_INT)
-    *(m_int*)REG(-SZ_INT) = !*(m_float*)REG(-SZ_INT);
-}
-
-static INSTR(float_r_assign) { GWDEBUG_EXE
-  POP_REG(shred, SZ_INT);
-  **(m_float**)REG(0) = *(m_float*)REG(-SZ_FLOAT);
-}
-
-#define describe_r(name, op) \
-static INSTR(float_r_##name) { GWDEBUG_EXE \
-  POP_REG(shred, SZ_INT); \
-  *(m_float*)REG(-SZ_FLOAT) = (**(m_float**)REG(0) op##= (*(m_float*)REG(-SZ_FLOAT))); \
-}
-
-describe_r(plus,   +)
-describe_r(minus,  -)
-describe_r(mul,  *)
-describe_r(div, /)
-
-#define describe_if(name, op) \
-static INSTR(int_float_##name) { GWDEBUG_EXE \
-  POP_REG(shred, SZ_INT); \
-  *(m_float*)REG(-SZ_FLOAT) = (m_float)*(m_int*)REG(-SZ_FLOAT) op \
-    *(m_float*)REG(SZ_INT-SZ_FLOAT); \
-}
-describe_if(plus,   +)
-describe_if(minus,  -)
-describe_if(mul,  *)
-describe_if(div, /)
-
-#define describe_logical_if(name, op) \
-static INSTR(int_float_##name) { GWDEBUG_EXE \
-  POP_REG(shred, SZ_FLOAT); \
-  *(m_int*)REG(-SZ_INT) = (*(m_int*)REG(-SZ_INT) op (m_int)*(m_float*)REG(0)); \
-}
-describe_logical_if(and, &&)
-describe_logical_if(or,  ||)
-describe_logical_if(eq,  ==)
-describe_logical_if(neq, !=)
-describe_logical_if(gt,   >)
-describe_logical_if(ge,  >=)
-describe_logical_if(lt,   <)
-describe_logical_if(le,  <=)
-
-#define describe_r_if(name, op) \
-static INSTR(int_float_r_##name) { GWDEBUG_EXE \
-  POP_REG(shred, SZ_INT * 2 - SZ_FLOAT); \
-  *(m_float*)REG(-SZ_FLOAT) = (**(m_float**)REG(SZ_INT - SZ_FLOAT) op##= \
-    (m_float)*(m_int*)REG(-SZ_FLOAT)); \
-}
-describe_r_if(assign,  )
-describe_r_if(plus,   +)
-describe_r_if(minus,  -)
-describe_r_if(mul,  *)
-describe_r_if(div, /)
-
-#define describe_fi(name, op) \
-static INSTR(float_int_##name) { GWDEBUG_EXE \
-  POP_REG(shred, SZ_INT); \
-  *(m_float*)REG(-SZ_FLOAT) op##= (m_float)*(m_int*)REG(0); \
-}
-describe_fi(plus,   +)
-describe_fi(minus,  -)
-describe_fi(mul,  *)
-describe_fi(div, /)
-
-#define describe_logical_fi(name, op) \
-static INSTR(float_int_##name) { GWDEBUG_EXE \
-  POP_REG(shred, SZ_FLOAT); \
-  *(m_int*)REG(-SZ_INT) = ((m_int)*(m_float*)REG(-SZ_INT) op *(m_int*)REG(SZ_FLOAT-SZ_INT)); \
-}
-describe_logical_fi(and, &&)
-describe_logical_fi(or,  ||)
-describe_logical_fi(eq,  ==)
-describe_logical_fi(neq, !=)
-describe_logical_fi(gt,   >)
-describe_logical_fi(ge,  >=)
-describe_logical_fi(lt,   <)
-describe_logical_fi(le,  <=)
-
-static INSTR(float_int_r_assign) { GWDEBUG_EXE
-  POP_REG(shred, SZ_FLOAT);
-  *(m_int*)REG(-SZ_INT) = **(m_int**)REG(SZ_FLOAT-SZ_INT) =
-    (m_int)*(m_float*)REG(-SZ_INT);
-}
-
-#define describe_r_fi(name, op) \
-static INSTR(float_int_r_##name) { GWDEBUG_EXE \
-  POP_REG(shred, SZ_FLOAT); \
-  *(m_int*)REG(-SZ_INT) = (**(m_int**)REG(SZ_FLOAT -SZ_INT) op##= (m_int)(*(m_float*)REG(-SZ_INT))); \
-}
-describe_r_fi(plus,   +)
-describe_r_fi(minus,  -)
-describe_r_fi(mul,  *)
-describe_r_fi(div, /)
-
-static INSTR(Time_Advance) { GWDEBUG_EXE
-  POP_REG(shred, SZ_FLOAT);
-  const m_float f = *(m_float*)REG(-SZ_FLOAT);
-  *(m_float*)REG(-SZ_FLOAT) = (shred->wake_time += f);
-  shredule(shred->vm->shreduler, shred, f);
-}
-
 static GWION_IMPORT(values) {
   VM* vm = gwi_vm(gwi);
   ALLOC_PTR(d_zero, m_float, 0.0);
@@ -213,17 +78,6 @@ static OP_EMIT(opem_f2i) {
   return GW_OK;
 }
 
-INSTR(CastI2F) { GWDEBUG_EXE
-  POP_REG(shred, SZ_INT - SZ_FLOAT);
-  *(m_float*)REG(-SZ_FLOAT) = (m_float)*(m_int*)REG(-SZ_FLOAT);
-}
-
-
-INSTR(CastF2I) { GWDEBUG_EXE
-  POP_REG(shred, SZ_FLOAT - SZ_INT);
-  *(m_int*)REG(-SZ_INT) = (m_int)*(m_float*)REG(-SZ_INT);
-}
-
 #define CHECK_OP(op, check, func) _CHECK_OP(op, check, float_##func)
 #define CHECK_IF(op, check, func) _CHECK_OP(op, check, int_float_##func)
 #define CHECK_FI(op, check, func) _CHECK_OP(op, check, float_int_##func)
index 61975a7384a63a4b7a38f949bca8163bb2155ab2..6a8bdbd03e4583517ccd9d636ac7e004beea646a 100644 (file)
 ANN Type check_exp_call1(const Env env, const Exp_Call *exp);
 ANN m_bool emit_exp_spork(const Emitter, const Exp_Unary*);
 
-static INSTR(assign_func) { GWDEBUG_EXE
-  const Func f = **(Func**)REG(-SZ_INT) = *(Func*)REG(-(SZ_INT*2+instr->m_val2));
-  POP_REG(shred, instr->m_val + instr->m_val2)
-  *(Func*)REG(-SZ_INT) = f; // do we need this ?
+static INSTR(FuncAssign) { GWDEBUG_EXE
+  POP_REG(shred, SZ_INT)
+  **(Func**)REG(0) = *(Func*)REG(-SZ_INT);
 }
 
 static OP_CHECK(opck_func_call) {
@@ -106,19 +105,6 @@ static OP_CHECK(opck_spork) {
     ERR_O(unary->self->pos, "only function calls can be sporked...")
   return NULL;
 }
-static OP_EMIT(opem_fptr_at) {
-  const Exp_Binary* bin = (Exp_Binary*)data;
-  const Instr instr = emit_add_instr(emit, assign_func);
-  if(GET_FLAG(bin->rhs->type->d.func, global))
-    instr->m_val = SZ_INT;
-  else if(GET_FLAG(bin->rhs->type->d.func, member)) {
-    if(bin->rhs->exp_type != ae_exp_decl)
-      instr->m_val2 = SZ_INT;
-    instr->m_val = SZ_INT*2;
-  } else
-    instr->m_val = SZ_INT;
-  return GW_OK;
-}
 
 static OP_EMIT(opem_spork) {
   const Exp_Unary* unary = (Exp_Unary*)data;
@@ -131,8 +117,7 @@ GWION_IMPORT(func) {
   CHECK_BB(gwi_oper_end(gwi, op_chuck, NULL))
   CHECK_BB(gwi_oper_ini(gwi, "@function", "@func_ptr", NULL))
   CHECK_BB(gwi_oper_add(gwi, opck_fptr_at))
-  CHECK_BB(gwi_oper_emi(gwi, opem_fptr_at))
-  CHECK_BB(gwi_oper_end(gwi, op_ref, NULL))
+  CHECK_BB(gwi_oper_end(gwi, op_ref, FuncAssign))
   CHECK_BB(gwi_oper_add(gwi, opck_fptr_cast))
   CHECK_BB(gwi_oper_emi(gwi, opem_basic_cast))
   CHECK_BB(gwi_oper_end(gwi, op_cast, NULL))
index 0e53bdc9351ab5e323fc6db008dfe17a30169306..5064b59480d78895c55b3e8e621ccab612a95ecc 100644 (file)
@@ -91,11 +91,11 @@ static void print_prim(const Type type, const m_bit* stack) {
   else
    print_float(*(m_float*)stack);
 }
-
+/*
 INSTR(Gack) { GWDEBUG_EXE
-  const Vector v = *(Vector*)instr->ptr;
-  const m_uint size = vector_size(v);
   m_uint offset = instr->m_val;
+  const Vector v = (Vector)instr->m_val2;
+  const m_uint size = vector_size(v);
   for(m_uint i = size + 1; --i;) {
     const Type type = (Type)vector_at(v, size - i);
     if(size == 1)
@@ -114,3 +114,26 @@ INSTR(Gack) { GWDEBUG_EXE
   }
   gw_out("\n");
 }
+*/
+void gack(const m_bit* reg, const Instr instr) {
+  m_uint offset = instr->m_val;
+  const Vector v = (Vector)instr->m_val2;
+  const m_uint size = vector_size(v);
+  for(m_uint i = size + 1; --i;) {
+    const Type type = (Type)vector_at(v, size - i);
+    if(size == 1)
+      print_type(type);
+    if(isa(type, t_object) > 0)
+      print_object(type, *(M_Object*)(reg-offset));
+    else if(isa(type, t_function) > 0)
+      print_func(type, (reg-offset));
+    else if(isa(type, t_class) > 0)
+      print_type(type->d.base_type);
+    else if(isa(type, t_void) > 0)
+      print_string1("void");
+    else
+      print_prim(type, (reg-offset));
+    offset -= type->size;
+  }
+  gw_out("\n");
+}
index 392a46759a17bd5f26a85137575b185b504a0527..233e53ecee69bce185e32f147c0c1b2141158d6f 100644 (file)
@@ -166,9 +166,8 @@ ANN static ID_List str2list(const m_str path, m_uint* array_depth) {
 ANN static m_bool mk_xtor(const Type type, const m_uint d, const ae_flag e) {
   VM_Code* code = e == ae_flag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
   const m_str name = type->name;
-  *code = new_vm_code(NULL, SZ_INT, 1, name);
+  *code = new_vm_code(NULL, SZ_INT, e | ae_flag_member | ae_flag_builtin, name);
   (*code)->native_func = (m_uint)d;
-  (*code)->flag = (e | ae_flag_member | ae_flag_builtin);
   type->flag |= e;
   return GW_OK;
 }
@@ -353,7 +352,7 @@ static Array_Sub make_dll_arg_list_array(Array_Sub array_sub,
   return array_sub;
 }
 
-ANN static Type_List str2tl(const Env env, const m_str s, m_uint *depth) {
+ANN /*static */ Type_List str2tl(const Env env, const m_str s, m_uint *depth) {
   Type_Decl* td = str2decl(env, s, depth);
   td->array = make_dll_arg_list_array(NULL, depth, 0);
   return new_type_list(td, NULL);
index 9dfdfc3b9bb22301c1f54d0e5a1440676266913f..6065c331a28d299bf29c512784e19ee982c354dc 100644 (file)
 #include "array.h"
 #include "nspc.h"
 
-ANN static inline m_bool overflow_(const VM_Shred c) {
-  return c->mem >  ((c->_reg + SIZEOF_REG) + (SIZEOF_MEM) - (MEM_STEP));
-}
-
-static inline void dl_return_push(const m_bit* retval, const VM_Shred shred,
-  const m_uint size  __attribute__((unused))) {
-  *(m_uint*)REG(0) = *(m_uint*)retval;
-  PUSH_REG(shred, SZ_INT);
-}
-
-static inline void dl_return_push2(const m_bit* retval, const VM_Shred shred,
-  const m_uint size  __attribute__((unused))) {
-  *(m_float*)REG(0) = *(m_float*)retval;
-  PUSH_REG(shred, SZ_FLOAT);
-}
-
-static inline void dl_return_push3(const m_bit* retval, const VM_Shred shred, const m_uint size) {
-    memcpy(REG(0), retval, size);
-    PUSH_REG(shred, size);
-}
-
-static void (*dl_return[])(const m_bit*, const VM_Shred, const m_uint) =
-  { dl_return_push, dl_return_push2, dl_return_push3 };
-
 INSTR(EOC) { GWDEBUG_EXE
   vm_shred_exit(shred);
 }
@@ -55,128 +31,20 @@ INSTR(EOC2) { GWDEBUG_EXE
   shreduler_remove(shred->vm->shreduler, shred, 0);
 }
 
-INSTR(RegPop) { GWDEBUG_EXE
-  POP_REG(shred, instr->m_val);
-}
-
-INSTR(RegPushImm) { GWDEBUG_EXE
-  *(m_uint*)shred->reg = instr->m_val;
-  shred->reg += SZ_INT;
-}
-#define describe_regpushimmxxx(name, type, size) \
-INSTR(RegPush##name) { GWDEBUG_EXE               \
-  *(type*)REG(0) = *(type*)instr->ptr;           \
-  PUSH_REG(shred, size);                         \
-}
-
-describe_regpushimmxxx(Imm2, m_float, SZ_FLOAT)
-INSTR(RegPushImm3) { GWDEBUG_EXE
-  memcpy(REG(0), instr->ptr, instr->m_val2);
-  PUSH_REG(shred, instr->m_val2);
-}
-
-INSTR(MemPushImm) { GWDEBUG_EXE
-  *(m_uint*)MEM(0) = instr->m_val;
-  PUSH_MEM(shred, SZ_INT);
-}
-
-INSTR(MemSetImm) { GWDEBUG_EXE
-  *(m_uint*)MEM(instr->m_val) = instr->m_val2;
-}
-
-#define describe_regpushxxx(name, type, size)                          \
-INSTR(RegPush##name) { GWDEBUG_EXE                                     \
-  *(type*)REG(0) = *(type*)(shred->mem + instr->m_val);                \
-  PUSH_REG(shred, size);                                               \
-}
-
-describe_regpushxxx(Mem,  m_uint,   SZ_INT)
-describe_regpushxxx(Mem2, m_float, SZ_FLOAT)
-INSTR(RegPushMem3) { GWDEBUG_EXE
-  memcpy(REG(0), (shred->mem + instr->m_val), instr->m_val2);
-  PUSH_REG(shred, instr->m_val2);
-}
-INSTR(RegPushMem4) { GWDEBUG_EXE
-  *(m_bit**)REG(0) = (m_bit*)(shred->mem + instr->m_val);
-  PUSH_REG(shred, SZ_INT);
-}
-
-#define describe_regpushbase(name, type, size)                         \
-INSTR(RegPush##name) { GWDEBUG_EXE                                     \
-  *(type*)REG(0) = *(type*)(shred->base + instr->m_val);               \
-  PUSH_REG(shred, size);                                               \
-}
-
-describe_regpushbase(Base,  m_uint,   SZ_INT)
-describe_regpushbase(Base2, m_float, SZ_FLOAT)
-INSTR(RegPushBase3) { GWDEBUG_EXE
-  memcpy(REG(0), (shred->base + instr->m_val), instr->m_val2);
-  PUSH_REG(shred, instr->m_val2);
-}
-INSTR(RegPushBase4) { GWDEBUG_EXE
-  *(m_bit**)REG(0) = (m_bit*)(shred->base + instr->m_val);
-  PUSH_REG(shred, SZ_INT);
-}
-
-INSTR(RegPushPtr) { GWDEBUG_EXE
-  *(m_uint*)REG(-SZ_INT) = instr->m_val;
-}
-
-INSTR(RegDup) { GWDEBUG_EXE
-  *(M_Object*)REG(0) = *(M_Object*)REG(-SZ_INT);
-  PUSH_REG(shred, SZ_INT);
-}
-
-INSTR(RegAddRef) { GWDEBUG_EXE
-  const M_Object obj = instr->m_val ? **(M_Object**)REG(-SZ_INT) :
-    *(M_Object*)REG(-SZ_INT);
-  if(obj)
-    ++obj->ref;
-}
-
 INSTR(RegPushMe) { GWDEBUG_EXE
   *(M_Object*)REG(0) = shred->me;
   PUSH_REG(shred, SZ_INT);
 }
 
-INSTR(RegPushNow) { GWDEBUG_EXE
-  *(m_float*)REG(0) = (m_float)shred->vm->bbq->pos;
-  PUSH_REG(shred, SZ_FLOAT);
-}
-
 INSTR(RegPushMaybe) { GWDEBUG_EXE
   *(m_uint*)REG(0) = gw_rand(shred->vm->rand) > (UINT32_MAX / 2);
   PUSH_REG(shred, SZ_INT);
 }
 
-INSTR(AllocWord) { GWDEBUG_EXE
-  *(m_uint*)MEM(instr->m_val) = 0;
-  *(m_uint*)REG(0) = 0; // MEM(instr->m_val);
-  PUSH_REG(shred, SZ_INT);
-}
-
-INSTR(AllocWord2) { GWDEBUG_EXE
-  *(m_float*)MEM(instr->m_val) = 0.0;
-  *(m_float*)REG(0) = 0.0; // MEM(instr->m_val);
-  PUSH_REG(shred, SZ_FLOAT);
-}
-
-INSTR(AllocWord3) { GWDEBUG_EXE
-  memset(MEM(instr->m_val), 0, instr->m_val2);
-  memset(REG(0), 0, instr->m_val2); // MEM(instr->m_val)
-  PUSH_REG(shred, instr->m_val2);
-}
-
-INSTR(AllocWord4) { GWDEBUG_EXE
-  memset(MEM(instr->m_val), 0, instr->m_val2);
-  *(m_bit**)REG(0) = (m_bit*)MEM(instr->m_val);
-  PUSH_REG(shred, SZ_INT);
-}
-
 /* branching */
 INSTR(SwitchIni) {
   const Vector v = (Vector)instr->m_val;
-  const m_uint size = vector_size(v);;
+  const m_uint size = vector_size(v);
   const Map m = (Map)instr->m_val2;
   POP_REG(shred, SZ_INT * (size - 1));
   for(m_uint i = 0; i < size; ++i)
@@ -193,337 +61,6 @@ INSTR(BranchSwitch) { GWDEBUG_EXE
     shred->pc = instr->m_val;
 }
 
-#define branch(name, type, sz, op)      \
-INSTR(Branch##name) { GWDEBUG_EXE      \
-  POP_REG(shred, sz * 2);               \
-  if(*(type*)REG(0) op *(type*)REG(sz)) \
-    shred->pc = instr->m_val;           \
-}
-branch(EqInt,    m_uint,     SZ_INT, ==)
-branch(NeqInt,   m_uint,     SZ_INT, !=)
-branch(EqFloat,  m_float,  SZ_FLOAT, ==)
-branch(NeqFloat, m_float, SZ_FLOAT, !=)
-
-INSTR(InitLoopCounter) { GWDEBUG_EXE
-  POP_REG(shred, SZ_INT);
-  (*(m_uint*)instr->m_val) = labs(*(m_int*)REG(0));
-}
-
-INSTR(RegPushDeref) { GWDEBUG_EXE
-  *(m_uint*)REG(0) =  **(m_uint**)instr->ptr;
-  PUSH_REG(shred, SZ_INT);
-}
-
-INSTR(RegPushDeref2) { GWDEBUG_EXE
-  *(m_float*)REG(0) = *(m_float*)instr->ptr;
-  PUSH_REG(shred, SZ_FLOAT);
-}
-
-INSTR(RegPushDeref3) { GWDEBUG_EXE
-  memcpy(REG(0), *(void**)instr->ptr, instr->m_val2);
-  PUSH_REG(shred, instr->m_val2);
-}
-
-INSTR(DecIntAddr) { GWDEBUG_EXE
-  --(*((m_uint*)(instr->m_val)));
-}
-
-INSTR(Goto) { GWDEBUG_EXE
-  shred->pc = instr->m_val;
-}
-
-ANN static VM_Shred init_spork_shred(const VM_Shred shred, const VM_Code code) {
-  const VM_Shred sh = new_vm_shred(code);
-  ADD_REF(code)
-  sh->parent = shred;
-  if(!shred->child.ptr)
-    vector_init(&shred->child);
-  vector_add(&shred->child, (vtype)sh);
-  sh->base = shred->base;
-  vm_add_shred(shred->vm, sh);
-  return sh;
-}
-#include "value.h"
-static inline void push_me(VM_Shred shred, VM_Shred sh) {
-  *(M_Object*)REG(0) = sh->me;
-  PUSH_REG(shred, SZ_INT);
-}
-
-INSTR(SporkFunc) { GWDEBUG_EXE
-  POP_REG(shred, SZ_INT);
-  const VM_Code code = (VM_Code)instr->m_val2;
-  const VM_Shred sh = init_spork_shred(shred, code);
-  const m_uint need = GET_FLAG(code, member) ? SZ_INT : 0;
-  shred->reg -= instr->m_val + need;
-  if(instr->m_val) {
-    for(m_uint i = 0; i < instr->m_val; i+= SZ_INT)
-      *(m_uint*)(sh->reg + i) = *(m_uint*)REG(i);
-    sh->reg += instr->m_val;
-  }
-  if(need) {
-    *(M_Object*)sh->reg = *(M_Object*)REG(instr->m_val);
-    PUSH_REG(sh, SZ_INT);
-  }
-  push_me(shred, sh);
-}
-
-INSTR(SporkExp) { GWDEBUG_EXE
-  POP_REG(shred, SZ_INT);
-  const VM_Code code = (VM_Code)instr->m_val2;
-  const VM_Shred sh = init_spork_shred(shred, code);
-  for(m_uint i = 0; i < instr->m_val; i+= SZ_INT)
-    *(m_uint*)(sh->mem + i) = *(m_uint*)MEM(i);
-  push_me(shred, sh);
-}
-
-ANN static void shred_func_prepare(const VM_Shred shred) {
-  POP_REG(shred, SZ_INT * 2);
-  // local depth + previous stack
-  const m_uint push = *(m_uint*)REG(SZ_INT) + *(m_uint*)MEM(-SZ_INT);
-  PUSH_MEM(shred, push + SZ_INT*3);
-  *(m_uint*)  MEM(-SZ_INT*3) = push;
-  *(VM_Code*) MEM(-SZ_INT*2) = shred->code;
-  *(m_uint*)  MEM(-SZ_INT) = shred->pc;
-  shred->pc = 0;
-  shred->code = *(VM_Code*)REG(0);
-  shred->instr = shred->code->instr;
-}
-
-ANN static inline void shred_func_need_this(const VM_Shred shred) {
-  *(m_uint*)MEM(0) = *(m_uint*)REG(shred->code->stack_depth - SZ_INT);
-  PUSH_MEM(shred, SZ_INT);
-}
-
-INSTR(FuncPtr) { GWDEBUG_EXE
-  const VM_Code code = *(VM_Code*)REG(-SZ_INT*2);
-  if(!code)
-    Except(shred, "NullFuncPtrException");
-  if(!GET_FLAG(code, builtin))
-    FuncUsr(shred, instr);
-  else if(GET_FLAG(code, member))
-    FuncMember(shred, instr);
-  else
-    FuncStatic(shred, instr);
-}
-
-INSTR(FuncUsr) { GWDEBUG_EXE
-  shred_func_prepare(shred);
-  const VM_Code code = shred->code;
-  m_uint stack_depth = code->stack_depth;
-  if(stack_depth) {
-    POP_REG(shred, stack_depth);
-    if(GET_FLAG(code, member)) {
-      shred_func_need_this(shred);
-      stack_depth -= SZ_INT;
-    }
-    for(m_uint i = 0; i < stack_depth; i+= SZ_INT)
-      *(m_uint*)MEM(i) = *(m_uint*)REG(i);
-    if(GET_FLAG(code, member))
-      POP_MEM(shred, SZ_INT);
-  }
-  if(overflow_(shred))
-    Except(shred, "StackOverflow");
-}
-
-INSTR(DotFunc) { GWDEBUG_EXE
-  const M_Object obj = *(M_Object*)REG(-SZ_INT);
-  if(!obj)
-    Except(shred, "NullPtrException");
-  *(VM_Code*)REG(-SZ_INT) = ((Func)vector_at(&obj->type_ref->nspc->vtable, instr->m_val))->code;
-}
-
-INSTR(FuncStatic) { GWDEBUG_EXE
-  POP_REG(shred, SZ_INT * 2);
-  const VM_Code code = *(VM_Code*)REG(0);
-  const m_uint local_depth = *(m_uint*)REG(SZ_INT);
-  PUSH_MEM(shred, local_depth);
-  const m_uint stack_depth = code->stack_depth;
-  if(stack_depth) {
-    POP_REG(shred, stack_depth);
-    for(m_uint i = 0; i < stack_depth; i+= SZ_INT)
-      *(m_uint*)MEM(i) = *(m_uint*)REG(i);
-  }
-  if(overflow_(shred))
-    Except(shred, "StackOverflow");
-  const m_bit retval[instr->m_val];
-  const f_sfun f = (f_sfun)code->native_func;
-  f(retval, shred);
-  if(instr->m_val)
-    dl_return[instr->m_val2](retval, shred, instr->m_val);
-  POP_MEM(shred, local_depth);
-}
-
-ANN static inline void copy_member_args(const VM_Shred shred, const VM_Code func) {
-  const m_uint stack_depth = func->stack_depth;
-  const m_uint depth = stack_depth -SZ_INT;
-  POP_REG(shred, stack_depth);
-  *(m_uint*)MEM(0) = *(m_uint*)REG(depth);
-    for(m_uint i = 0; i < stack_depth; i+= SZ_INT)
-      *(m_uint*)MEM(i+SZ_INT) = *(m_uint*)REG(i);
-}
-
-INSTR(FuncMember) { GWDEBUG_EXE
-  POP_REG(shred, SZ_INT * 2);
-  const VM_Code code = *(VM_Code*)REG(0);
-  const m_uint local_depth =   *(m_uint*)REG(SZ_INT);
-  PUSH_MEM(shred, local_depth);
-  copy_member_args(shred, code);
-  if(overflow_(shred))
-    Except(shred, "StackOverflow");
-  if(GET_FLAG(code, ctor)) {
-    const f_xtor f = (f_xtor)code->native_func;
-    f(*(M_Object*)MEM(0), shred);
-  } else {
-    assert(instr);
-    const m_bit retval[instr->m_val];
-    const f_mfun f = (f_mfun)code->native_func;
-    f((*(M_Object*)MEM(0)), retval, shred);
-    if(instr->m_val)
-      dl_return[instr->m_val2](retval, shred, instr->m_val);
-  }
-  POP_MEM(shred, local_depth);
-}
-
-INSTR(FuncReturn) { GWDEBUG_EXE
-  shred->pc = *(m_uint*)MEM(-SZ_INT);
-  shred->code = *(VM_Code*)MEM(-SZ_INT*2);
-  shred->instr = shred->code->instr;
-  POP_MEM(shred, *(m_uint*)MEM(-SZ_INT*3) + SZ_INT*3);
-}
-
-INSTR(PreCtor) { GWDEBUG_EXE
-  const VM_Code pre_ctor = (VM_Code)instr->m_val;
-  *(m_uint*)REG(0) = *(m_uint*)REG(-SZ_INT);
-  *(VM_Code*)REG(SZ_INT) = pre_ctor;
-  *(m_uint*)REG(SZ_INT*2) = instr->m_val2;
-  PUSH_REG(shred, SZ_INT*3);
-  if(GET_FLAG(pre_ctor, builtin))
-    FuncMember(shred, NULL);
-  else
-    FuncUsr(shred, NULL);
-}
-
-INSTR(ObjectInstantiate) { GWDEBUG_EXE
-  const M_Object o = new_object(shred, (Type)instr->m_val);
-  *(M_Object*)REG(0) = o;
-  PUSH_REG(shred, SZ_INT);
-}
-
-INSTR(PushNull) { GWDEBUG_EXE
-  *(m_uint*)REG(0) = 0;
-  PUSH_REG(shred, SZ_INT);
-}
-
-INSTR(PushNull2) { GWDEBUG_EXE
-  *(m_float*)REG(0) = 0.0;
-  PUSH_REG(shred, SZ_FLOAT);
-}
-
-INSTR(PushNull3) { GWDEBUG_EXE
-  memset(REG(0), 0, instr->m_val2); // 0 <=> *data
-  PUSH_REG(shred, instr->m_val2);
-}
-
-INSTR(AllocMember4) { GWDEBUG_EXE
-  const M_Object obj = *(M_Object*)MEM(0);
-  *(const m_bit**)REG(0) = obj->data + instr->m_val;
-  PUSH_REG(shred, SZ_INT);
-}
-
-INSTR(DotStatic) { GWDEBUG_EXE
-  const Type t = *(Type*)REG(-SZ_INT);
-  m_uint *const data = (m_uint*)(t->nspc->class_data + instr->m_val);
-  *(m_uint*)REG(-SZ_INT) = data ? *data : 0;
-}
-
-INSTR(DotStatic2) { GWDEBUG_EXE
-  const Type t = *(Type*)REG(-SZ_INT);
-  m_float *const data = (m_float*)(t->nspc->class_data + instr->m_val);
-  *(m_float*)REG(-SZ_INT) = *data;
-  PUSH_REG(shred, SZ_FLOAT - SZ_INT);
-}
-
-INSTR(DotStatic3) { GWDEBUG_EXE
-  const Type t = *(Type*)REG(-SZ_INT);
-  const m_bit* data = t->nspc->class_data + instr->m_val;
-  memcpy(REG(-SZ_INT), data, instr->m_val2);
-  PUSH_REG(shred, instr->m_val2 - SZ_INT);
-}
-
-INSTR(DotStatic4) { GWDEBUG_EXE
-  const Type t = *(Type*)REG(-SZ_INT);
-  const m_bit* data = t->nspc->class_data + instr->m_val;
-  *(m_bit**)REG(-SZ_INT) = (m_bit*)data;
-}
-
-INSTR(DotImport) { GWDEBUG_EXE
-  *(m_uint*)REG(0) =  *(m_uint*)instr->m_val;
-  PUSH_REG(shred, SZ_INT);
-}
-
-INSTR(DotImport2) { GWDEBUG_EXE
-  *(m_float*)REG(0) =  *(m_float*)instr->m_val;
-  PUSH_REG(shred, SZ_FLOAT);
-}
-
-INSTR(DotImport3) { GWDEBUG_EXE
-  memcpy(REG(0), (m_bit*)instr->m_val, instr->m_val2);
-  PUSH_REG(shred, instr->m_val2);
-}
-
-INSTR(DotImport4) { GWDEBUG_EXE
-  *(m_bit**)REG(0) = (m_bit*)(instr->m_val);
-  PUSH_REG(shred, SZ_INT);
-}
-
-INSTR(DotMember) { GWDEBUG_EXE
-  const M_Object obj  = *(M_Object*)REG(-SZ_INT);
-  if(!obj)
-    Except(shred, "NullPtrException");
-  *(m_uint*)REG(-SZ_INT) = *(m_uint*)(obj->data + instr->m_val);
-}
-
-INSTR(DotMember2) { GWDEBUG_EXE
-  const M_Object obj  = *(M_Object*)REG(-SZ_INT);
-  if(!obj)
-    Except(shred, "NullPtrException");
-  *(m_float*)REG(-SZ_INT) = *(m_float*)(obj->data + instr->m_val);
-  PUSH_REG(shred, SZ_FLOAT - SZ_INT);
-}
-
-INSTR(DotMember3) { GWDEBUG_EXE
-  const M_Object obj  = *(M_Object*)REG(-SZ_INT);
-  if(!obj)
-    Except(shred, "NullPtrException");
-  memcpy(REG(-SZ_INT), (obj->data + instr->m_val), instr->m_val2);
-  PUSH_REG(shred, instr->m_val2 - SZ_INT);
-}
-
-INSTR(DotMember4) { GWDEBUG_EXE
-  const M_Object obj  = *(M_Object*)REG(-SZ_INT);
-  if(!obj)
-    Except(shred, "NullPtrException");
-  *(m_bit**)REG(-SZ_INT) = (m_bit*)(obj->data + instr->m_val);
-}
-
-INSTR(ObjectRelease) { GWDEBUG_EXE
-  release(*(M_Object*)MEM(instr->m_val), shred);
-}
-
-INSTR(GcIni) { GWDEBUG_EXE
-  vector_add(&shred->gc, (vtype)NULL);
-}
-
-INSTR(GcAdd) { GWDEBUG_EXE
-  vector_add(&shred->gc, *(vtype*)REG(-SZ_INT));
-}
-
-INSTR(GcEnd) { GWDEBUG_EXE
-  M_Object o;
-  while((o = (M_Object)vector_pop(&shred->gc)))
-    _release(o, shred);
-}
-
 INSTR(AutoLoopStart) { GWDEBUG_EXE
   const M_Object o =  *(M_Object*)REG(-SZ_INT);
   if(!o)
@@ -542,15 +79,11 @@ INSTR(AutoLoopStart) { GWDEBUG_EXE
 }
 
 INSTR(AutoLoopEnd) { GWDEBUG_EXE
-  if(instr->m_val2) {
-    const M_Object ptr = *(M_Object*)MEM(instr->m_val + SZ_INT);
-    _release(ptr, shred);
-  }
   m_uint* idx = (m_uint*)MEM(instr->m_val);
   ++*idx;
   const M_Object o =  *(M_Object*)REG(-SZ_INT);
   if(*idx >= m_vector_size(ARRAY(o))) {
-    shred->pc = *(m_uint*)instr->ptr;
+    shred->pc = instr->m_val2;
     POP_REG(shred, SZ_INT);
   }
 }
@@ -585,6 +118,18 @@ INSTR(ConstPropGet) { GWDEBUG_EXE
 }
 #endif
 
+Type_List tmpl_tl(const Env env, const m_str name) {
+//  const Value v = f->value_ref;
+m_str start = strchr(name, '<');
+m_str end = strchr(name, '@');
+char c[strlen(name)];
+strcpy(c, start + 1);
+c[strlen(start) - strlen(end) - 2] = '\0';
+m_uint depth;
+  return str2tl(env, c, &depth);
+}
+
+
 INSTR(PopArrayClass) { GWDEBUG_EXE
   POP_REG(shred, SZ_INT);
   const M_Object obj = *(M_Object*)REG(-SZ_INT);
@@ -593,3 +138,83 @@ INSTR(PopArrayClass) { GWDEBUG_EXE
   free_object(tmp);
   ADD_REF(obj->type_ref) // add ref to typedef array type
 }
+#include "gwion.h"
+#include "emit.h"
+#include "value.h"
+#include "template.h"
+INSTR(DotTmpl) {
+  const m_str name = (m_str)instr->m_val;
+  const M_Object o = *(M_Object*)REG(-SZ_INT);
+  Type t = o->type_ref;
+  do {
+    char str[instr->m_val2 + strlen(t->name) + 1];
+    strcpy(str, name);
+    strcpy(str + instr->m_val2, t->name);
+    const Value value = nspc_lookup_value1(t->nspc, insert_symbol(str));
+    const Func f = nspc_lookup_func1(t->nspc, insert_symbol(str));
+    if(f) {
+      if(!f->code) {
+      const Emitter emit = shred->vm->gwion->emit;
+emit->env->name = "runtime";
+  const Value v = f->value_ref;
+m_str start = strchr(name, '<');
+m_str end = strchr(name, '@');
+char c[instr->m_val2];
+strcpy(c, start + 1);
+c[strlen(start) - strlen(end) - 2] = '\0';
+m_uint depth;
+const Type_List tl = str2tl(emit->env, c, &depth);
+assert(v);
+assert(v->d.func_ref->def = f->def);
+env_push_type(emit->env, v->owner_class);
+if(template_push_types(emit->env, f->def->tmpl->list, tl) > 0)
+//  if(traverse_func_def(emit->env, f->value_ref->d.func_ref->def) > 0)
+  if(traverse_func_def(emit->env, f->def) > 0)
+emit_func_def(emit, f->def);
+assert(f->code);
+assert(f->code = f->def->func->code);
+nspc_pop_type(emit->env->curr);
+env_pop(emit->env, 0);
+free_type_list(tl);
+f->def->func->code->stack_depth -= SZ_INT;
+}
+      *(VM_Code*)shred->reg = f->code;
+      shred->reg += SZ_INT;
+      return;
+    } else {
+      const Emitter emit = shred->vm->gwion->emit;
+emit->env->name = "runtime";
+//m_str start = strchr(name, '<');
+m_str start = name;
+m_str end = strchr(name, '<');
+char c[instr->m_val2];
+strcpy(c, start);
+c[strlen(start) - strlen(end)] = '\0';
+const Symbol sym = func_symbol(o->type_ref->name, c, "template", 
+*(m_uint*)instr->ptr);
+    const Value v = nspc_lookup_value1(o->type_ref->nspc, sym);
+      const Func_Def base = v->d.func_ref->def; 
+      const Func_Def def = new_func_def(base->td, insert_symbol(v->name),
+                base->arg_list, base->d.code, base->flag);
+      def->tmpl = new_tmpl_list(base->tmpl->list, *(m_int*)instr->ptr);
+      SET_FLAG(def, template);
+  Type_List tl = tmpl_tl(emit->env, name);
+  env_push_type(emit->env, v->owner_class);
+  if(template_push_types(emit->env, def->tmpl->list, tl) > 0)
+    if(traverse_func_def(emit->env, def) > 0) {
+      emit_func_def(emit, def);
+    nspc_pop_type(emit->env->curr);
+  }
+env_pop(emit->env, 0);
+def->func->code->stack_depth -= SZ_INT;
+      *(VM_Code*)shred->reg = def->func->code;
+      shred->reg += SZ_INT;
+      return;
+
+
+
+}
+  } while((t = t->parent));
+// should not be reached
+  Except(shred, "MissigTmplException[internal]");
+}
index bcb4acb100e028e664eec493742d6efb31b2ab5a..06070ff40d31e771363f8fc2f4b28b49e163021d 100644 (file)
@@ -8,76 +8,6 @@
 #include "object.h"
 #include "import.h"
 
-#define TEST0(pos) if(!*(m_int*)REG(pos))Except(shred, "ZeroDivideException")
-#define PREFIX int
-
-#define _describe(prefix, sz, name, action, ...) \
-static INSTR(prefix##_##name) { GWDEBUG_EXE \
-  POP_REG(shred, sz); \
-   __VA_ARGS__ \
-  action \
-}
-
-#define describe(name, op, ...) _describe(int, SZ_INT, name, \
-  {*(m_int*)REG(-SZ_INT) op##= *(m_int*)REG(0); }, __VA_ARGS__)
-
-#define describe_r(name, op, ...) _describe(int_r, SZ_INT, name, \
-  {*(m_int*)REG(-SZ_INT) = (**(m_int**)REG(0) op##= (*(m_int*)REG(-SZ_INT)));}, __VA_ARGS__)
-
-#define describe_logical(name, op) _describe(int, SZ_INT, name, \
-  {*(m_int*)REG(-SZ_INT) = (*(m_int*)REG(-SZ_INT) op *(m_int*)REG(0));},)
-#define describe_pre(name, op) \
-static INSTR(int_pre_##name)  { *(m_int*)REG(- SZ_INT) = op(**(m_int**)REG(- SZ_INT)); }
-#define describe_post(name, op) \
-static INSTR(int_post_##name) { GWDEBUG_EXE *(m_int*)REG(- SZ_INT) = (**(m_int**)REG(- SZ_INT))op; }
-
-static INSTR(int_negate) { GWDEBUG_EXE *(m_int*)REG(-SZ_INT) *= -1; }
-static INSTR(int_cmp) { GWDEBUG_EXE *(m_int*)REG(-SZ_INT) = ~*(m_int*)REG(-SZ_INT); }
-
-INSTR(IntNot) { GWDEBUG_EXE *(m_int*)REG(-SZ_INT) = !*(m_int*)REG(-SZ_INT); }
-
-static INSTR(int_r_assign) { GWDEBUG_EXE
-  POP_REG(shred, SZ_INT);
-  **(m_int**)REG(0) = *(m_int*)REG(-SZ_INT);
-}
-
-describe(plus,   +,)
-describe(minus,  -,)
-describe(mul,  *,)
-describe(div, /, TEST0(0))
-describe(modulo, %, TEST0(0))
-
-describe_logical(and,  &&)
-describe_logical(or,   ||)
-describe_logical(eq,   ==)
-describe_logical(neq,  !=)
-describe_logical(gt,    >)
-describe_logical(ge,   >=)
-describe_logical(lt,    <)
-describe_logical(le,   <=)
-describe_logical(sl,   <<)
-describe_logical(sr,   >>)
-describe_logical(sand,  &)
-describe_logical(sor,   |)
-describe_logical(xor,   ^)
-
-describe_pre(inc, ++)
-describe_pre(dec, --)
-//describe_pre(cmp, ~)
-describe_post(inc, ++)
-describe_post(dec, --)
-
-describe_r(plus,   +,)
-describe_r(minus,  -,)
-describe_r(mul,  *,)
-describe_r(div, /, TEST0(-SZ_INT))
-describe_r(modulo, %, TEST0(-SZ_INT))
-describe_r(sl,     <<,)
-describe_r(sr,     >>,)
-describe_r(sand,   &,)
-describe_r(sor,    |,)
-describe_r(sxor,   ^,)
-
 #define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func)
 
 GWION_IMPORT(int) {
@@ -116,11 +46,9 @@ GWION_IMPORT(int) {
   CHECK_BB(gwi_oper_end(gwi,  op_sub,       int_negate))
   CHECK_BB(gwi_oper_add(gwi,  opck_unary_meta))
   CHECK_BB(gwi_oper_end(gwi,  op_not, IntNot))
-//  CHECK_OP(not, unary_meta, not)
   CHECK_OP(inc,   unary, pre_inc)
   CHECK_OP(dec, unary, pre_dec)
   CHECK_BB(gwi_oper_end(gwi,  op_cmp, int_cmp))
-//  CHECK_OP(cmp, unary, pre_cmp)
   CHECK_BB(gwi_oper_ini(gwi, "int", NULL, "int"))
   CHECK_OP(inc,   post,  post_inc)
   CHECK_OP(dec, post,  post_dec)
index b390eaebc1bce20afb97a3f6b2df4564b516f088..7620acf1911b0cc6440383b66429db95f7d33e94 100644 (file)
@@ -23,6 +23,7 @@ M_Object new_object(const VM_Shred shred, const Type t) {
   const M_Object a = mp_alloc(M_Object);
   a->ref = 1;
   a->type_ref = t;
+  a->vtable = &t->nspc->vtable;
   if(t->nspc->offset) {
     Type type = t;
     while(!type->p)
@@ -69,7 +70,7 @@ ANN static void handle_dtor(const M_Object object, const VM_Shred shred) {
 __attribute__((hot))
 ANN void __release(const M_Object obj, const VM_Shred shred) {
   Type t = obj->type_ref;
-  do {
+  while(t->parent) {
     struct scope_iter iter = { &t->nspc->value, 0, 0 };\
     Value v;
     while(scope_iter(&iter, &v) > 0) {
@@ -77,36 +78,24 @@ ANN void __release(const M_Object obj, const VM_Shred shred) {
         release(*(M_Object*)(obj->data + v->offset), shred);
     }
     if(GET_FLAG(t, dtor)) {
-      if(t->nspc->dtor->native_func)
-        ((f_xtor)t->nspc->dtor->native_func)(obj, shred);
+      if(GET_FLAG(t->nspc->dtor, builtin))
+        ((f_xtor)t->nspc->dtor->native_func)(obj, NULL, shred);
       else {
         handle_dtor(obj, shred);
         return;
       }
     }
-  } while((t = t->parent));
+    t = t->parent;
+  }
+  free_object(obj);
 }
 
-void free_object(const M_Object o) {
+ANN void free_object(const M_Object o) {
   if(o->data)
     _mp_free2(o->p, o->data);
   mp_free(M_Object, o);
 }
 
-static DTOR(object_dtor) { free_object(o); }
-INSTR(ObjectAssign) { GWDEBUG_EXE
-  POP_REG(shred, SZ_INT);
-  const M_Object src = *(M_Object*)REG(-SZ_INT);
-  const M_Object tgt = **(M_Object**)REG(0);
-  if(tgt) {
-    --tgt->ref;
-    _release(tgt, shred);
-  }
-  if(instr->m_val)
-    *(m_bit**)REG(-SZ_INT) = REG(-SZ_INT);
-  **(M_Object**)REG(0) = src;
-}
-
 #define describe_logical(name, op)               \
 static INSTR(name##Object) { GWDEBUG_EXE        \
   POP_REG(shred, SZ_INT);                        \
@@ -138,7 +127,14 @@ static OP_CHECK(opck_object_cast) {
   const Exp_Cast* cast = (Exp_Cast*)data;
   const Type l = cast->exp->type;
   const Type r = cast->self->type;
-  return isa(l, r) > 0 ? r : t_null;
+//  return isa(l, r) > 0 ? r : t_null;
+  if(isa(l, r) > 0) {
+    const Type t = type_copy(r);
+    SET_FLAG(t, force);
+    env_add_type(env, t);
+    return t;
+  }
+  return t_null;
 }
 
 static OP_CHECK(opck_implicit_null2obj) {
@@ -148,7 +144,7 @@ static OP_CHECK(opck_implicit_null2obj) {
 
 GWION_IMPORT(object) {
   CHECK_OB((t_object  = gwi_mk_type(gwi, "Object", SZ_INT, NULL)))
-  CHECK_BB(gwi_class_ini(gwi, t_object, NULL, object_dtor))
+  CHECK_BB(gwi_class_ini(gwi, t_object, NULL, NULL))
   CHECK_BB(gwi_class_end(gwi))
   CHECK_BB(gwi_oper_ini(gwi, "@null", "Object", "Object"))
   CHECK_BB(gwi_oper_add(gwi, at_object))
index 7818a2158d6700028794d31708f24ed45dba99af..87f24563da248be6baa78bc11f50e1a341e6cd92 100644 (file)
@@ -161,11 +161,6 @@ describe_string_plus(Vec4_, SZ_VEC4, m_vec4,,
 describe_string_plus(Object_, SZ_INT, M_Object, release(lhs, shred),
   11, "%p", (void*)lhs)
 
-INSTR(RegPushStr) { GWDEBUG_EXE
-  *(M_Object*)REG(0) = new_string2(shred, (m_str)instr->m_val);
-  PUSH_REG(shred, SZ_INT);
-}
-
 static CTOR(string_ctor) {
   STRING(o) = "";
 }
index 6a148ea6a26e6b79b8fbf468650ae2f988e882d1..a7fe6ff51e62f55eb3cd75f56e0775664efc67c7 100644 (file)
@@ -1,17 +1,14 @@
 #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"
@@ -33,8 +30,6 @@
 #endif
 
 #include "plug.h"
-#include <dlfcn.h>
-#include <dirent.h>
 
 extern void parse_args(Arg*, DriverInfo*);
 static VM* some_static_vm;
@@ -45,19 +40,18 @@ static void sig(int unused __attribute__((unused))) {
 
 #include "gwion.h"
 int main(int argc, char** argv) {
-  Driver d;
-  Arg arg;
+  Driver d = { };
+  Arg arg = { .argc = argc, .argv=argv, .loop=-1, .quit=0};
   DriverInfo di = { 2, 2, 2,
   48000, 256, 3, "default:CARD=CODEC", 0, 0, D_FUNC, vm_run, 0, 0};
 
-  d.del = NULL;
-  memset(&arg, 0, sizeof(Arg));
-  arg.argc = argc;
-  arg.argv = argv;
-  arg.loop = -1;
   arg_init(&arg);
-//__fsetlocking(stdout, FSETLOCKING_BYCALLER);
-//__fsetlocking(stderr, FSETLOCKING_BYCALLER);
+
+#define STD_BUFSZ 10000
+char buf[STD_BUFSZ];
+setvbuf(stdout, buf, _IOFBF, STD_BUFSZ);
+char buf2[STD_BUFSZ];
+setvbuf(stderr, buf2, _IOFBF, STD_BUFSZ);
 
   parse_args(&arg, &di);
 struct Gwion_ gwion;
@@ -92,9 +86,6 @@ clean:
   arg_release(&arg);
   if(d.del)
     d.del(gwion.vm, &di);
-#ifndef __linux__
-  sleep(1);
-#endif
   plug_end(pi);
   gwion_release(&gwion);
   return 0;
index eff355b1e77ffe4a916d6996019376bb3cf68db8..370b3b6325dcc26f19c80bfc900d5e61aacf81f9 100644 (file)
@@ -6,22 +6,20 @@
 #include "nspc.h"
 #include "context.h"
 
+ANN static void free_context(const Context a) {
+  REM_REF(a->nspc)
+  mp_free(Context, a);
+}
+
 ANN2(2) Context new_context(const Ast ast, const m_str str) {
   const Context context = mp_alloc(Context);
   context->nspc = new_nspc(str);
   context->tree = ast;
   context->name = str;
-  INIT_OO(context, e_context_obj);
+  INIT_OO(context, free_context);
   return context;
 }
 
-ANN void free_context(const Context a) {
-//if(a->nspc->obj.ref_count > 1)exit(2);
-//  REM_REF(a->nspc);
-  free_nspc(a->nspc);
-  mp_free(Context, a);
-}
-
 ANN void load_context(const Context context, const Env env) {
   ADD_REF((env->context = context))
   vector_add(&env->nspc_stack, (vtype)env->curr);
index 0b3c730a83ca9c3d5cc70e43d6ec4238cf61f02e..bea7357ea73282045a83c4c59da7e25c5d8c4ac5 100644 (file)
@@ -18,20 +18,10 @@ ANN void nspc_commit(const Nspc nspc) {
   scope_commit(&nspc->type);
 }
 
-ANN Nspc new_nspc(const m_str name) {
-  const Nspc a = mp_alloc(Nspc);
-  a->name = name;
-  scope_init(&a->value);
-  scope_init(&a->type);
-  scope_init(&a->func);
-  INIT_OO(a, e_nspc_obj);
-  return a;
-}
-
 ANN static void nspc_release_object(const Nspc a, Value value) {
   if(value->d.ptr || (GET_FLAG(value, static) && a->class_data) ||
     (value->d.ptr && GET_FLAG(value, builtin))) {
-    const VM_Code code = new_vm_code(NULL, 0, 0, "in code dtor");
+    const VM_Code code = new_vm_code(NULL, 0, ae_flag_builtin, "in code dtor");
     const VM_Shred s = new_vm_shred(code);
     const M_Object obj = value->d.ptr ? (M_Object)value->d.ptr :
         *(M_Object*)(a->class_data + value->offset);
@@ -67,7 +57,7 @@ ANN static void nspc_free_##b(Nspc n) {\
 describe_nspc_free(Func, func)
 describe_nspc_free(Type, type)
 
-ANN void free_nspc(Nspc a) {
+ANN static void free_nspc(Nspc a) {
   free_nspc_value(a);
   nspc_free_func(a);
   nspc_free_type(a);
@@ -84,3 +74,13 @@ ANN void free_nspc(Nspc a) {
     free_op_map(&a->op_map);
   mp_free(Nspc, a);
 }
+
+ANN Nspc new_nspc(const m_str name) {
+  const Nspc a = mp_alloc(Nspc);
+  a->name = name;
+  scope_init(&a->value);
+  scope_init(&a->type);
+  scope_init(&a->func);
+  INIT_OO(a, free_nspc);
+  return a;
+}
diff --git a/src/oo/oo.c b/src/oo/oo.c
deleted file mode 100644 (file)
index 657ad33..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "gwion_util.h"
-#include "gwion_ast.h"
-#include "oo.h"
-
-extern ANN void free_nspc(void* a);
-extern ANN void free_type(void* a);
-extern ANN void free_value(void* a);
-extern ANN void free_context(void* a);
-extern ANN void free_func(void* a);
-extern ANN void free_vm_code(void* a);
-
-typedef void (*cleaner)(void*);
-static cleaner cleaners[] = { free_nspc, free_context, free_type,
-  free_value, free_func, free_vm_code };
-
-ANN void rem_ref(const VM_Object a, void* ptr) {
-  if(--a->ref_count)
-    return;
-  cleaners[a->type](ptr);
-}
index 9aa04e0a1a6674a34f610ef62a2b02d93745c866..e7e2877ca878818d6f72ea9f5d332765382856b7 100644 (file)
@@ -6,6 +6,14 @@
 #include "type.h"
 #include "nspc.h"
 
+ANN static void free_type(Type a) {
+  if(GET_FLAG(a, template))
+    free_class_def(a->def);
+  if(a->nspc)
+    REM_REF(a->nspc);
+  mp_free(Type, a);
+}
+
 ANN2(2) Type new_type(const m_uint xid, const m_str name, const Type parent) {
   const Type type = mp_alloc(Type);
   type->xid    = xid;
@@ -13,18 +21,10 @@ ANN2(2) Type new_type(const m_uint xid, const m_str name, const Type parent) {
   type->parent = parent;
   if(type->parent)
     type->size = parent->size;
-  INIT_OO(type, e_type_obj);
+  INIT_OO(type, free_type);
   return type;
 }
 
-ANN void free_type(Type a) {
-  if(GET_FLAG(a, template))
-    free_class_def(a->def);
-  if(a->nspc)
-    REM_REF(a->nspc);
-  mp_free(Type, a);
-}
-
 ANN Type type_copy(const Type type) {
   const Type a = new_type(type->xid, type->name, type->parent);
   a->nspc          = type->nspc;
index 91afaa90f3bf0f0490a84286128956547f026266..c06b0795cfe001c44aff547fdd6377c724869e96 100644 (file)
@@ -6,15 +6,7 @@
 #include "value.h"
 #include "type.h"
 
-ANN Value new_value(struct Gwion_* gwion, const Type type, const m_str name) {
-  const Value a = mp_alloc(Value);
-  a->type       = type;
-  a->name       = name;
-  a->gwion = gwion;
-  INIT_OO(a, e_value_obj);
-  return a;
-}
-ANN void free_value(Value a) {
+ANN static void free_value(Value a) {
 //  if(!GET_FLAG(a, func) && !GET_FLAG(a, constprop) && a->d.ptr && isa(a->type, t_object) < 0)
   if(!GET_FLAG(a, func) && !GET_FLAG(a, constprop) && a->d.ptr &&
 !(GET_FLAG(a, enum) && GET_FLAG(a, builtin) && a->owner_class)
@@ -27,3 +19,11 @@ ANN void free_value(Value a) {
   mp_free(Value, a);
 }
 
+ANN Value new_value(struct Gwion_* gwion, const Type type, const m_str name) {
+  const Value a = mp_alloc(Value);
+  a->type       = type;
+  a->name       = name;
+  a->gwion = gwion;
+  INIT_OO(a, free_value);
+  return a;
+}
index da48ad874125a57a70dde1c826c137da4b9d615f..1eabd258fe8b2b3a85bd611aad79083a8c4539ac 100644 (file)
@@ -368,7 +368,7 @@ ANN static inline Value template_get_ready(const Value v, const m_str tmpl, cons
       nspc_lookup_value1(v->owner, sym);
 }
 
-ANN Func find_template_match(const Env env, const Value v, const Exp_Call* exp) {
+ANN static Func _find_template_match(const Env env, const Value v, const Exp_Call* exp) {
   const Exp args = exp->args;
   const Type_List types = exp->tmpl->types;
   Func m_func = exp->m_func;
@@ -385,15 +385,25 @@ ANN Func find_template_match(const Env env, const Value v, const Exp_Call* exp)
         return env->func;
       }
       base = def = value->d.func_ref->def;
+if(!def->tmpl) {
+      if(!(value = template_get_ready(v, "template", i)))
+        continue;
+      base = value->d.func_ref->def;
+      def->tmpl = new_tmpl_list(base->tmpl->list, (m_int)i);
+}
     } else {
       if(!(value = template_get_ready(v, "template", i)))
         continue;
       base = value->d.func_ref->def;
       def = new_func_def(base->td, insert_symbol(v->name),
+//      def = new_func_def(base->td, insert_symbol(v->name),
                 base->arg_list, base->d.code, base->flag);
+//create = 1;
+//assert(base->tmpl);
       def->tmpl = new_tmpl_list(base->tmpl->list, (m_int)i);
       SET_FLAG(def, template);
     }
+//assert(def->tmpl);
     if(traverse_func_template(env, def, types) > 0) {
       nspc_pop_type(env->curr);
       if(check_call(env, exp) > 0) {
@@ -402,21 +412,49 @@ ANN Func find_template_match(const Env env, const Value v, const Exp_Call* exp)
         m_func = find_func_match(env, def->func, args);
         def->func->next = next;
         if(m_func) {
+if(!m_func->def->ret_type) {
+if(!m_func->def->td)exit(76);
+m_func->def->ret_type = type_decl_resolve(env, m_func->def->td);
+exit(77);
+}
           SET_FLAG(m_func, checked | ae_flag_template);
           goto end;
         }
       }
     }
     SET_FLAG(base, template);
-    free_func_def(def);
+//if(create)
+//    free_func_def(def);
   }
-  assert(exp->self);
-  err_msg(exp->self->pos, "arguments do not match for template call");
+//  assert(exp->self);
+//  err_msg(exp->self->pos, "arguments do not match for template call");
 end:
   free(tmpl_name);
   env_pop(env, scope);
   return m_func;
 }
+ANN Func find_template_match(const Env env, const Value value, const Exp_Call* exp) {
+//  Value v = value;
+  Type t = value->owner_class;
+  const Func f = _find_template_match(env, value, exp);
+  if(f)
+    return f;
+  while(t) {
+//assert(t->nspc);
+    const Value v = nspc_lookup_value1(t->nspc, value->d.func_ref->def->name);
+if(!v)goto next;
+    const Func f = _find_template_match(env, v, exp);
+    if(f)
+      return f;
+next:
+t = t->parent;
+}
+
+  assert(exp->self);
+  err_msg(exp->self->pos, "arguments do not match for template call");
+  return NULL;
+}
+
 
 ANN static void print_current_args(Exp e) {
   gw_err("and not\n\t");
@@ -511,6 +549,7 @@ ANN static Type check_exp_call_template(const Env env, const Exp_Call *exp) {
   Tmpl_Call tmpl = { .types=tl[0] };
   const Exp_Call tmp_func = { .func=call, .args=args, .tmpl=&tmpl, .self=base };
   const Func func = get_template_func(env, &tmp_func, base, value);
+//exit(2);
   if(base->exp_type == ae_exp_call)
     base->d.exp_call.m_func = func;
   else // if(base->exp_type == ae_exp_binary)
@@ -590,7 +629,7 @@ ANN static Type check_exp_dur(const Env env, const Exp_Dur* exp) { GWDEBUG_EXE
 
 ANN static Type check_exp_call(const Env env, Exp_Call* exp) { GWDEBUG_EXE
   if(exp->tmpl) {
-    CHECK_OO(check_exp(env, exp->func)) // â†’ puts this up ?
+    CHECK_OO(check_exp(env, exp->func))
     const Type t = actual_type(exp->func->type);
     const Value v = nspc_lookup_value1(t->owner, insert_symbol(t->name));
     if(!v)
@@ -926,7 +965,8 @@ ANN static m_bool check_stmt_list(const Env env, Stmt_List l) { GWDEBUG_EXE
 }
 
 ANN static m_bool check_signature_match(const Func_Def f, const Func parent) { GWDEBUG_EXE
-  if(GET_FLAG(parent->def, static) || GET_FLAG(f, static)) {
+//  if(GET_FLAG(parent->def, static) || GET_FLAG(f, static)) {
+  if(GET_FLAG(parent->def, static) != GET_FLAG(f, static)) { // wath me
     const m_str c_name  = f->func->value_ref->owner_class->name;
     const m_str p_name = parent->value_ref->owner_class->name;
     const m_str f_name = s_name(f->name);
@@ -946,7 +986,7 @@ ANN static m_bool parent_match_actual(const Env env, const restrict Func_Def f,
     if(compat_func(f, parent_func->def) > 0) {
       CHECK_BB(check_signature_match(f, parent_func))
       f->func->vt_index = parent_func->vt_index;
-      vector_set(&env->curr->vtable, f->func->vt_index, (vtype)func);
+      vector_set(&env->curr->vtable, f->func->vt_index, (vtype)f->func);
       return GW_OK;
     }
   } while((parent_func = parent_func->next));
@@ -964,7 +1004,9 @@ ANN static m_bool check_parent_match(const Env env, const Func_Def f) { GWDEBUG_
         return match;
     }
   }
-  if(GET_FLAG(func, member)) {
+//  if(SAFE_FLAG(func, member)) {
+//  if(GET_FLAG(func, member)) {
+  if(func->value_ref->owner_class) {
     if(!env->curr->vtable.ptr)
       vector_init(&env->curr->vtable);
     func->vt_index = vector_size(&env->curr->vtable);
index 4bf0a42c3543227dba814042ff75f3a5d5231cea..23fb0a9d315f5f26a3acb70a509d94335820d1ab 100644 (file)
@@ -8,26 +8,24 @@
 #include "nspc.h"
 #include "func.h"
 
+ANN static void free_func(Func a) {
+  if(GET_FLAG(a, template)) {
+    free_tmpl_list(a->def->tmpl);
+    mp_free(Func_Def, a->def);
+  }
+  if(a->code)
+    REM_REF(a->code);
+  mp_free(Func, a);
+}
+
 ANN Func new_func(const m_str name, const Func_Def def) {
   Func func = mp_alloc(Func);
   func->name = name;
   func->def = def;
-  INIT_OO(func, e_func_obj);
+  INIT_OO(func, free_func);
   return func;
 }
 
-ANN void free_func(Func a) {
-  if(GET_FLAG(a, ref)) {
-    if(GET_FLAG(a, template)) {
-      free_tmpl_list(a->def->tmpl);
-      mp_free(Func_Def, a->def);
-    }
-  }
-  if(a->code)
-    REM_REF(a->code);
-  mp_free(Func, a);
-}
-
 #include <string.h>
 #include "env.h"
 #include "type.h"
index 742ef6e1c7418d67f004ba6fe4d6e77f677a9a2b..7ecc459ae9e043dbdb397dcbf9cf30aa12195c9d 100644 (file)
@@ -16,12 +16,6 @@ ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list);
 ANN m_bool scan1_class_def(const Env env, const Class_Def class_def);
 ANN static m_bool scan1_stmt(const Env env, Stmt stmt);
 
-ANN static void scan1_exp_decl_template(const Type t, const Exp_Decl* decl) {
-  Exp_Decl* d = (Exp_Decl*)decl;
-  d->base = t->def;
-  d->type = t;
-}
-
 ANN static Type void_type(const Env env, const Type_Decl* td, const uint pos) {
   const Type t = known_type(env, td);
   CHECK_OO(t)
@@ -30,7 +24,7 @@ ANN static Type void_type(const Env env, const Type_Decl* td, const uint pos) {
   ERR_O(pos, "cannot declare variables of size '0' (i.e. 'void')...")
 }
 
-ANN static Type scan1_exp_decl_type(const Env env, const Exp_Decl* decl) {
+ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) {
   const Type t = void_type(env, decl->td, decl->self->pos);
   CHECK_OO(t);
   if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, ref))
@@ -49,17 +43,18 @@ ANN static Type scan1_exp_decl_type(const Env env, const Exp_Decl* decl) {
     if(GET_FLAG(decl->td, global) && env->class_def) // forbid this ?
       UNSET_FLAG(decl->td, global);
   }
-  if(GET_FLAG(t, template))
-    scan1_exp_decl_template(t, decl);
+  // for template
+  decl->base = t->def;
+  decl->type = t;
   return t;
 }
 
-ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE
+ANN m_bool scan1_exp_decl(const Env env, Exp_Decl* decl) { GWDEBUG_EXE
   CHECK_BB(env_access(env, decl->td->flag))
   env_storage(env, &decl->td->flag);
   Var_Decl_List list = decl->list;
   m_uint scope;
-  ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, decl);
+  ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
   CHECK_OB(decl->type)
   const m_bool global = GET_FLAG(decl->td, global);
   const Nspc nspc = !global ? env->curr : env->global_nspc;
@@ -90,7 +85,7 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE
     v->owner = !env->func ? env->curr : NULL;
     v->owner_class = env->scope ? NULL : env->class_def;
   } while((list = list->next));
-  ((Exp_Decl*)decl)->type = decl->list->self->value->type;
+  decl->type = decl->list->self->value->type;
   if(global)
     env_pop(env, scope);
   return GW_OK;
@@ -192,10 +187,7 @@ ANN m_bool scan1_stmt_enum(const Env env, const Stmt_Enum stmt) { GWDEBUG_EXE
       v->owner_class = env->class_def;
       v->owner = env->curr;
       SET_FLAG(v, static);
-      if(GET_FLAG(stmt, private))
-        SET_FLAG(v, private);
-      else if(GET_FLAG(stmt, protect))
-        SET_FLAG(v, protect);
+      SET_ACCESS(stmt, v)
     }
     SET_FLAG(v, const | ae_flag_enum | ae_flag_checked);
     nspc_add_value(stmt->t->owner, list->xid, v);
index 5de5a3ecc6d31b8a150d5d7e4e5946f9db1129f3..464897003b23b0fd7ddb30b727ace7b903cd9b42 100644 (file)
@@ -82,10 +82,7 @@ ANN static Value scan2_func_assign(const Env env, const Func_Def d,
     if(GET_FLAG(f, member))
       SET_FLAG(v, member);
     else SET_FLAG(v, static);
-    if(GET_FLAG(d, private))
-      SET_FLAG(v, private);
-    else if(GET_FLAG(d, protect))
-      SET_FLAG(v, protect);
+    SET_ACCESS(d, v)
   }
   d->func = v->d.func_ref = f;
   return f->value_ref = v;
@@ -133,9 +130,19 @@ ANN static inline Value prim_value(const Env env, const Symbol s) {
 }
 
 ANN static inline m_bool scan2_exp_primary(const Env env, const Exp_Primary* prim) { GWDEBUG_EXE
-  if(prim->primary_type == ae_primary_hack)
+  if(prim->primary_type == ae_primary_hack) {
     CHECK_BB(scan2_exp(env, prim->d.exp))
-  else if(prim->primary_type == ae_primary_id) {
+    Exp e = prim->d.exp;
+    do {
+      if(e->exp_type == ae_exp_decl) {
+        Var_Decl_List l = e->d.exp_decl.list;
+        do {
+           const Value v = l->self->value;
+           SET_FLAG(v, used);
+        }while ((l = l->next));
+      }
+    } while((e = e->next));
+  } else if(prim->primary_type == ae_primary_id) {
     const Value v = prim_value(env, prim->d.var);
     if(v)
       SET_FLAG(v, used);
@@ -335,14 +342,14 @@ ANN2(1,2) static Value func_value(const Env env, const Func f,
   if(!overload) {
     ADD_REF(v);
     nspc_add_value(env->curr, f->def->name, v);
-  } else {
+  } else if(!GET_FLAG(f->def, template)) {
     f->next = overload->d.func_ref->next;
     overload->d.func_ref->next = f;
   }
   return v;
 }
 
-ANN2(1, 2) static m_bool scan2_func_def_template (const Env env, const Func_Def f, const Value overload) { GWDEBUG_EXE
+ANN2(1, 2) static m_bool scan2_func_def_template(const Env env, const Func_Def f, const Value overload) { GWDEBUG_EXE
   const m_str func_name = s_name(f->name);
   const Func func = scan_new_func(env, f, func_name);
   const Value value = func_value(env, func, overload);
@@ -350,13 +357,16 @@ ANN2(1, 2) static m_bool scan2_func_def_template (const Env env, const Func_Def
   SET_FLAG(value->type, func); // the only types with func flag, name could be better
   const Symbol sym = func_symbol(env->curr->name, func_name, "template", overload ? ++overload->offset : 0);
   nspc_add_value(env->curr, sym, value);
+if(!overload) {
+  ADD_REF(value)
+  nspc_add_value(env->curr, f->name, value);
+}
   return GW_OK;
 }
 
 ANN static m_bool scan2_func_def_builtin(const Func func, const m_str name) { GWDEBUG_EXE
   SET_FLAG(func, builtin);
-  func->code = new_vm_code(NULL, func->def->stack_depth, GET_FLAG(func, member), name);
-  SET_FLAG(func->code, builtin);
+  func->code = new_vm_code(NULL, func->def->stack_depth, func->flag, name);
   func->code->native_func = (m_uint)func->def->d.dl_func_ptr;
   return GW_OK;
 }
@@ -431,6 +441,7 @@ ANN2(1,2,4) static Value func_create(const Env env, const Func_Def f,
   scan2_func_def_flag(f);
   if(GET_FLAG(f, builtin))
     CHECK_BO(scan2_func_def_builtin(func, func->name))
+//  if(GET_FLAG(func, member) && !GET_FLAG(func->def, func))
   if(GET_FLAG(func, member))
     f->stack_depth += SZ_INT;
   if(GET_FLAG(func->def, variadic))
@@ -452,11 +463,14 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE
     const Symbol sym  = func_symbol(env->curr->name, func_name, NULL, overload ? ++overload->offset : 0);
     func_name = s_name(sym);
   } else {
+if(f->func)
+  func_name = f->func->name;
+else
     func_name = func_tmpl_name(env, f);
     const Func func = nspc_lookup_func1(env->curr, insert_symbol(func_name));
     if(func) {
       f->ret_type = type_decl_resolve(env, f->td);
-      return f->arg_list ? scan2_args(env, f) : 1;
+      return f->arg_list ? scan2_args(env, f) : GW_OK;
     }
   }
   const Func base = get_func(env, f);
@@ -467,8 +481,9 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE
     CHECK_OB((value = func_create(env, f, overload, func_name)))
     if(GET_FLAG(f, global))
       env_pop(env, scope);
-  } else
+  } else {
     f->func = base;
+}
   if(f->arg_list)
     CHECK_BB(scan2_args(env, f))
   if(!GET_FLAG(f, builtin) && f->d.code->d.stmt_code.stmt_list)
index c0a586c639132e0e4cb92e29459df73eb8aa2220..3d369016c36586b57ee65a47b5b28dd360ce6995 100644 (file)
@@ -34,7 +34,6 @@ ANN static void shreduler_parent(const VM_Shred out, const Vector v) {
     vector_release(v);
     out->parent->child.ptr = NULL;
   }
-  out->parent = NULL;
 }
 
 ANN static void shreduler_child(const Shreduler s, const Vector v) {
index 4fddafe820359eb56905e7136ebdbd9bf3386411..f614e31d9dd006a90d240e667463ae6d02547e08 100644 (file)
@@ -6,13 +6,21 @@
 #include "oo.h"
 #include "vm.h"
 #include "env.h"
+#include "nspc.h"//dot func
+#include "func.h"//dot func
 #include "type.h"
 #include "instr.h"
 #include "object.h"
+#include "import.h"
 #include "ugen.h"
 #include "shreduler_private.h"
 #include "emit.h"
 #include "gwion.h"
+#include "map_private.h"
+
+#include "value.h"
+
+
 static inline uint64_t splitmix64_stateless(uint64_t index) {
   uint64_t z = (index + UINT64_C(0x9E3779B97F4A7C15));
   z = (z ^ (z >> 30)) * UINT64_C(0xBF58476D1CE4E5B9);
@@ -74,7 +82,6 @@ ANN m_uint vm_add_shred(const VM* vm, const VM_Shred shred) {
   shred->me = new_shred(shred);
   shreduler_add(vm->shreduler, shred);
   shredule(vm->shreduler, shred, .5);
-  shred->instr = shred->code->instr;
   return shred->xid;
 }
 
@@ -100,7 +107,7 @@ ANN static inline void vm_ugen_init(const VM* vm) {
 #define VM_INFO                                                              \
   if(s->curr)                                                                \
     gw_err("shred[%" UINT_F "] mem[%" INT_F"] reg[%" INT_F"]\n", shred->xid, \
-    shred->mem - (shred->_reg + SIZEOF_REG), shred->reg - shred->_reg);
+    mem - (shred->_reg + SIZEOF_REG), reg - shred->_reg);
 #else
 #define VM_INFO
 #endif
@@ -111,20 +118,674 @@ static struct timespec exec_time;
 #include <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[] = {
+    &&regpushimm, &&regpushfloat, &&regpushother, &&regpushaddr,
+    &&regpushmem, &&regpushmemfloat, &&regpushmemother, &&regpushmemaddr,
+    &&pushnow,
+    &&baseint, &&basefloat, &&baseother, &&baseaddr,
+    &&regdup,
+    &&mempushimm, &&memsetimm,
+    &&regpop, &&regpushptr,
+    &&funcreturn,
+    &&_goto,
+    &&allocint, &&allocfloat, &&allocother, &&allocaddr,
+    &&intplus, &&intminus, && intmul, &&intdiv, &&intmod,
+    // int relationnal
+    &&inteq, &&intne, &&intand, &&intor,
+    &&intgt, &&intge, &&intlt, &&intle,
+    &&intsl, &&intsr, &&intsand, &&intsor, &&intxor,
+    &&intnegate, &&intnot, &&intcmp,
+    &&intrassign,
+    &&intradd, &&intrsub, &&intrmul, &&intrdiv, &&intrmod,
+    &&intrsl, &&intrsr, &&intrsand, &&intrsor, &&intrxor,
+    &&preinc, &&predec,
+    &&postinc, &&postdec,
+    &&floatadd, &&floatsub, &&floatmul, &&floatdiv,
+// logical
+    &&floatand, &&floator, &&floateq, &&floatne,
+    &&floatgt, &&floatge, &&floatlt, &&floatle,
+    &&floatneg, &&floatnot,
+    &&floatrassign, &&floatradd, &&floatrsub, &&floatrmul, &&floatrdiv,
+    &&ifadd, &&ifsub, &&ifmul, &&ifdiv,
+    &&ifand, &&ifor, &&ifeq, &&ifne, &&ifgt, &&ifge, &&iflt, &&ifle,
+    &&ifrassign, &&ifradd, &&ifrsub, &&ifrmul, &&ifrdiv,
+    &&fiadd, &&fisub, &&fimul, &&fidiv,
+    &&fiand, &&fior, &&fieq, &&fine, &&figt, &&fige, &&filt, &&file,
+    &&firassign, &&firadd, &&firsub, &&firmul, &&firdiv,
+    &&itof, &&ftoi,
+    &&timeadv,
+    &&funcusr, &&funcmember, &&funcstatic,
+    &&sporkini, &&sporkfunc, &&sporkthis, &&sporkexp, &&sporkend,
+    &&funcptr,
+    &&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat,
+    &&decintaddr, &&initloop,
+    &&newobj,
+    &&addref, &&assign, &&remref,
+    &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr,
+    &&staticint, &&staticfloat, &&staticother,
+    &&dotfunc,&&staticcode, &&pushstr,
+    &&gcini, &&gcadd, &&gcend,
+    &&gack, &&other
+  };
   const Shreduler s = vm->shreduler;
   VM_Shred shred;
+
+
+#define DISPATCH()\
+  instr =(Instr)(ip[pc++]);\
+  VM_INFO;\
+  goto *dispatch[instr->opcode];
+
   while((shred = shreduler_get(s))) {
+register VM_Code code = shred->code;
+register
+m_uint* ip = code->instr->ptr + OFFSET;
+register
+size_t pc = shred->pc;
+register
+m_bit* reg = shred->reg;
+register
+m_bit* mem = shred->mem;
+
+register union {
+M_Object obj;
+VM_Code code;
+VM_Shred child;
+} a;
+
 #ifdef VMBENCH
 struct timespec exec_ini, exec_end, exec_ret;
 clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_ini);
 #endif
   do {
-//      const Instr instr = (Instr)vector_at(shred->code->instr, shred->pc++);
-      const Instr instr = (Instr)vector_at(shred->instr, shred->pc++);
+    register Instr instr; DISPATCH();
+regpushimm:
+  *(m_uint*)reg = instr->m_val;
+  reg += SZ_INT;
+  DISPATCH();
+regpushfloat:
+//  *(m_float*)reg = instr->f;
+  *(m_float*)reg = *(m_float*)instr->ptr;
+  reg += SZ_FLOAT;
+  DISPATCH();
+regpushother:
+  LOOP_OPTIM
+  for(m_uint i = 0; i <= instr->m_val2; i+= SZ_INT)
+//    *(m_bit**)(reg+i) = (m_bit*)(instr->m_val + i);
+    *(m_bit**)(reg+i) = (m_bit*)(instr->ptr + i);
+  reg += instr->m_val2;
+  DISPATCH();
+regpushaddr:
+//  *(m_bit**)reg =  &instr->m_val;
+  *(m_bit**)reg =  instr->ptr;
+  reg += SZ_INT;
+  DISPATCH()
+regpushmem:
+  *(m_uint*)reg = *(m_uint*)(mem + instr->m_val);
+  reg += SZ_INT;
+  DISPATCH();
+regpushmemfloat:
+  *(m_float*)reg = *(m_float*)(mem + instr->m_val);
+  reg += SZ_FLOAT;
+  DISPATCH();
+regpushmemother:
+  LOOP_OPTIM
+  for(m_uint i = 0; i <= instr->m_val2; i+= SZ_INT)
+    *(m_uint*)(reg+i) = *(m_uint*)((mem + instr->m_val) + i);
+  reg += instr->m_val2;
+  DISPATCH();
+regpushmemaddr:
+  *(m_bit**)reg = (mem + instr->m_val);
+  reg += SZ_INT;
+  DISPATCH()
+pushnow:
+  *(m_float*)reg = vm->bbq->pos;
+  reg += SZ_FLOAT;
+  DISPATCH();
+baseint:
+  *(m_uint*)reg = *(m_uint*)(shred->base + instr->m_val);
+  reg += SZ_INT;
+  DISPATCH();
+basefloat:
+  *(m_float*)reg = *(m_float*)(shred->base + instr->m_val);
+  reg += SZ_FLOAT;
+  DISPATCH();
+baseother:
+  LOOP_OPTIM
+  for(m_uint i = 0; i <= instr->m_val2; i+= SZ_INT)
+    *(m_uint*)(reg+i) = *(m_uint*)((shred->base + instr->m_val) + i);
+  reg += instr->m_val2;
+  DISPATCH();
+baseaddr:
+  *(m_bit**)reg = (shred->base + instr->m_val);
+  reg += SZ_INT;
+  DISPATCH();
+regdup:
+  *(m_uint*)reg = *(m_uint*)(reg-SZ_INT);
+  reg += SZ_INT;
+  DISPATCH()
+mempushimm:
+  *(m_uint*)mem = instr->m_val;
+  mem += SZ_INT;
+  DISPATCH();
+memsetimm:
+  *(m_uint*)(mem+instr->m_val) = instr->m_val2;
+  DISPATCH();
+regpop:
+  reg -= instr->m_val;
+  DISPATCH();
+regpushptr:
+  *(m_uint*)(reg-SZ_INT) = instr->m_val;
+  DISPATCH()
+funcreturn:
+  pc = *(m_uint*)(mem-SZ_INT);
+  code = *(VM_Code*)(mem-SZ_INT*2);
+  mem -= (*(m_uint*)(mem-SZ_INT*3) + SZ_INT*3);
+  ip = code->instr->ptr + OFFSET;
+  DISPATCH();
+_goto:
+  pc = instr->m_val;
+  DISPATCH();
+allocint:
+  *(m_uint*)reg = *(m_uint*)(mem+instr->m_val) = 0;
+  reg += SZ_INT;
+  DISPATCH()
+allocfloat:
+  *(m_float*)reg = *(m_float*)(mem+instr->m_val) = 0;
+  reg += SZ_FLOAT;
+  DISPATCH()
+allocother:
+  LOOP_OPTIM
+  for(m_uint i = 0; i <= instr->m_val; i += SZ_INT)
+    *(m_uint*)(reg+i) = (*(m_uint*)(mem+instr->m_val+i) = 0);
+  reg += instr->m_val2;
+  DISPATCH()
+allocaddr:
+  *(m_uint*)(mem+instr->m_val) = 0; // just set object to null in
+  *(m_bit**)reg = mem + instr->m_val;
+  reg += SZ_INT;
+  DISPATCH()
+#define OP(t, sz, op, ...) \
+  reg -= sz;\
+  __VA_ARGS__\
+  *(t*)(reg - sz) op##= *(t*)reg;\
+  DISPATCH();
+
+#define INT_OP(op, ...) OP(m_int, SZ_INT, op, __VA_ARGS__)
+intplus:  INT_OP(+)
+intminus: INT_OP(-)
+intmul:   INT_OP(*)
+intdiv:   INT_OP(/, TEST0(m_int, 0))
+intmod:   INT_OP(%, TEST0(m_int, 0))
+
+#define LOGICAL(t, sz0, sz, op)\
+reg -= sz0;\
+*(m_int*)(reg-SZ_INT) = (*(t*)(reg - SZ_INT) op *(t*)(reg+sz));\
+DISPATCH()
+
+// rename to int logical
+#define INT_REL(op) LOGICAL(m_int, SZ_INT, 0, op)
+inteq:   INT_REL(==)
+intne:   INT_REL(!=)
+intand:  INT_REL(&&)
+intor:   INT_REL(||)
+intgt:   INT_REL(>)
+intge:   INT_REL(>=)
+intlt:   INT_REL(<)
+intle:   INT_REL(<=)
+intsl:   INT_REL(<<)
+intsr:   INT_REL(>>)
+intsand: INT_REL(&)
+intsor:  INT_REL(|)
+intxor:  INT_REL(^)
+
+#define SELF(t, sz,op) \
+  *(t*)(reg - sz) = op*(t*)(reg - sz);\
+  DISPATCH();
+#define INT_SELF(op) SELF(m_int, SZ_INT, op)
+intnegate:
+  *(m_int*)(reg - SZ_INT) *= -1;
+  DISPATCH()
+intnot: INT_SELF(!)
+intcmp: INT_SELF(~)
+
+intrassign:
+  reg -= SZ_INT;
+/*assert(*(m_int**)reg);*/
+  **(m_int**)reg = *(m_int*)(reg-SZ_INT);
+  DISPATCH()
+
+#define R(t, sz, op, ...) \
+reg -= SZ_INT;\
+__VA_ARGS__\
+*(t*)(reg-sz) = (**(t**)reg op##= (*(t*)(reg-sz)));\
+DISPATCH()
+#define INT_R(op, ...) R(m_int, SZ_INT, op, __VA_ARGS__)
+intradd: INT_R(+)
+intrsub: INT_R(-)
+intrmul: INT_R(*)
+intrdiv: INT_R(/, TEST0(m_int, -SZ_INT))
+intrmod: INT_R(%, TEST0(m_int, -SZ_INT))
+intrsl: INT_R(<<)
+intrsr: INT_R(>>)
+intrsand: INT_R(&)
+intrsor: INT_R(|)
+intrxor: INT_R(^)
+
+#define INT_PRE(op) \
+/*assert(*(m_int**)(reg-SZ_INT));*/\
+*(m_int*)(reg- SZ_INT) = op(**(m_int**)(reg-SZ_INT));\
+DISPATCH()
+preinc: INT_PRE(++)
+predec: INT_PRE(--)
+
+#define INT_POST(op) \
+/*assert(*(m_int**)(reg-SZ_INT));*/\
+*(m_int*)(reg- SZ_INT) = (**(m_int**)(reg-SZ_INT))op;\
+DISPATCH()
+postinc: INT_POST(++)
+postdec: INT_POST(--)
+
+
+#define FLOAT_OP(op) OP(m_float, SZ_FLOAT, op)
+
+floatadd: FLOAT_OP(+)
+floatsub: FLOAT_OP(-)
+floatmul: FLOAT_OP(*)
+floatdiv: FLOAT_OP(/)
+
+#define FLOAT_LOGICAL(op) LOGICAL(m_float, SZ_FLOAT * 2 - SZ_INT, \
+  SZ_FLOAT - SZ_INT, op)
+floatand: FLOAT_LOGICAL(&&)
+floator: FLOAT_LOGICAL(||)
+floateq: FLOAT_LOGICAL(==)
+floatne: FLOAT_LOGICAL(!=)
+floatgt: FLOAT_LOGICAL(>)
+floatge: FLOAT_LOGICAL(>=)
+floatlt: FLOAT_LOGICAL(<)
+floatle: FLOAT_LOGICAL(<=)
+
+floatneg: SELF(m_float, SZ_FLOAT, -)
+
+floatnot:
+  reg -= SZ_FLOAT - SZ_INT;
+  *(m_int*)(reg - SZ_INT) = !*(m_float*)(reg - SZ_INT);
+  DISPATCH()
+
+floatrassign:
+  reg -= SZ_INT;
+  **(m_float**)reg = *(m_float*)(reg-SZ_FLOAT);
+  DISPATCH()
+
+#define FLOAT_R(op, ...) R(m_float, SZ_FLOAT, op)
+floatradd: FLOAT_R(+)
+floatrsub: FLOAT_R(-)
+floatrmul: FLOAT_R(*)
+floatrdiv: FLOAT_R(/)
+
+#define IF_OP(op) \
+  reg -=SZ_INT;\
+    *(m_float*)(reg-SZ_FLOAT) = (m_float)*(m_int*)(reg-SZ_FLOAT) op \
+    *(m_float*)(reg + SZ_INT - SZ_FLOAT); \
+  DISPATCH()
+ifadd: IF_OP(+)
+ifsub: IF_OP(-)
+ifmul: IF_OP(*)
+ifdiv: IF_OP(/)
+
+#define IF_LOGICAL(op)\
+  reg -= SZ_FLOAT; \
+  *(m_int*)(reg-SZ_INT) = (*(m_int*)(reg-SZ_INT) op (m_int)*(m_float*)reg); \
+  DISPATCH()
+ifand: IF_LOGICAL(&&)
+ifor: IF_LOGICAL(||)
+ifeq: IF_LOGICAL(==)
+ifne: IF_LOGICAL(!=)
+ifgt: IF_LOGICAL(>)
+ifge: IF_LOGICAL(>=)
+iflt: IF_LOGICAL(<)
+ifle: IF_LOGICAL(<=)
+
+#define IF_R(op) \
+  reg -= SZ_INT * 2 - SZ_FLOAT; \
+  *(m_float*)(reg-SZ_FLOAT) = (**(m_float**)(reg +SZ_INT - SZ_FLOAT) op##= \
+    (m_float)*(m_int*)(reg-SZ_FLOAT)); \
+  DISPATCH()
+ifrassign: IF_R()
+ifradd: IF_R(+)
+ifrsub: IF_R(-)
+ifrmul: IF_R(*)
+ifrdiv: IF_R(/)
+
+#define FI_OP(op)\
+  reg -= SZ_INT; \
+  *(m_float*)(reg-SZ_FLOAT) op##= (m_float)*(m_int*)reg; \
+  DISPATCH()
+fiadd: FI_OP(+)
+fisub: FI_OP(-)
+fimul: FI_OP(*)
+fidiv: FI_OP(/)
+
+#define FI_LOGICAL(op) \
+  reg -= SZ_FLOAT; \
+  *(m_int*)(reg-SZ_INT) = ((m_int)*(m_float*)(reg-SZ_INT) op\
+    *(m_int*)(reg + SZ_FLOAT-SZ_INT)); \
+  DISPATCH()
+fiand: FI_LOGICAL(&&)
+fior: FI_LOGICAL(||)
+fieq: FI_LOGICAL(==)
+fine: FI_LOGICAL(!=)
+figt: FI_LOGICAL( >)
+fige: FI_LOGICAL(>=)
+filt: FI_LOGICAL( <)
+file: FI_LOGICAL(<=)
+
+firassign:
+  reg -=SZ_FLOAT;
+  *(m_int*)(reg-SZ_INT) = **(m_int**)(reg + SZ_FLOAT-SZ_INT) =
+    (m_int)*(m_float*)(reg-SZ_INT);
+  DISPATCH()
+
+#define FI_R(op) \
+  reg -= SZ_FLOAT; \
+  *(m_int*)(reg-SZ_INT) = (**(m_int**)(reg+SZ_FLOAT -SZ_INT) op##= \
+    (m_int)(*(m_float*)(reg-SZ_INT))); \
+  DISPATCH()
+firadd: FI_R(+)
+firsub: FI_R(-)
+firmul: FI_R(*)
+firdiv: FI_R(/)
+
+itof:
+  reg -=SZ_INT - SZ_FLOAT;
+  *(m_float*)(reg-SZ_FLOAT) = (m_float)*(m_int*)(reg-SZ_FLOAT);
+  DISPATCH()
+ftoi:
+  reg -= SZ_FLOAT -SZ_INT;
+  *(m_int*)(reg-SZ_INT) = (m_int)*(m_float*)(reg-SZ_INT);
+  DISPATCH()
+
+timeadv:
+  reg -= SZ_FLOAT;
+{
+  register const m_float f = *(m_float*)(reg-SZ_FLOAT);
+  *(m_float*)(reg-SZ_FLOAT) = (shred->wake_time += f);
+  shredule(s, shred, f);
+}
+shred->code = code;
+shred->reg = reg;
+shred->mem = mem;
+shred->pc = pc;
+  break;
+
+funcusr:
+{
+  reg -= SZ_INT * 2;
+  register const m_uint push = *(m_uint*)(reg + SZ_INT) + *(m_uint*)(mem-SZ_INT);
+  mem += push;
+  *(m_uint*)  mem = push;mem += SZ_INT;
+  *(VM_Code*) mem = code; mem += SZ_INT;
+  *(m_uint*)  mem = pc; mem += SZ_INT;
+  pc = 0;
+  code = *(VM_Code*)reg;
+//puts(code->name);
+//  assert(code);
+  ip = code->instr->ptr + OFFSET;
+  m_uint stack_depth = code->stack_depth;
+  if(stack_depth) {
+    register const m_uint f = GET_FLAG(code, member) ? SZ_INT : 0;
+    if(f) {
+      *(m_uint*)mem = *(m_uint*)(reg - SZ_INT);
+      stack_depth -= SZ_INT;
+    }
+    reg-=code->stack_depth;
+    LOOP_OPTIM
+    for(m_uint i = 0; i < stack_depth; i+= SZ_INT)
+      *(m_uint*)(mem+i+f) = *(m_uint*)(reg+i);
+  }
+  if(overflow_(mem, shred))
+    Except(shred, "StackOverflow");
+}
+//puts(code->name);
+DISPATCH();
+funcmember:
+{
+  reg -= SZ_INT * 2;
+  a.code = *(VM_Code*)reg;
+  register const m_uint local_depth =   *(m_uint*)(reg + SZ_INT);
+  register m_bit* m = mem + local_depth;
+//  assert(a.code);
+  register const m_uint stack_depth = a.code->stack_depth;
+  register const m_uint depth = stack_depth -SZ_INT;
+  reg -= stack_depth;
+  *(m_uint*)m = *(m_uint*)(reg + depth);
+//  for(m_uint i = 0; i < stack_depth; i+= SZ_INT)
+  LOOP_OPTIM
+  for(m_uint i = 0; i < depth; i+= SZ_INT)
+    *(m_uint*)(m+i+SZ_INT) = *(m_uint*)(reg+i);
+  if(overflow_(m, shred))
+    Except(shred, "StackOverflow");
+  shred->mem = m;
+  shred->pc = pc;
+  if(GET_FLAG(a.code, ctor)) {
+    register const f_xtor f = (f_xtor)a.code->native_func;
+    f(*(M_Object*)m, NULL, shred);// callnat
+    goto funcend2;//2
+  }
+  register const f_mfun f = (f_mfun)a.code->native_func;
+  f((*(M_Object*)m), reg, shred);//call native
+  goto funcend;
+}
+funcstatic:
+{
+  reg -= SZ_INT * 2;
+  a.code = *(VM_Code*)reg;
+  register const m_uint local_depth = *(m_uint*)(reg + SZ_INT);
+  register m_bit* m = mem + local_depth;
+  //assert(a.code);
+  register const m_uint stack_depth = a.code->stack_depth;
+  if(stack_depth) {
+    reg -= stack_depth;
+    LOOP_OPTIM
+    for(m_uint i = 0; i < stack_depth; i+= SZ_INT)
+      *(m_uint*)(m+i) = *(m_uint*)(reg+i);
+  }
+  if(overflow_(m, shred))
+    Except(shred, "StackOverflow");
+//  shred->reg = reg;
+  shred->mem = m;
+  shred->pc = pc;
+  register const f_sfun f = (f_sfun)a.code->native_func;
+  f(reg, shred);
+funcend:
+  reg += instr->m_val;
+funcend2:
+  if(!s->curr)break;
+  pc = shred->pc;
+  DISPATCH()
+}
+sporkini:
+  a.child = init_spork_shred(shred, (VM_Code)instr->m_val);
+  DISPATCH()
+sporkfunc:
+  LOOP_OPTIM
+  for(m_uint i = 0; i < instr->m_val; i+= SZ_INT)
+    *(m_uint*)(a.child->reg + i) = *(m_uint*)(reg + i - SZ_INT);
+  a.child->reg += instr->m_val;
+  DISPATCH()
+sporkthis:
+  *(M_Object*)a.child->reg = *(M_Object*)(reg + instr->m_val);
+  a.child->reg += SZ_INT;
+  DISPATCH()
+sporkexp:
+  LOOP_OPTIM
+  for(m_uint i = 0; i < instr->m_val; i+= SZ_INT)
+    *(m_uint*)(a.child->mem + i) = *(m_uint*)(mem+i);
+  DISPATCH()
+sporkend:
+  *(M_Object*)(reg-SZ_INT) = a.child->me;
+  DISPATCH()
+funcptr:
+  if(!GET_FLAG((VM_Code)a.code, builtin))
+    goto funcusr;
+  else if(GET_FLAG((VM_Code)a.code, member))
+    goto funcmember;
+  else
+    goto funcstatic;
+brancheqint:
+  reg -= SZ_INT;
+  if(!*(m_uint*)reg)
+    pc = instr->m_val;
+  DISPATCH();
+branchneint:
+  reg -= SZ_INT;
+  if(*(m_uint*)reg)
+    pc = instr->m_val;
+  DISPATCH();
+brancheqfloat:
+  reg -= SZ_FLOAT;
+  if(!*(m_float*)reg)
+    pc = instr->m_val;
+  DISPATCH();
+branchnefloat:
+  reg -= SZ_FLOAT;
+  if(*(m_float*)reg)
+    pc = instr->m_val;
+  DISPATCH();
+decintaddr:
+  --(*((m_uint*)(instr->m_val)));
+  DISPATCH()
+initloop:
+  reg -= SZ_INT;
+  (*(m_uint*)instr->m_val) = labs(*(m_int*)reg);
+  DISPATCH()
+newobj:
+  *(M_Object*)reg = new_object(shred, (Type)instr->m_val);
+  reg += SZ_INT;
+  DISPATCH()
+addref:
+//  assert(instr->m_val ? *(m_bit**)(reg-SZ_INT) : reg); // scan-build
+  if((a.obj = instr->m_val ? **(M_Object**)(reg-SZ_INT) :
+    *(M_Object*)(reg-SZ_INT)))
+    ++a.obj->ref;
+  DISPATCH()
+assign:
+  reg -= SZ_INT;
+  a.obj = *(M_Object*)(reg-SZ_INT);
+//  assert(*(M_Object**)reg); // scan-build
+  const M_Object tgt = **(M_Object**)reg;
+  if(tgt) {
+    --tgt->ref;
+    _release(tgt, shred);
+  }
+  **(M_Object**)reg = a.obj;
+  DISPATCH()
+remref:
+  release(*(M_Object*)(mem + instr->m_val), shred);
+  DISPATCH()
+except:
+  if(!(a.obj  = *(M_Object*)(reg+instr->m_val)))
+    Except(shred, "NullPtrException");
+  DISPATCH();
+allocmemberaddr:
+  a.obj = *(M_Object*)mem;
+  *(m_bit**)reg = a.obj->data + instr->m_val;
+  reg += SZ_INT;
+  DISPATCH()
+dotmember:
+  *(m_uint*)(reg-SZ_INT) = *(m_uint*)(a.obj->data + instr->m_val);
+  DISPATCH()
+dotfloat:
+  *(m_float*)(reg-SZ_INT) = *(m_float*)(a.obj->data + instr->m_val);
+  reg += SZ_FLOAT - SZ_INT;
+  DISPATCH()
+dotother:
+  LOOP_OPTIM
+  for(m_uint i = 0; i <= instr->m_val2; i += SZ_INT)
+    *(m_uint*)(reg+i-SZ_INT) = *(m_uint*)((a.obj->data + instr->m_val) + i);
+  reg += instr->m_val2 - SZ_INT;
+  DISPATCH()
+dotaddr:
+  *(m_bit**)(reg-SZ_INT) = (a.obj->data + instr->m_val);
+  DISPATCH()
+staticint:
+  *(m_uint*)reg = *(m_uint*)instr->m_val;
+  reg += SZ_INT;
+  DISPATCH()
+staticfloat:
+  *(m_float*)reg = *(m_float*)instr->m_val;
+  reg += SZ_FLOAT;
+  DISPATCH()
+staticother:
+  LOOP_OPTIM
+  for(m_uint i = 0; i <= instr->m_val2; i += SZ_INT)
+    *(m_uint*)(reg+i) = *(m_uint*)(instr->m_val + i);
+  reg += instr->m_val2;
+  DISPATCH()
+dotfunc:
+  assert(a.obj);
+//  *(VM_Code*)(reg) = ((Func)vector_at(&a.obj->type_ref->nspc->vtable, instr->m_val))->code;
+  *(VM_Code*)(reg) = ((Func)vector_at(a.obj->vtable, instr->m_val))->code;
+  reg += SZ_INT;
+  DISPATCH()
+//dottemplate:
+staticcode:
+  (*(VM_Code*)reg = ((Func)instr->m_val)->code);
+  reg += SZ_INT;
+  DISPATCH()
+pushstr:
+  *(M_Object*)reg = new_string2(shred, (m_str)instr->m_val);
+  reg += SZ_INT;
+  DISPATCH();
+gcini:
+  vector_add(&shred->gc, 0);
+  DISPATCH();
+gcadd:
+  vector_add(&shred->gc, *(vtype*)(reg-SZ_INT));
+  DISPATCH();
+gcend:
+  while((a.obj = (M_Object)vector_pop(&shred->gc))) {
+    assert(a.obj);
+    _release(a.obj, shred);
+  }
+  DISPATCH()
+gack:
+  gack(reg, instr);
+  DISPATCH()
+other:
+shred->code = code;
+shred->reg = reg;
+shred->mem = mem;
+shred->pc = pc;
       instr->execute(shred, instr);
-      VM_INFO;
+if(!s->curr)break;
+code = shred->code;
+ip = shred->code->instr->ptr + OFFSET;
+reg = shred->reg;
+mem = shred->mem;
+pc = shred->pc;
+DISPATCH()
     } while(s->curr);
 #ifdef VMBENCH
 clock_gettime(CLOCK_THREAD_CPUTIME_ID, &exec_end);
@@ -135,8 +796,9 @@ timespecadd(&exec_time, &exec_ret, &exec_time);
   if(!vm->is_running) {
 #ifdef VMBENCH
     printf("[VM] exec time %lu.%09lu\n", exec_time.tv_sec, exec_time.tv_nsec);
+    printf("[VM] exec time %09lu\n", exec_time.tv_nsec/1000);
 #endif
     return;
-  }
+}
   vm_ugen_init(vm);
 }
index bc93a29f9753c0bca51e054116b5b3bf354e5836..be729fe0a5a88db98d2e0e0ed428f76a99ce2269 100644 (file)
 #include "array.h"
 #include "memoize.h"
 
-VM_Code new_vm_code(const Vector instr, const m_uint stack_depth,
-    const m_bool need_this, const m_str name) {
-  VM_Code code           = mp_alloc(VM_Code);
-  code->instr            = instr ?  vector_copy(instr) : NULL;
-  code->name             = strdup(name);
-  code->stack_depth      = stack_depth;
-  code->native_func      = 0;
-  if(need_this)
-    SET_FLAG(code, member);
-  INIT_OO(code, e_code_obj)
-  return code;
-}
-
 ANN static void free_code_instr_gack(const Instr instr) {
-  const Vector v = *(Vector*)instr->ptr;
+  const Vector v = (Vector)instr->m_val2;
   for(m_uint i = vector_size(v) + 1; --i;)
     REM_REF(((Type)vector_at(v, i - 1)));
   free_vector(v);
@@ -41,20 +28,18 @@ ANN static void free_array_info(ArrayInfo* info) {
 ANN static void free_code_instr(const Vector v) {
   for(m_uint i = vector_size(v) + 1; --i;) {
     const Instr instr = (Instr)vector_at(v, i - 1);
-    if(instr->execute == SporkExp)
-      REM_REF((VM_Code)instr->m_val2)
-    else if(instr->execute == SporkFunc)
-      REM_REF((VM_Code)instr->m_val2)
+    if(instr->opcode == (m_uint)SporkIni)
+      REM_REF((VM_Code)instr->m_val)
     else if(instr->execute == ArrayAlloc)
-      free_array_info(*(ArrayInfo**)instr->ptr);
-    else if(instr->execute == Gack)
+      free_array_info((ArrayInfo*)instr->m_val);
+    else if(instr->opcode == (m_uint)Gack)
       free_code_instr_gack(instr);
     else if(instr->execute == BranchSwitch)
       free_map((Map)instr->m_val2);
     else if(instr->execute == SwitchIni) {
       free_vector((Vector)instr->m_val);
       free_map((Map)instr->m_val2);
-    } else if(instr->execute == InitLoopCounter)
+    } else if(instr->opcode == (m_uint)InitLoopCounter)
       free((m_int*)instr->m_val);
     else if(instr->execute == VarargIni) {
       if(instr->m_val2)
@@ -65,13 +50,26 @@ ANN static void free_code_instr(const Vector v) {
   free_vector(v);
 }
 
-void free_vm_code(VM_Code a) {
+ANN static void free_vm_code(VM_Code a) {
 #ifndef NOMEMOIZE
   if(a->memoize)
     memoize_end(a->memoize);
 #endif
-  if(a->instr)
+  if(!GET_FLAG(a, builtin))
+//  if(a->instr)
     free_code_instr(a->instr);
   free(a->name);
   mp_free(VM_Code, a);
 }
+
+VM_Code new_vm_code(const Vector instr, const m_uint stack_depth,
+    const ae_flag flag, const m_str name) {
+  VM_Code code           = mp_alloc(VM_Code);
+  code->instr            = instr ?  vector_copy(instr) : NULL;
+  code->name             = strdup(name);
+  code->stack_depth      = stack_depth;
+  code->flag = flag;
+  INIT_OO(code, free_vm_code)
+  return code;
+}
+
index b2b9b24f16aa1d919eb4dd15ee2f14adaabbf759..4f233108bbe8a414773bc0c06bba871dbd66d402 100644 (file)
@@ -1,4 +1,4 @@
-// [contains] NullFuncPtrException
+// [contains] NullPtrException
 class C
 {
        typedef void test();
index 879ac9a0a8d1243868438559c2a08ef836c14cc3..e31849738bc1dd37476cbc7138eda3d290420f0a 100644 (file)
@@ -1,4 +1,4 @@
-// [contains] NullFuncPtrException
+// [contains] NullPtrException
 typedef void Test()
 Test test;
 test();