]> Nishi Git Mirror - gwion.git/commitdiff
:bug: Update DotTmpl
authorfennecdjay <fennecdjay@gmail.com>
Thu, 30 Jun 2022 21:38:57 +0000 (23:38 +0200)
committerfennecdjay <fennecdjay@gmail.com>
Thu, 30 Jun 2022 21:38:57 +0000 (23:38 +0200)
include/instr.h
src/emit/emit.c
src/lib/closure.c
src/lib/instr.c
src/lib/object_op.c
tests/fptr/fptr_cast.gw

index 2b42da0c28ad453d361971257ee62f049a99ce7d..8a7466bdfe580ffa9fdafa7c99a1a945bbce06ef 100644 (file)
@@ -59,9 +59,9 @@ INSTR(DotTmpl);
 INSTR(GTmpl);
 
 struct dottmpl_ {
-  m_str     name;
-  Func_Def  base, def;
-  Type_List tl;
+  Nspc  nspc;
+  Type  type;
+  m_str tmpl_name;
 };
 ANN m_bool traverse_dot_tmpl(const Emitter emit, const Func_Def fdef, const Value v);
 
index a322288ffa70dc504b6024defaa1cd1b504c5588..4c321da6638309ce04fdb52ce39b3fef00c146df 100644 (file)
@@ -1436,13 +1436,6 @@ static inline m_bool push_func_code(const Emitter emit, const Func f) {
     return GW_OK;
   }
   const Instr instr = (Instr)vector_back(&emit->code->instr);
-  if (instr->opcode == eDotTmplVal) {
-    instr->opcode  = eOP_MAX;
-    instr->m_val   = (m_uint)f->def;
-    instr->m_val2  = (m_uint)tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->pos);
-    instr->execute = DotTmpl;
-    return GW_OK;
-  }
   instr->opcode = eRegPushImm;
   instr->m_val  = (m_uint)f->code;
   return GW_OK;
@@ -1616,9 +1609,7 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f,
   else if (unlikely(!f->code && emit->env->func != f)) {
     if (tmpl) CHECK_BB(emit_template_code(emit, f));
     else CHECK_BB(emit_ensure_func(emit, f));
-  } else if(!f->value_ref->from->owner_class ||
-       GET_FLAG(f->value_ref->from->owner_class, final) ||
-       GET_FLAG(f, static) || tmpl)
+  } else if(is_static)
     push_func_code(emit, f);
   call_finish(emit, f, is_static);
   emit->status = status;
index 3f32d10fd8ac5ceb56824cb9787474f4e74c9e5c..8e0428c9a1cec2f6ec663f921f0fd1030cc56cd8 100644 (file)
@@ -659,8 +659,12 @@ static OP_CHECK(opck_class_partial) {
    return op_check(env, &opi);
 }
 
+static FREEARG(freearg_gtmpl) {
+  free_mstr(((Gwion)gwion)->mp, (m_str)instr->m_val2);
+}
 static FREEARG(freearg_dottmpl) {
-  if (instr->m_val2) free_mstr(((Gwion)gwion)->mp, (m_str)instr->m_val2);
+  struct dottmpl_ *dt = (struct dottmpl_*) instr->m_val2;
+  free_mstr(((Gwion)gwion)->mp, dt->tmpl_name);
 }
 
 #include "tmpl_info.h"
@@ -777,7 +781,7 @@ GWION_IMPORT(func) {
   GWI_BB(gwi_oper_add(gwi, opck_class_partial))
   GWI_BB(gwi_oper_end(gwi, "@partial", NULL))
 
+  gwi_register_freearg(gwi, GTmpl, freearg_gtmpl);
   gwi_register_freearg(gwi, DotTmpl, freearg_dottmpl);
-  gwi_register_freearg(gwi, GTmpl, freearg_dottmpl);
   return GW_OK;
 }
index f827d10151f1f9ef03ab196fc2954fe9925a1dca..05438217796bddbc497c1144fe80f7906e822b7b 100644 (file)
@@ -10,6 +10,8 @@
 #include "operator.h"
 #include "import.h"
 #include "emit.h"
+#include "traverse.h"
+#include "parse.h"
 
 ANN static Func_Def traverse_tmpl(const Emitter emit, Func_Def fdef, Func_Def fbase,
                               const Nspc nspc) {
@@ -37,7 +39,7 @@ ANN static void foo(const VM_Shred shred, Type t, const Func_Def fbase, const m_
     const Symbol sym  = func_symbol(emit->env, t->name, base->name, tmpl_name, base->def->vt_index);
     const Func f = nspc_lookup_func0(t->nspc, sym);
     if (f) {
-      if(!f->code) exit(15); //continue;
+      if(!f->code) continue;
       if (vflag(f->value_ref, vflag_member)) shred->reg += SZ_INT;
       *(VM_Code *)(shred->reg - SZ_INT) = f->code;
       return;
@@ -90,7 +92,7 @@ INSTR(GTmpl) {
       const Symbol sym  = func_symbol(emit->env, t->name, f->name, tmpl, f->def->vt_index);
       const Func f = nspc_lookup_func0(t->nspc, sym);
       if (f) {
-        if (!f->code) exit(15); //continue;
+        if (!f->code) continue;
         *(VM_Code *)(shred->reg - SZ_INT) = f->code;
         return;
       } else {
@@ -106,9 +108,24 @@ INSTR(GTmpl) {
 
 INSTR(DotTmpl) {
   const Func_Def fbase = (Func_Def)instr->m_val;
-  const m_str tmpl = (m_str)instr->m_val2;
-  const M_Object   o    = *(M_Object *)REG(-SZ_INT); // orig
-  foo(shred, o->type_ref, fbase, tmpl);
+  const M_Object   o    = *(M_Object *)REG(-SZ_INT);
+  const Func f = fbase->base->func;
+  if(o->type_ref == f->value_ref->from->owner_class) {
+    if (vflag(f->value_ref, vflag_member)) shred->reg += SZ_INT;
+    *(VM_Code *)(shred->reg - SZ_INT) = f->code;
+    return;
+  }
+  const Emitter emit = shred->info->vm->gwion->emit;
+  const struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val2;
+  struct EnvSet es    = {.env   = emit->env,
+                         .data  = emit,
+//                         .func  = (_exp_func)emit_cdef,
+                         .func  = (_exp_func)dummy_func,
+                         .scope = 0,
+                         .flag  = tflag_emit};
+  if(envset_push(&es, dt->type, dt->nspc) < 0) return;
+  foo(shred, o->type_ref, fbase, dt->tmpl_name);
+  if (es.run) envset_pop(&es, dt->type);
 }
 
 #define VAL  (*(m_uint *)(byte + SZ_INT))
index 336d39845e6697742a39384a5a5c0b18946e506c..912cad74ad8c58aa1ff17d8e1ed2483ca1f04600 100644 (file)
@@ -96,6 +96,16 @@ ANN static void emit_dot_static_import_data(const Emitter emit, const Value v,
     emit_dot_static_data(emit, v, emit_addr);
 }
 
+ANN static void emit_dottmpl(const Emitter emit, const Func f) {
+  const Instr instr = emit_add_instr(emit, DotTmpl);
+  instr->m_val = (m_uint)f->def;
+  struct dottmpl_ *dt = mp_malloc(emit->gwion->mp, dottmpl);
+  dt->nspc = emit->env->curr;
+  dt->type = emit->env->class_def;
+  dt->tmpl_name = tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->pos);
+  instr->m_val2 = (m_uint)dt;
+}
+
 ANN static void emit_member_func(const Emitter emit, const Exp_Dot *member) {
   const Func f = exp_self(member)->type->info->func;
 
@@ -107,7 +117,7 @@ ANN static void emit_member_func(const Emitter emit, const Exp_Dot *member) {
     return;
   }
   if (f->def->base->tmpl) {
-    if(member->is_call) emit_add_instr(emit, DotTmplVal);
+    if(member->is_call) emit_dottmpl(emit, f);
     else {
       if(vflag(f->value_ref, vflag_member)) {
         const Instr instr = emit_add_instr(emit, RegMove);
index a79971cfa4c544085abfafd68112652816896323..0dfc82130e375cbb1541d5f0f8e42c355567405e 100644 (file)
@@ -1,3 +1,3 @@
 \ a { return 2; }(2);
 (\ a { return 2; } $ (int(int)));
-#!\ a { return 2; }(3);
+\ a { return 2; }(3);