]> Nishi Git Mirror - gwion.git/commitdiff
Revert ":art: Improve emit and VM"
authorfennecdjay <astor.jeremie@wanadoo.fr>
Thu, 16 May 2019 13:40:01 +0000 (15:40 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Thu, 16 May 2019 13:40:01 +0000 (15:40 +0200)
This reverts commit b10dab2e00a6920c5aa32d1d8a54445f21b417eb.

12 files changed:
include/opcode.h
include/vm.h
opcode.txt
src/emit/emit.c
src/parse/check.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/type_decl.c
src/vm/shreduler.c
src/vm/vm.c
src/vm/vm_shred.c

index f1d678fc25161a493a156fa20e68f1b98b9c0616..aa3061430e533e26b59ef5e1d647a54a41d72568 100644 (file)
@@ -152,6 +152,7 @@ enum {
   eRegAddRef,
   eObjectAssign,
   eObjectRelease,
+  eGWOP_EXCEPTBASE,
   eGWOP_EXCEPT,
   eAllocMember4,
   eDotMember,
@@ -325,6 +326,7 @@ enum {
 #define  RegAddRef           (f_instr)eRegAddRef
 #define  ObjectAssign        (f_instr)eObjectAssign
 #define  ObjectRelease       (f_instr)eObjectRelease
+#define  GWOP_EXCEPTBASE     (f_instr)eGWOP_EXCEPTBASE
 #define  GWOP_EXCEPT         (f_instr)eGWOP_EXCEPT
 #define  AllocMember4        (f_instr)eAllocMember4
 #define  DotMember           (f_instr)eDotMember
index 3c10ea91e28d48d35b8caf61619d5aa418eede30..393439a3bc25eabdba452ee1a08d002d5b81a5a4 100644 (file)
@@ -34,7 +34,6 @@ struct ShredInfo_ {
   m_str name;
   Vector args;
   MemPool mp;
-  VM_Code orig;
 };
 
 struct ShredTick_ {
index 88498ce7b2e9ea94e3e2a09deecc0ad93fce53b0..b090ee1fa0ed8a56d9a60cf867663a8cbcc55e1a 100644 (file)
@@ -149,6 +149,7 @@ ObjectInstantiate
 RegAddRef
 ObjectAssign
 ObjectRelease
+GWOP_EXCEPTBASE
 GWOP_EXCEPT
 AllocMember4
 DotMember
index 2e085c5e2458d878e3efb1f5a57fbe16a2fc5bb1..6f6e3e191948b172bccc6bbf37adbc1a07c5ffbd 100644 (file)
@@ -390,11 +390,10 @@ ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array* array) {
   const m_uint is_var = exp_self(array)->emit_var;
   const m_uint depth = get_depth(array->base->type) - exp_self(array)->type->array_depth;
   CHECK_BB(emit_exp(emit, array->base, 0))
-  emit_add_instr(emit, GcAdd);
   CHECK_BB(emit_exp(emit, array->array->exp, 0))
   const Instr pop = emit_add_instr(emit, RegPop);
   pop->m_val = depth * SZ_INT;
-  emit_add_instr(emit, GWOP_EXCEPT);
+  emit_add_instr(emit, GWOP_EXCEPTBASE);
   for(m_uint i = 0; i < depth - 1; ++i) {
     const Instr access = emit_add_instr(emit, ArrayAccess);
     access->m_val = i;
@@ -613,9 +612,14 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_de
 
 ANN static m_bool emit_class_def(const Emitter, const Class_Def);
 
-ANN static inline m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) {
+ANN static m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) {
   const Type t = typedef_base(decl->type);
-  return !GET_FLAG(t, emit) ? emit_class_def(emit, t->e->def) : GW_OK;
+  if(!GET_FLAG(t, emit)) {
+    CHECK_BB(template_push_types(emit->env, t->e->def->tmpl->list.list, t->e->def->tmpl->base))
+    CHECK_BB(emit_class_def(emit, t->e->def))
+    emit_pop_type(emit);
+  }
+  return GW_OK;
 }
 
 ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) {
@@ -828,8 +832,9 @@ ANN static Instr emit_call(const Emitter emit, const Func f) {
       instr->m_val = (instr->m_val2 = i) + member;
       ++prelude->m_val2;
     }
-  }
-  exec = Overflow;
+    exec = Overflow;
+  } else
+    exec = Next;
   if(memoize)
     memoize->m_val = prelude->m_val2 + 1;
   return emit_add_instr(emit, exec);
@@ -1392,7 +1397,7 @@ ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) {
         (m_bit*)xcalloc(1, stmt->value->type->nspc->info->class_data_size);
     stmt->value->type->nspc->info->offset = stmt->s;
     Type_Decl *type_decl = new_type_decl(emit->gwion->mp,
-        new_id_list(emit->gwion->mp, stmt->xid, loc_cpy(emit->gwion->mp, stmt_self(stmt)->pos)),
+        new_id_list(emit->gwion->mp, stmt->xid, loc_cpy(emit->gwion->mp, loc_cpy(emit->gwion->mp, stmt_self(stmt)->pos))),
 //        emit->env->class_def ? ae_flag_member : 0);
         stmt->flag);
 //if(emit->env->class_def && !GET_FLAG(stmt, static))
@@ -1433,8 +1438,8 @@ ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) {
     SET_FLAG(stmt->l->self->d.exp_decl.list->self->value, enum);
   }
   if(stmt->xid){
-    const Instr instr = emit_add_instr(emit, RegPop);
-    instr->m_val = !GET_FLAG(stmt, static) ? SZ_INT : SZ_INT*2;
+      const Instr instr = emit_add_instr(emit, RegPop);
+      instr->m_val = !GET_FLAG(stmt, static) ? SZ_INT : SZ_INT*2;
   }
   emit_union_offset(stmt->l, stmt->o);
   if(stmt->xid || stmt->type_xid || global)
index 509c6659513774ef4455ed7bdea4702d807285fd..2e88c71a2d9795c6a843527c72c403461ea97aa9 100644 (file)
@@ -110,8 +110,7 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) {
       ERR_O(td_pos(decl->td), "can't infer type.");
   if(GET_FLAG(decl->type , template)) {
     const Type t = typedef_base(decl->type);
-    if(!GET_FLAG(t, check))
-      CHECK_BO(traverse_template(env, t->e->def))
+    CHECK_BO(traverse_template(env, t->e->def))
   }
   const m_bool global = GET_FLAG(decl->td, global);
   const m_uint scope = !global ? env->scope->depth : env_push_global(env);
@@ -413,7 +412,6 @@ ANN static Func _find_template_match(const Env env, const Value v, const Exp_Cal
   const Exp args = exp->args;
   const Type_List types = exp->tmpl->types;
   Func m_func = exp->m_func, former = env->func;
-if(types->td->types)exit(12);
   const m_str tmpl_name = tl2str(env, types);
   const m_uint sz = vector_size((Vector)env->curr->info->type);
   const m_uint scope = env_push(env, v->owner_class, v->owner);
@@ -1166,11 +1164,11 @@ ANN static m_bool check_class_parent(const Env env, const Class_Def class_def) {
     const Type t = class_def->base.type->e->parent->array_depth ?
       array_base(class_def->base.type->e->parent) : class_def->base.type->e->parent;
     if(!GET_FLAG(t, checked)) {
-//      if(class_def->tmpl)
-//        CHECK_BB(template_push_types(env, class_def->tmpl->list.list, class_def->tmpl->base))
+      if(class_def->tmpl)
+        CHECK_BB(template_push_types(env, class_def->tmpl->list.list, class_def->tmpl->base))
       CHECK_BB(traverse_template(env, t->e->def))
-//      if(class_def->tmpl)
-//        nspc_pop_type(env->gwion->mp, env->curr);
+      if(class_def->tmpl)
+        nspc_pop_type(env->gwion->mp, env->curr);
     }
   }
   if(!GET_FLAG(class_def->base.type->e->parent, checked))
@@ -1199,7 +1197,7 @@ ANN static inline void inherit(const Type t) {
 ANN m_bool check_class_def(const Env env, const Class_Def class_def) {
   if(tmpl_class_base(class_def->tmpl))
     return GW_OK;
-   if(class_def->base.type->e->parent == t_undefined) {
+  if(class_def->base.type->e->parent == t_undefined) {
     class_def->base.type->e->parent = check_td(env, class_def->base.ext);
     return traverse_class_def(env, class_def);
   }
index e46ea601e1f67ebd98ec1c3e246e8c8a7e7eff8d..561577d605a0cddc4a3d730f60b9f996d53585e8 100644 (file)
@@ -62,14 +62,6 @@ ANN m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt) {
     const ae_flag flag = base->e->def ? base->e->def->flag : 0;
     const Class_Def cdef = new_class_def(env->gwion->mp, flag, stmt->xid, stmt->ext, NULL,
       loc_cpy(env->gwion->mp, td_pos(stmt->ext)));
-//const Type parent = known_type(env, stmt->ext);
-//if(!parent->array_depth && !GET_FLAG(parent, builtin) && !GET_FLAG(parent, scan0)) {
-//puts(parent->name);
-//exit(9);
-//}
-//printf("%p\n", stmt->ext->types);exit(6);
-//if(stmt->ext->types)
-//  cdef->tmpl = new_tmpl_class(, $2, -1);
     CHECK_BB(scan0_class_def(env, cdef))
     stmt->type = cdef->base.type;
   }
@@ -103,7 +95,6 @@ ANN m_bool scan0_stmt_enum(const Env env, const Stmt_Enum stmt) {
 ANN static Type union_type(const Env env, const Nspc nspc, const Symbol s, const m_bool add) {
   const m_str name = s_name(s);
   const Type t = type_copy(env->gwion->mp, t_union);
-//t->e->parent = t_union;
   t->xid = ++env->scope->type_xid;
   t->name = name;
   t->nspc = new_nspc(env->gwion->mp, name);
@@ -241,7 +232,6 @@ ANN m_bool scan0_class_def(const Env env, const Class_Def cdef) {
   (void)mk_class(env, cdef->base.type);
   if(GET_FLAG(cdef, global))
     env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
-  SET_FLAG(cdef->base.type, scan0);
   return GW_OK;
 }
 
index bd325a0b757a1d6052210d5ee3c4d39ccae4e7b2..3804d27e03e4680c421e5f8794c0210bd3e7d05a 100644 (file)
@@ -9,7 +9,6 @@
 #include "vm.h"
 #include "parse.h"
 #include "traverse.h"
-#include "template.h"
 
 ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list);
 ANN static m_bool scan1_stmt(const Env env, Stmt stmt);
@@ -44,7 +43,7 @@ ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) {
   decl->base = t->e->def;
   return decl->type = t;
 }
-//#include "loc.h"
+
 ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
   CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos))
   Var_Decl_List list = decl->list;
index 24be16a17b8ded5f32d57eed43985058eb1d63d0..58a5b55759896870c3d3d027e7a276c15ec83731 100644 (file)
@@ -543,9 +543,8 @@ DECL_SECTION_FUNC(scan2)
 ANN static m_bool scan2_class_parent(const Env env, const Class_Def cdef) {
   const Type t = cdef->base.type->e->parent->array_depth ?
     array_base(cdef->base.type->e->parent) : cdef->base.type->e->parent;
-  if(!GET_FLAG(t, scan2) && GET_FLAG(cdef->base.ext, typedef)) {
+  if(!GET_FLAG(t, scan2) && GET_FLAG(cdef->base.ext, typedef))
     CHECK_BB(scan2_class_def(env, t->e->def))
-  }
   if(cdef->base.ext->array)
     CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp))
   return GW_OK;
index b320346d4e12e081e2fc9ac2a37c060acc4a0e5a..4b37f0abc98c8cbf218d883b5b5b14ad489db5fe 100644 (file)
@@ -18,41 +18,57 @@ ANN Type type_decl_resolve(const Env env, const Type_Decl* td) {
 
 struct td_info {
   Type_List tl;
-  GwText text;
+  m_str str;
+  size_t len;
+  size_t cap;
 };
 
+ANN static inline m_bool td_add(struct td_info* info, const char c) {
+  return *(info->str + info->len++ - 1) = c;
+}
+
+ANN static inline void td_check(struct td_info* info, const size_t len) {
+  if(info->len + len >= info->cap) {
+    while(info->len + len >= info->cap)
+      info->cap <<= 1;
+    info->str = (m_str)xrealloc(info->str, info->cap);
+  }
+}
+
 ANEW ANN static m_str td2str(const Env env, const Type_Decl* td);
 ANN static void td_info_run(const Env env, struct td_info* info) {
   Type_List tl = info->tl;
   do {
     m_str name = td2str(env, tl->td);
-    text_add(&info->text, name);
+    const size_t nlen = strlen(name);
+    td_check(info, nlen + !!tl->next);
+    strcpy(info->str + info->len -1, name);
+    info->len += nlen;
     xfree(name);
-    if(tl->next)
-      text_add(&info->text, ",");
-  } while((tl = tl->next));
+  } while((tl = tl->next) && td_add(info, ','));
 }
 
 ANEW ANN static m_str td2str(const Env env, const Type_Decl* td) {
   m_uint depth = td->array ? td->array->depth : 0;
-  const size_t len = id_list_len(td->xid)  + depth * 2;
-  const size_t cap = round2szint(len);
-  struct td_info info = { td->types, { (m_str)xmalloc(cap), cap, len }};
-  type_path(info.text.str, td->xid);
-  while(depth--) { text_add(&info.text, "[]"); }
+  const size_t l = id_list_len(td->xid)  + depth * 2;
+  struct td_info info = { td->types, (m_str)xmalloc(l), l, l };
+  type_path(info.str, td->xid);
+  while(depth--) { td_add(&info, '['); td_add(&info, ']'); }
   Type_List tl = td->types;
   if(tl) {
-    text_add(&info.text, "<");
+    td_check(&info, 2);
+    td_add(&info, '<');
     td_info_run(env, &info);
-    text_add(&info.text, ">");
+    td_add(&info, '>');
   }
-  return info.text.str;
+  info.str[info.len - 1] = '\0';
+  return info.str;
 }
 
 ANEW ANN m_str tl2str(const Env env, Type_List tl) {
-  struct td_info info = { .tl=tl };
+  struct td_info info = { tl, (m_str)xmalloc(32), 1, 32 };
   td_info_run(env, &info);
-  return info.text.str;
+  return info.str;
 }
 
 ANN static inline void* type_unknown(const Env env, const ID_List id) {
index a3b0c5b798489bfcdc0adcdf6fa358e61cd1d5e5..674aa4a8c8e98c29f2af16f2e8bd7fbc6524b390 100644 (file)
@@ -6,6 +6,9 @@
 #include "object.h"
 #include "driver.h"
 #include "shreduler_private.h"
+#include "env.h" // unwind
+#include "gwion.h" // unwind
+#include "instr.h" // unwind
 
 ANN void shreduler_set_loop(const Shreduler s, const m_bool loop) {
   s->loop = loop > 0;
@@ -38,6 +41,22 @@ ANN static void shreduler_parent(const VM_Shred out, const Vector v) {
   }
 }
 
+ANN static void unwind(const VM_Shred shred) {
+  VM_Code code = shred->code;
+  while(code) {
+    if(shred->mem <= (((m_bit*)(shred) + sizeof(struct VM_Shred_) + SIZEOF_REG)))
+      break;
+    const m_bit exec = (m_bit)((Instr)vector_back(code->instr))->opcode;
+    if(exec == eFuncReturn) {
+      code = *(VM_Code*)(shred->mem - SZ_INT*3);
+      if(!GET_FLAG(code, op))
+        REM_REF(code, shred->info->vm->gwion)
+      shred->mem -= *(m_uint*)(shred->mem - SZ_INT*4) + SZ_INT*4;
+    } else break;
+  }
+  shred->code = code;
+}
+
 ANN static inline void shreduler_child(const Vector v) {
   for(m_uint i = vector_size(v) + 1; --i;) {
     const VM_Shred child = (VM_Shred)vector_at(v, i - 1);
@@ -46,6 +65,7 @@ ANN static inline void shreduler_child(const Vector v) {
 }
 
 ANN static void shreduler_erase(const Shreduler s, struct ShredTick_ *tk) {
+  unwind(tk->self);
   if(tk->parent)
     shreduler_parent(tk->self, &tk->parent->child);
   if(tk->child.ptr)
index f329d5109eafb775897c566e76aefc67f0c964da..8c42a61ba7046cb0d64c8d9912ee80a63f53b4dc 100644 (file)
@@ -277,7 +277,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, &&assign, &&remref,
-    &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr,
+    &&exceptbase, &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr,
     &&staticint, &&staticfloat, &&staticother,
     &&dotfunc, &&dotstaticfunc, &&staticcode, &&pushstr,
     &&gcini, &&gcadd, &&gcend,
@@ -297,6 +297,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto]
       VM_Code code;
       VM_Shred child;
     } a;
+    register M_Object array_base = NULL;
   MUTEX_LOCK(s->mutex);
   do {
     register Instr instr; DISPATCH();
@@ -586,9 +587,12 @@ regtomem:
   *(m_uint*)(mem+instr->m_val) = *(m_uint*)(reg+instr->m_val2);
   DISPATCH()
 overflow:
-  if(overflow_(mem + SZ_INT*8, shred)) {
-    exception(shred, "StackOverflow");
-    continue;
+  if(overflow_((shred->mem = mem), shred)) {
+PRAGMA_PUSH()
+//    shred->code = a.code;
+  shred->mem = mem;
+PRAGMA_POP()
+    Except(shred, "StackOverflow");
   }
 next:
 PRAGMA_PUSH()
@@ -670,6 +674,8 @@ arrayaccess:
 {
   const m_int idx = *(m_int*)(reg + SZ_INT * instr->m_val);
   if(idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(a.obj))) {
+// should we go to except ? so we can remove release array_base
+    _release(array_base, shred);
     gw_err("\t... at index [%" INT_F "]\n", idx);
     gw_err("\t... at dimension [%" INT_F "]\n", instr->m_val);
     shred->code = code;
@@ -686,7 +692,7 @@ arrayaddr:
   *(m_bit**)(reg + (m_int)instr->m_val2) = m_vector_addr(ARRAY(a.obj), *(m_int*)(reg + SZ_INT * instr->m_val));
   DISPATCH()
 arrayvalid:
-  vector_pop(&shred->gc);
+  array_base = NULL;
   goto regpush;
 newobj:
   *(M_Object*)reg = new_object(vm->gwion->mp, shred, (Type)instr->m_val2);
@@ -710,8 +716,13 @@ assign:
 remref:
   release(*(M_Object*)(mem + instr->m_val), shred);
   DISPATCH()
+exceptbase:
+  array_base = *(M_Object*)(reg-SZ_INT);
 except:
   if(!(a.obj  = *(M_Object*)(reg-SZ_INT))) {
+    if(array_base) _release(array_base, shred);
+//    shred->code = code;
+    shred->mem = mem;
     exception(shred, "NullPtrException");
     continue;
   }
index aa35302f478dac01944879e40efb8830df00b4ee..a67ec2b7de8b228e8076cbf720267761a3614311 100644 (file)
@@ -39,7 +39,6 @@ VM_Shred new_vm_shred(MemPool p, VM_Code c) {
   shred->reg           = (m_bit*)shred + sizeof(struct VM_Shred_);
   shred->base = shred->mem = shred->reg + SIZEOF_REG;
   shred->info = new_shredinfo(p, c->name);
-  shred->info->orig = c;
   vector_init(&shred->gc);
   return shred;
 }
@@ -48,7 +47,7 @@ void free_vm_shred(VM_Shred shred) {
   for(m_uint i = vector_size(&shred->gc) + 1; --i;)
     release((M_Object)vector_at(&shred->gc, i - 1), shred);
   vector_release(&shred->gc);
-  REM_REF(shred->info->orig, shred->info->vm->gwion);
+  REM_REF(shred->code, shred->info->vm->gwion);
   MemPool mp = shred->info->mp;
   mp_free(mp, ShredTick, shred->tick);
   free_shredinfo(mp, shred->info);