]> Nishi Git Mirror - gwion.git/commitdiff
:art: VM improvments
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Thu, 10 Sep 2020 16:24:06 +0000 (18:24 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Thu, 10 Sep 2020 16:24:06 +0000 (18:24 +0200)
include/emit.h
include/opcode.h
opcode.txt
src/emit/emit.c
src/lib/array.c
src/vm/vm.c

index df5602257c877821b126e7f1d4fce9350f28afe3..d7c2fc7dec131640cd35ad14a98e60c1614ed507 100644 (file)
@@ -47,6 +47,7 @@ ANN m_uint emit_local(const Emitter emit, const Type t);
 ANN Instr emit_exp_spork(const Emitter, const Exp_Unary*);
 ANN m_bool emit_exp(const Emitter, const Exp);
 ANN static inline void emit_except(const Emitter emit, const Type t) {
-  emit_add_instr(emit, !GET_FLAG(t, nonnull) ? GWOP_EXCEPT : SetObj);
+  if(!GET_FLAG(t, nonnull))
+    emit_add_instr(emit, GWOP_EXCEPT);
 }
 #endif
index 8a9327fccc0a1169870ca3a1f50df17d0e437664..a7ed4a7418746dd33ef8c0ec8c80099fd4bb6649 100644 (file)
@@ -156,7 +156,6 @@ enum {
   eObjectAssign,
   eAssign,
   eObjectRelease,
-  eSetObj,
   eGWOP_EXCEPT,
   eAllocMember4,
   eDotMember,
@@ -335,7 +334,6 @@ enum {
 #define  ObjectAssign        (f_instr)eObjectAssign
 #define  Assign              (f_instr)eAssign
 #define  ObjectRelease       (f_instr)eObjectRelease
-#define  SetObj              (f_instr)eSetObj
 #define  GWOP_EXCEPT         (f_instr)eGWOP_EXCEPT
 #define  AllocMember4        (f_instr)eAllocMember4
 #define  DotMember           (f_instr)eDotMember
index ff33a87690481ec58621433b0b3c07968b98c203..2ae78cc84e4cf64fcf5253c28245baeb36972a4a 100644 (file)
@@ -153,7 +153,6 @@ RegAddRefAddr
 ObjectAssign
 Assign
 ObjectRelease
-SetObj
 GWOP_EXCEPT
 AllocMember4
 DotMember
index 1169192acb7b58dcc8902d5ec1c804bc1e742c63..67614f56ddbafeddcac467878bc7309283c5214d 100644 (file)
@@ -1097,8 +1097,9 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
     m_bit exec = back->opcode;
     m_uint val = back->m_val;
     m_uint val2 = back->m_val2;
-    back->opcode = eRegPushMem;
-    back->m_val = back->m_val2 = 0;
+    back->opcode = eReg2Reg;
+    back->m_val2 = -SZ_INT;
+    regpush(emit, SZ_INT);
     const Instr instr = emit_add_instr(emit, (f_instr)(m_uint)exec);
     instr->m_val = val;
     instr->m_val2 = val2;
@@ -1214,6 +1215,15 @@ ANN void spork_code(const Emitter emit, const struct Sporker *sp) {
 ANN void spork_func(const Emitter emit, const struct Sporker *sp) {
   const Func f = sp->exp->d.exp_call.m_func;
   if(GET_FLAG(f, member) && is_fptr(emit->gwion, f->value_ref->type)) {
+    regpush(emit, SZ_INT*2);
+    // (re-)emit owner
+    if(sp->exp->d.exp_call.func->exp_type == ae_exp_dot)
+      emit_exp(emit, sp->exp->d.exp_call.func->d.exp_dot.base);
+    else {
+      assert(sp->exp->d.exp_call.func->exp_type == ae_exp_primary);
+      emit_add_instr(emit, RegPushMem);
+    }
+    regpop(emit, SZ_INT*3);
     const m_uint depth = f->def->stack_depth;
     regpop(emit, depth -SZ_INT);
     const Instr spork = emit_add_instr(emit, SporkMemberFptr);
@@ -1470,7 +1480,6 @@ ANN static m_bool emit_stmt_flow(const Emitter emit, const Stmt_Flow stmt) {
 ANN static m_bool variadic_state(const Emitter emit, const Stmt_VarLoop stmt, const m_uint status) {
   regpushi(emit, status);
   CHECK_BB(emit_exp(emit, stmt->exp))
-  emit_add_instr(emit, SetObj);
   const Instr member = emit_add_instr(emit, DotMember4);
   member->m_val = SZ_INT;
   emit_add_instr(emit, int_r_assign);
index 340463361394f3fc2b2bae0244d437188b4d8914..b61fb477f735e507b39889f97e120dd776bcb286 100644 (file)
@@ -272,22 +272,23 @@ ANN static void array_loop(const Emitter emit, const m_uint depth) {
   emit_add_instr(emit, GWOP_EXCEPT);
   for(m_uint i = 0; i < depth - 1; ++i) {
     const Instr access = emit_add_instr(emit, ArrayAccess);
-    access->m_val = i;
+    access->m_val = i * SZ_INT;
+    access->m_val2 = !i ? SZ_INT : 0;
     const Instr get = emit_add_instr(emit, ArrayGet);
-    get->m_val = i;
+    get->m_val = i * SZ_INT;
     get->m_val2 = -SZ_INT;
     emit_add_instr(emit, GWOP_EXCEPT);
   }
   const Instr post_pop = emit_add_instr(emit, RegPop);
   post_pop->m_val = SZ_INT;
   const Instr access = emit_add_instr(emit, ArrayAccess);
-  access->m_val = depth;
+  access->m_val = depth * SZ_INT;
 }
 
 ANN static void array_finish(const Emitter emit, const m_uint depth,
                const m_uint size, const m_bool is_var) {
   const Instr get = emit_add_instr(emit, is_var ? ArrayAddr : ArrayGet);
-  get->m_val = depth;
+  get->m_val = depth * SZ_INT;
   const Instr push = emit_add_instr(emit, ArrayValid);
   push->m_val = is_var ? SZ_INT : size;
 }
index aab88f5a2d8b3cedf1bb9dad3667696a65866f03..3e4d34903c60ca5dcd992f45ffad0ff1c28940a9 100644 (file)
@@ -325,7 +325,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto]
     &&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat,
     &&arrayappend, &&autoloop, &&autoloopptr, &&autoloopcount, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&arrayvalid,
     &&newobj, &&addref, &&addrefaddr, &&objassign, &&assign, &&remref,
-    &&setobj, &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr,
+    &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr,
     &&staticint, &&staticfloat, &&staticother,
     &&dotfunc, &&dotstaticfunc,
     &&gcini, &&gcadd, &&gcend,
@@ -680,9 +680,9 @@ PRAGMA_PUSH()
   DISPATCH()
 PRAGMA_POP()
 sporkmemberfptr:
-  for(m_uint i = 0; i < VAL; i+= SZ_INT)
+  for(m_uint i = SZ_INT; i < VAL; i+= SZ_INT)
     *(m_uint*)(child->reg + i) = *(m_uint*)(reg - VAL + i);
-  *(M_Object*)(child->reg + VAL) = a.obj;
+  *(M_Object*)(child->reg + VAL) = *(M_Object*)(reg + VAL + SZ_INT);
   *(m_uint*)(child->reg + VAL + SZ_INT) = *(m_uint*)(reg + VAL - SZ_INT*2);
   child->reg += VAL + SZ_INT*2;
   DISPATCH()
@@ -727,7 +727,8 @@ arraytop:
     goto _goto;
 arrayaccess:
 {
-  register const m_int idx = *(m_int*)(reg + SZ_INT * VAL);
+  register const m_int idx = *(m_int*)(reg + VAL);
+  a.obj = *(M_Object*)(reg-VAL2);
   if(idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(a.obj))) {
     gw_err(_("  ... at index [%" INT_F "]\n"), idx);
     gw_err(_("  ... at dimension [%" INT_F "]\n"), VAL);
@@ -738,10 +739,10 @@ arrayaccess:
   DISPATCH()
 }
 arrayget:
-  m_vector_get(ARRAY(a.obj), *(m_int*)(reg + SZ_INT * VAL), (reg + (m_int)VAL2));
+  m_vector_get(ARRAY(a.obj), *(m_int*)(reg + VAL), (reg + (m_int)VAL2));
   DISPATCH()
 arrayaddr:
-  *(m_bit**)(reg + (m_int)VAL2) = m_vector_addr(ARRAY(a.obj), *(m_int*)(reg + SZ_INT * VAL));
+  *(m_bit**)(reg + (m_int)VAL2) = m_vector_addr(ARRAY(a.obj), *(m_int*)(reg + VAL));
   DISPATCH()
 arrayvalid:
 // are we sure it is the array ?
@@ -753,20 +754,27 @@ newobj:
   reg += SZ_INT;
   DISPATCH()
 addref:
-  a.obj = *((M_Object*)(reg+(m_int)VAL) + (m_int)VAL2);
-  goto addrefcommon;
+  {
+    const M_Object o = *((M_Object*)(reg+(m_int)VAL) + (m_int)VAL2);
+    if(o)
+      ++o->ref;
+  }
+  DISPATCH()
 addrefaddr:
-  a.obj = *(*(M_Object**)(reg+(m_int)VAL) + (m_int)VAL2);
-addrefcommon:
-  if(a.obj)
-    ++a.obj->ref;
+  {
+    const M_Object o = *(*(M_Object**)(reg+(m_int)VAL) + (m_int)VAL2);
+    if(o)
+      ++o->ref;
+  }
   DISPATCH()
 objassign:
-  a.obj = **(M_Object**)(reg -SZ_INT);
-  if(a.obj) {
-    --a.obj->ref;
-    _release(a.obj, shred);
+{
+  const M_Object o = **(M_Object**)(reg -SZ_INT);
+  if(o) {
+    --o->ref;
+    _release(o, shred);
   }
+}
 assign:
   reg -= SZ_INT;
   **(M_Object**)reg = *(M_Object*)(reg-SZ_INT);
@@ -774,43 +782,39 @@ assign:
 remref:
   release(*(M_Object*)(mem + VAL), shred);
   DISPATCH()
-setobj:
-  a.obj  = *(M_Object*)(reg-SZ_INT-(m_int)VAL);
-  DISPATCH();
 except:
 /* TODO: Refactor except instruction             *
  * so that                                       *
  *  VAL = offset (no default SZ_INT)             *
  *  VAL2 = error message                         *
  * grep for GWOP_EXCEPT and Except, exception... */
-  if(!(a.obj  = *(M_Object*)(reg-SZ_INT-VAL))) {
+  if(!*(M_Object*)(reg-SZ_INT-VAL)) {
     shred->pc = PC;
     exception(shred, "NullPtrException");
     continue;
   }
   DISPATCH();
 allocmemberaddr:
-  a.obj = *(M_Object*)mem;
-  *(m_bit**)reg = a.obj->data + VAL;
+  *(m_bit**)reg = (*(M_Object*)mem)->data + VAL;
   reg += SZ_INT;
   DISPATCH()
 dotmember:
-  *(m_uint*)(reg-SZ_INT) = *(m_uint*)(a.obj->data + VAL);
+  *(m_uint*)(reg-SZ_INT) = *(m_uint*)((*(M_Object*)(reg-SZ_INT))->data + VAL);
   DISPATCH()
 dotfloat:
-  *(m_float*)(reg-SZ_INT) = *(m_float*)(a.obj->data + VAL);
+  *(m_float*)(reg-SZ_INT) = *(m_float*)((*(M_Object*)(reg-SZ_INT))->data + VAL);
   reg += SZ_FLOAT - SZ_INT;
   DISPATCH()
 dotother:
 //  LOOP_OPTIM
 PRAGMA_PUSH()
   for(m_uint i = 0; i <= VAL2; i += SZ_INT)
-    *(m_uint*)(reg+i-SZ_INT) = *(m_uint*)((a.obj->data + VAL) + i);
+    *(m_uint*)(reg+i-SZ_INT) = *(m_uint*)(((*(M_Object*)(reg-SZ_INT))->data + VAL) + i);
 PRAGMA_POP()
   reg += VAL2 - SZ_INT;
   DISPATCH()
 dotaddr:
-  *(m_bit**)(reg-SZ_INT) = (a.obj->data + VAL);
+  *(m_bit**)(reg-SZ_INT) = ((*(M_Object*)(reg-SZ_INT))->data + VAL);
   DISPATCH()
 staticint:
   *(m_uint*)reg = *(m_uint*)VAL;
@@ -828,11 +832,11 @@ staticother:
   reg += VAL2;
   DISPATCH()
 dotfunc:
-  assert(a.obj);
   reg += SZ_INT;
+  VAL2 = SZ_INT;
 dotstaticfunc:
 PRAGMA_PUSH()
-  *(VM_Code*)(reg-SZ_INT) = ((Func)vector_at(a.obj->vtable, VAL))->code;
+  *(VM_Code*)(reg-SZ_INT) = ((Func)vector_at((*(M_Object*)(reg-SZ_INT-VAL2))->vtable, VAL))->code;
 PRAGMA_POP()
   DISPATCH()
 gcini:
@@ -842,16 +846,19 @@ gcadd:
   vector_add(&shred->gc, *(vtype*)(reg-SZ_INT));
   DISPATCH();
 gcend:
-  while((a.obj = (M_Object)vector_pop(&shred->gc)))
-    _release(a.obj, shred);
+{
+  M_Object o;
+  while((o = (M_Object)vector_pop(&shred->gc)))
+    _release(o, shred);
+}
   DISPATCH()
 gacktype:
 {
   const M_Object o = *(M_Object*)(reg - SZ_INT);
   if(o)
     *(Type*)reg = o->type_ref;
-  DISPATCH()
 }
+  DISPATCH()
 gackend:
 {
   m_str str = *(m_str*)(reg - SZ_INT);