]> Nishi Git Mirror - gwion.git/commitdiff
:art: Prepare emit
authorfennecdjay <astor.jeremie@wanadoo.fr>
Sun, 22 Sep 2019 18:56:24 +0000 (20:56 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Sun, 22 Sep 2019 18:56:24 +0000 (20:56 +0200)
include/emit.h
src/compile.c
src/emit/emit.c
src/emit/emitter.c
src/emit/escape.c
src/emit/memoize.c
src/gwion.c
src/lib/instr.c

index 57b406e7c8864ea14b18fc353d4bfb53a3e95609..e08bc23a0e413b7bd20d5ffcf561777d804a4568 100644 (file)
@@ -15,21 +15,28 @@ typedef struct Code_ {
   ae_flag flag;
 } Code;
 
+struct EmitterInfo_ {
+  struct Vector_ pure;
+  struct Vector_ variadic;
+  char *escape;
+  f_instr finalyzer;
+  VM_Code (*emit_code)(const Emitter);
+  VM_Code code;
+  m_bool memoize;
+};
+
 struct Emitter_ {
   Env    env;
   Code*  code;
   struct Gwion_ *gwion;
-  struct Vector_  stack;
-  struct Vector_ pure;
-  struct Vector_  variadic;
-  char *escape;
-  m_bool memoize;
+  struct EmitterInfo_ *info;
+  struct Vector_ stack;
 };
 
 ANEW ANN Emitter new_emitter(MemPool);
 ANN void free_emitter(MemPool, Emitter);
 ANEW ANN VM_Code emit_code(const Emitter);
-ANN VM_Code emit_ast(const Emitter emit, Ast ast);
+ANN m_bool emit_ast(const Env env, Ast ast);
 ANN Instr emit_exp_call1(const Emitter, const Func);
 ANN2(1) Instr emit_add_instr(const Emitter, const f_instr) __attribute__((returns_nonnull));
 ANN Code* emit_class_code(const Emitter, const m_str);
index 679ee3990f545399630bdfb0b5a4b69eff3cd13b..fd8ad67fe08f666205a7372cef3e3d802bcdd07c 100644 (file)
@@ -80,33 +80,42 @@ static inline m_bool compiler_open(MemPool p, struct Compiler* c) {
   return GW_OK;
 }
 
-static m_bool check(struct Gwion_* gwion, struct Compiler* c) {
+static inline m_bool _check(struct Gwion_* gwion, struct Compiler* c) {
   struct ScannerArg_ arg = { c->name, c->file, gwion->st };
-  MUTEX_LOCK(gwion->data->mutex);
   CHECK_OB((c->ast = parse(&arg)))
   gwion->env->name = c->name;
-  const m_bool ret = type_engine_check_prog(gwion->env, c->ast);
+  return type_engine_check_prog(gwion->env, c->ast);
+}
+/*
+static m_bool check(struct Gwion_* gwion, struct Compiler* c) {
+  MUTEX_LOCK(gwion->data->mutex);
+  const m_bool ret = _check(gwion, c);
   MUTEX_UNLOCK(gwion->data->mutex);
   return ret;
 }
+*/
+static m_uint _compile(struct Gwion_* gwion, struct Compiler* c) {
+  CHECK_BB(compiler_open(gwion->mp, c))
+  if(_check(gwion, c) < 0 || emit_ast(gwion->env, c->ast) < 0) {
+    gw_err(_("while compiling file '%s'\n"), c->base);
+    return 0;
+  }
+  const VM_Shred shred = new_vm_shred(gwion->mp, gwion->emit->info->code);
+  shred->info->args = c->args;
+  vm_add_shred(gwion->vm, shred);
+  gwion->emit->info->code = NULL;
+  return shred->tick->xid;
+}
 
 static m_uint compile(struct Gwion_* gwion, struct Compiler* c) {
-  VM_Shred shred = NULL;
-  VM_Code code;
   compiler_name(gwion->mp, c);
   MUTEX_LOCK(gwion->data->mutex);
-  CHECK_BB(compiler_open(gwion->mp, c))
-  if(check(gwion, c) < 0 || !(code = emit_ast(gwion->emit, c->ast)))
-    gw_err(_("while compiling file '%s'\n"), c->base);
-  else {
-    const VM_Shred shred = new_vm_shred(gwion->mp, code);
-    shred->info->args = c->args;
-    vm_add_shred(gwion->vm, shred);
-  }
+  const m_uint ret = _compile(gwion, c);
   MUTEX_UNLOCK(gwion->data->mutex);
   compiler_clean(gwion->mp, c);
-  return shred ? shred->tick->xid : 0;
+  return ret;
 }
+
 /*
 m_bool check_filename(struct Gwion_* vm, const m_str filename) {
   struct Compiler c = { .base=filename, .type=COMPILE_NAME };
@@ -131,12 +140,13 @@ m_uint compile_filename(struct Gwion_* gwion, const m_str filename) {
   struct Compiler c = { .base=filename, .type=COMPILE_NAME };
   return compile(gwion, &c);
 }
-/*
+
 m_uint compile_string(struct Gwion_* vm, const m_str filename, const m_str data) {
   struct Compiler c = { .base=filename, .type=COMPILE_MSTR, .data=data };
   return compile(vm, &c);
 }
 
+/*
 m_uint compile_file(struct Gwion_* vm, const m_str filename, FILE* file) {
   struct Compiler c = { .base=filename, .type=COMPILE_MSTR, .file=file };
   return compile(vm, &c);
index c7eadfec797af051ace61fa4201b560d3bd7c28b..6c126c6ffeab39685b7f1407ad65d1a7b8b6ed03 100644 (file)
@@ -125,7 +125,7 @@ ANN static void emit_pop_scope(const Emitter emit) {
     Instr instr = emit_add_instr(emit, ObjectRelease);
     instr->m_val = (m_uint)offset;
   }
-  vector_pop(&emit->pure);
+  vector_pop(&emit->info->pure);
 }
 
 ANN static inline void emit_push_code(const Emitter emit, const m_str name) {
@@ -133,13 +133,9 @@ ANN static inline void emit_push_code(const Emitter emit, const m_str name) {
   emit->code = new_code(emit, name);
 }
 
-ANN static inline void emit_pop_code(const Emitter emit)   {
-  emit->code = (Code*)vector_pop(&emit->stack);
-}
-
 ANN static inline void emit_push_scope(const Emitter emit) {
   frame_push(emit->code->frame);
-  vector_add(&emit->pure, 0);
+  vector_add(&emit->info->pure, 0);
 }
 
 ANN static inline m_uint emit_code_size(const Emitter emit) {
@@ -235,7 +231,7 @@ ANN m_bool emit_array_extend(const Emitter emit, const Type t, const Exp e) {
 }
 
 ANN static inline void emit_notpure(const Emitter emit) {
-  ++VPTR(&emit->pure, VLEN(&emit->pure) - 1);
+  ++VPTR(&emit->info->pure, VLEN(&emit->info->pure) - 1);
 }
 
 ANN static Array_Sub instantiate_typedef(MemPool p, const m_uint depth) {
@@ -374,10 +370,10 @@ ANEW ANN VM_Code emit_code(const Emitter emit) {
   return code;
 }
 
-ANN static VM_Code finalyze(const Emitter emit) {
-  emit_add_instr(emit, EOC);
+ANN static VM_Code finalyze(const Emitter emit, const f_instr exec) {
+  emit_add_instr(emit, exec);
   const VM_Code code = emit_code(emit);
-  emit_pop_code(emit);
+  emit->code = (Code*)vector_pop(&emit->stack);
   return code;
 }
 
@@ -945,7 +941,7 @@ ANN static void emit_args(const Emitter emit, const Func f) {
 }
 
 ANN static Instr emit_call(const Emitter emit, const Func f) {
-  const Instr memoize = !(emit->memoize && GET_FLAG(f, pure)) ? NULL : emit_add_instr(emit, MemoizeCall);
+  const Instr memoize = !(emit->info->memoize && GET_FLAG(f, pure)) ? NULL : emit_add_instr(emit, MemoizeCall);
   const Instr prelude = get_prelude(emit, f);
   prelude->m_val = f->def->stack_depth;
   const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
@@ -1026,7 +1022,7 @@ static inline void stack_alloc_this(const Emitter emit) {
 static m_bool scoped_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) {
   ++emit->env->scope->depth;
   emit_push_scope(emit);
-  const m_bool pure = !vector_back(&emit->pure);
+  const m_bool pure = !vector_back(&emit->info->pure);
   if(!pure)
     emit_add_instr(emit, GcIni);
   CHECK_BB(emit_stmt(emit, stmt, pop))
@@ -1068,7 +1064,7 @@ ANN Instr emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
     push_spork_code(emit, is_spork ? SPORK_FUNC_PREFIX : FORK_CODE_PREFIX, unary->exp->pos);
     CHECK_BO(spork_func(emit, &unary->exp->d.exp_call))
   }
-  const VM_Code code = finalyze(emit);
+  const VM_Code code = finalyze(emit, EOC);
   const Instr ini = emit_add_instr(emit, unary->op == insert_symbol("spork") ? SporkIni : ForkIni);
   ini->m_val = (m_uint)code;
   ini->m_val2 = is_spork;
@@ -1604,11 +1600,11 @@ ANN static m_bool emit_vararg_start(const Emitter emit, const m_uint offset) {
   const Instr instr = emit_add_instr(emit, VarargTop);
   instr->m_val = offset;
   instr->m_val2 = emit_code_size(emit);
-  vector_set(&emit->variadic, vector_size(&emit->variadic) -1, (vtype)instr);
+  vector_set(&emit->info->variadic, vector_size(&emit->info->variadic) -1, (vtype)instr);
   return GW_OK;
 }
 ANN static inline Instr get_variadic(const Emitter emit) {
-  return (Instr)vector_back(&emit->variadic);
+  return (Instr)vector_back(&emit->info->variadic);
 }
 
 ANN static void emit_vararg_end(const Emitter emit, const m_uint offset) {
@@ -1745,19 +1741,12 @@ ANN static void emit_func_def_return(const Emitter emit) {
   }
   vector_clear(&emit->code->stack_return);
   emit_pop_scope(emit);
-  if(emit->memoize && GET_FLAG(emit->env->func, pure))
+  if(emit->info->memoize && GET_FLAG(emit->env->func, pure))
     emit_add_instr(emit, MemoizeStore);
-  emit_add_instr(emit, FuncReturn);
 }
 
 ANN static void emit_func_def_code(const Emitter emit, const Func func) {
-  if(GET_FLAG(func->def, dtor)) {
-    Instr instr = (Instr)vector_back(&emit->code->instr);
-    instr->opcode = eOP_MAX;
-    instr->execute = DTOR_EOC;
-    instr->m_val = (m_uint)emit->gwion->mp;
-  }
-  func->code = emit_code(emit);
+  func->code = finalyze(emit, !GET_FLAG(func->def, dtor) ? FuncReturn : DTOR_EOC);
   if(GET_FLAG(func->def, dtor)) {
     emit->env->class_def->nspc->dtor = func->code;
     ADD_REF(func->code)
@@ -1776,7 +1765,7 @@ ANN static m_bool _fdef_body(const Emitter emit, const Func_Def fdef) {
 }
 
 ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) {
-  vector_add(&emit->variadic, 0);
+  vector_add(&emit->info->variadic, 0);
   CHECK_BB(_fdef_body(emit, fdef))
   if(GET_FLAG(fdef, variadic)) {
     if(!get_variadic(emit))
@@ -1819,11 +1808,10 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def fdef) {
   emit_func_def_code(emit, func);
   if(fdef->base->tmpl)
     emit_pop_type(emit);
-  emit_pop_code(emit);
   emit->env->func = former;
   if(!emit->env->class_def && !GET_FLAG(fdef, global) && !fdef->base->tmpl)
     emit_func_def_global(emit, func->value_ref);
-  if(emit->memoize && GET_FLAG(func, pure))
+  if(emit->info->memoize && GET_FLAG(func, pure))
     func->code->memoize = memoize_ini(emit, func,
       kindof(func->def->base->ret_type->size, !func->def->base->ret_type->size));
   return GW_OK;
@@ -1841,12 +1829,6 @@ ANN Code* emit_class_code(const Emitter emit, const m_str name) {
   return emit->code;
 }
 
-ANN inline void emit_class_finish(const Emitter emit, const Nspc nspc) {
-  emit_add_instr(emit, FuncReturn);
-  nspc->pre_ctor = emit_code(emit);
-  SET_FLAG(nspc->pre_ctor, ctor);
-}
-
 ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) {
   const Type parent = cdef->base.type->e->parent;
   const Type base = parent->e->d.base_type;
@@ -1860,6 +1842,11 @@ ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) {
       (_exp_func)emit_class_def, (_exp_func)emit_union_def);
 }
 
+ANN void emit_class_finish(const Emitter emit, const Nspc nspc) {
+  nspc->pre_ctor = finalyze(emit, FuncReturn);
+  SET_FLAG(nspc->pre_ctor, ctor);
+}
+
 ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
   if(tmpl_base(cdef->base.tmpl))
     return GW_OK;
@@ -1874,13 +1861,12 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
     CHECK_BB(emit_array_extend(emit, type->e->parent, cdef->base.ext->array->exp))
   if(cdef->body)
     CHECK_BB(scanx_body(emit->env, cdef, (_exp_func)emit_section, emit))
-  emit_class_finish(emit, nspc);
-  emit_pop_code(emit);
+  emit_class_finish(emit, type->nspc);
   SET_FLAG(type, emit);
   return GW_OK;
 }
 
-ANN static void emit_free_code(const Emitter emit, Code* code) {
+ANN static inline void emit_free_code(const Emitter emit, Code* code) {
   if(vector_size(&code->instr))
     free_code_instr(&code->instr, emit->gwion);
   free_code(emit->gwion->mp, code);
@@ -1891,7 +1877,7 @@ ANN static VM_Code emit_free_stack(const Emitter emit) {
   for(m_uint i = vector_size(&emit->stack) + 1; --i;)
     emit_free_code(emit, (Code*)vector_at(&emit->stack, i - 1));
   vector_clear(&emit->stack);
-  vector_clear(&emit->pure);
+  vector_clear(&emit->info->pure);
   emit_free_code(emit, emit->code);
   return NULL;
 }
@@ -1902,10 +1888,15 @@ ANN static inline m_bool emit_ast_inner(const Emitter emit, Ast ast) {
   return GW_OK;
 }
 
-ANN VM_Code emit_ast(const Emitter emit, Ast ast) {
+ANN m_bool emit_ast(const Env env, Ast ast) {
+  const Emitter emit = env->gwion->emit;
   emit->code = new_code(emit, emit->env->name);
   emit_push_scope(emit);
   const m_bool ret = emit_ast_inner(emit, ast);
   emit_pop_scope(emit);
-  return ret > 0 ? finalyze(emit) : emit_free_stack(emit);
+  if(ret > 0)
+    emit->info->code = finalyze(emit, emit->info->finalyzer);
+  else
+    emit_free_stack(emit);
+  return ret;
 }
index 3ac80be7ab863a037f6c630c3f78019e18acb5b5..71c8df69b60a49806f4fc186e4e001490b695b8f 100644 (file)
 ANEW Emitter new_emitter(MemPool p) {
   Emitter emit = (Emitter)mp_calloc(p, Emitter);
   vector_init(&emit->stack);
-  vector_init(&emit->pure);
-  vector_init(&emit->variadic);
-  emit->escape = escape_table(p);
+  emit->info = (struct EmitterInfo_*)mp_calloc(p, EmitterInfo);
+  vector_init(&emit->info->pure);
+  vector_init(&emit->info->variadic);
+  emit->info->escape = escape_table(p);
+  emit->info->finalyzer = EOC;
   return emit;
 }
 
 ANN void free_emitter(MemPool p, Emitter a) {
   vector_release(&a->stack);
-  vector_release(&a->pure);
-  vector_release(&a->variadic);
-  mp_free2(p, 256, a->escape);
+  vector_release(&a->info->pure);
+  vector_release(&a->info->variadic);
+  mp_free2(p, 256, a->info->escape);
+  mp_free(p, EmitterInfo, a->info);
   mp_free(p, Emitter, a);
 }
 
index b9d492114ae88d0aae39e8b50c3eccb3c61046fe..c5493c09f9c05e89660f2ac20a2d798d2e5e9f7c 100644 (file)
@@ -24,8 +24,8 @@ char* escape_table(MemPool p) {
 }
 
 static int get_escape(const Emitter emit, const char c, const loc_t pos) {
-  if(emit->escape[(int)c])
-    return emit->escape[(int)c];
+  if(emit->info->escape[(int)c])
+    return emit->info->escape[(int)c];
   env_err(emit->env, pos, _("unrecognized escape sequence '\\%c'"), c);
   return GW_ERROR;
 }
index 538af2b012727996b3815dede261df715d59ad43..4e80f2b090289b33499468221948c96051d0caba 100644 (file)
@@ -56,7 +56,7 @@ Memoize memoize_ini(const Emitter emit, const Func f, const enum Kind kind) {
     m->member = SZ_INT;
     m->arg_sz = f->def->stack_depth - SZ_INT;
   }
-  m->limit = emit->memoize;
+  m->limit = emit->info->memoize;
   m->p = new_pool((uint32_t)(m->arg_sz + m->ret_sz));
   return m;
 }
index 50798b0795914f7bbb248a3598a72ffd27af9d71..c28493a6fe57380c1171de701b8b6f3158ed8d07 100644 (file)
@@ -71,7 +71,7 @@ ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) {
   gwion->vm->bbq->si = new_soundinfo(gwion->mp);
   arg->si = gwion->vm->bbq->si;
   arg_parse(arg);
-  gwion->emit->memoize = arg->memoize;
+  gwion->emit->info->memoize = arg->memoize;
   gwion->plug = new_plug(gwion->mp, &arg->lib);
   gwion->data = new_gwiondata(gwion->mp);
   shreduler_set_loop(gwion->vm->shreduler, arg->loop);
index 0da50fc57453ccfddcd41937d58f32fa7a715888..7c922cab3af27f044737c8abe61e3421c21c3f13 100644 (file)
@@ -53,6 +53,12 @@ ANN static Func_Def from_base(const Env env, struct dottmpl_ *const dt, const Ns
   return def;
 }
 
+ANN static Func_Def traverse_tmpl(const Emitter emit, struct dottmpl_ *const dt, const Nspc nspc) {
+  DECL_OO(const Func_Def, def, = from_base(emit->env, dt, nspc))
+  CHECK_BO(traverse_dot_tmpl(emit, dt))
+  return def;
+}
+
 INSTR(GTmpl) {
   struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val;
   const Func f = *(Func*)REG(-SZ_INT);
@@ -73,13 +79,10 @@ INSTR(GTmpl) {
   }
   free_mstr(emit->gwion->mp, tmpl_name);
   dt->def = f->def;
-  const Func_Def def = from_base(emit->env, dt, f->value_ref->owner);
+  const Func_Def def = traverse_tmpl(emit, dt, f->value_ref->owner);
   if(!def)
     Except(shred, "MissigTmplPtrException[internal]");
-  if(traverse_dot_tmpl(emit, dt) > 0)
-    *(VM_Code*)(shred->reg -SZ_INT) = def->base->func->code;
-  else
-    Except(shred, "TemplateException");
+  *(VM_Code*)(shred->reg -SZ_INT) = def->base->func->code;
 }
 
 INSTR(DotTmpl) {
@@ -101,14 +104,12 @@ INSTR(DotTmpl) {
       shred->reg += SZ_INT;
       return;
     } else {
-      const Func_Def def = from_base(emit->env, dt, t->nspc);
+      const Func_Def def = traverse_tmpl(emit, dt, t->nspc);
       if(!def)
         continue;
-      if(traverse_dot_tmpl(emit, dt) > 0) {
-        *(VM_Code*)shred->reg = def->base->func->code;
-        shred->reg += SZ_INT;
-        return;
-      } else break;
+      *(VM_Code*)shred->reg = def->base->func->code;
+      shred->reg += SZ_INT;
+      return;
     }
   } while((t = t->e->parent));
   Except(shred, "MissigTmplException[internal]"); //unreachable