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);
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;
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;
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"
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;
}
#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) {
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;
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 {
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))
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;
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);
\ a { return 2; }(2);
(\ a { return 2; } $ (int(int)));
-#!\ a { return 2; }(3);
+\ a { return 2; }(3);