From: fennecdjay Date: Thu, 30 Jun 2022 21:38:57 +0000 (+0200) Subject: :bug: Update DotTmpl X-Git-Tag: nightly~264^2~121 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=7144382384c220cce857060d1bcd066db2490cc1;p=gwion.git :bug: Update DotTmpl --- diff --git a/include/instr.h b/include/instr.h index 2b42da0c..8a7466bd 100644 --- a/include/instr.h +++ b/include/instr.h @@ -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); diff --git a/src/emit/emit.c b/src/emit/emit.c index a322288f..4c321da6 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -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; diff --git a/src/lib/closure.c b/src/lib/closure.c index 3f32d10f..8e0428c9 100644 --- a/src/lib/closure.c +++ b/src/lib/closure.c @@ -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; } diff --git a/src/lib/instr.c b/src/lib/instr.c index f827d101..05438217 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -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)) diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 336d3984..912cad74 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -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); diff --git a/tests/fptr/fptr_cast.gw b/tests/fptr/fptr_cast.gw index a79971cf..0dfc8213 100644 --- a/tests/fptr/fptr_cast.gw +++ b/tests/fptr/fptr_cast.gw @@ -1,3 +1,3 @@ \ a { return 2; }(2); (\ a { return 2; } $ (int(int))); -#!\ a { return 2; }(3); +\ a { return 2; }(3);