From: fennecdjay Date: Sat, 16 Feb 2019 10:56:03 +0000 (+0100) Subject: :art: FIx member template X-Git-Tag: nightly~2761^2~32 X-Git-Url: http://10.11.0.4:5575/?a=commitdiff_plain;h=67466d752bb3c23b272d6065b26201733860b257;p=gwion.git :art: FIx member template --- diff --git a/include/instr.h b/include/instr.h index e13236f8..555b20f4 100644 --- a/include/instr.h +++ b/include/instr.h @@ -69,9 +69,19 @@ INSTR(PopArrayClass); INSTR(AutoLoopStart); INSTR(AutoLoopEnd); INSTR(DotTmpl); + +struct dottmpl_ { + size_t len; + m_str name; + Func_Def base; + size_t overload; // => vtindex ? + Type_List tl; +}; +ANN void free_dottmpl(struct dottmpl_*); +#endif + // optimizations #ifdef OPTIMIZE INSTR(PutArgsInMem); -#endif #include "opcode.h" #endif diff --git a/src/emit/emit.c b/src/emit/emit.c index b5856660..7641e77b 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -690,7 +690,11 @@ assert(_instr->execute == DotTmpl); char c[sz + 1]; strncpy(c, f->name, sz); c[sz] = '\0'; - _instr->m_val = (m_uint)s_name(insert_symbol(c)); + struct dottmpl_ *dt = mp_alloc(dottmpl); + dt->name = s_name(insert_symbol(c)); + dt->overload = f->def->tmpl->base; + dt->base = f->def; + _instr->m_val = (m_uint)dt; _instr->m_val2 = strlen(c); *(m_int*)_instr->ptr = f->def->tmpl->base; return GW_OK; diff --git a/src/lib/instr.c b/src/lib/instr.c index 78214c67..04f70ac0 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -109,7 +109,8 @@ INSTR(PopArrayClass) { GWDEBUG_EXE #include "value.h" #include "template.h" INSTR(DotTmpl) { - const m_str name = (m_str)instr->m_val; + const struct dottmpl_ * dt = (struct dottmpl_*)instr->m_val; + const m_str name = dt->name; const M_Object o = *(M_Object*)REG(-SZ_INT); Type t = o->type_ref; do { @@ -130,19 +131,17 @@ strcpy(c, start + 1); c[strlen(start) - strlen(end) - 2] = '\0'; m_uint depth; const Type_List tl = str2tl(emit->env, c, &depth); -assert(v); -assert(v->d.func_ref->def = f->def); -env_push_type(emit->env, v->owner_class); -if(template_push_types(emit->env, f->def->tmpl->list, tl) > 0) -// if(traverse_func_def(emit->env, f->value_ref->d.func_ref->def) > 0) - if(traverse_func_def(emit->env, f->def) > 0) -emit_func_def(emit, f->def); -assert(f->code); -assert(f->code = f->def->func->code); -nspc_pop_type(emit->env->curr); -env_pop(emit->env, 0); -free_type_list(tl); -f->def->func->code->stack_depth -= SZ_INT; + m_uint scope = env_push_type(emit->env, v->owner_class); + m_bool ret = GW_ERROR; + if(traverse_func_template(emit->env, f->def, tl) > 0) { + ret = emit_func_def(emit, f->def); + nspc_pop_type(emit->env->curr); + }//} + env_pop(emit->env, scope); + free_type_list(tl); + if(ret < 0) + continue; + } *(VM_Code*)shred->reg = f->code; shred->reg += SZ_INT; @@ -156,31 +155,30 @@ m_str end = strchr(name, '<'); char c[instr->m_val2]; strcpy(c, start); c[strlen(start) - strlen(end)] = '\0'; -const Symbol sym = func_symbol(o->type_ref->name, c, "template", -*(m_uint*)instr->ptr); +const Symbol sym = func_symbol(o->type_ref->name, c, "template", dt->overload); const Value v = nspc_lookup_value1(o->type_ref->nspc, sym); + if(!v) + continue; const Func_Def base = v->d.func_ref->def; const Func_Def def = new_func_def(base->td, insert_symbol(v->name), base->arg_list, base->d.code, base->flag); - def->tmpl = new_tmpl_list(base->tmpl->list, *(m_int*)instr->ptr); + def->tmpl = new_tmpl_list(base->tmpl->list, dt->overload); SET_FLAG(def, template); - Type_List tl = tmpl_tl(emit->env, name); - env_push_type(emit->env, v->owner_class); - if(template_push_types(emit->env, def->tmpl->list, tl) > 0) - if(traverse_func_def(emit->env, def) > 0) { - emit_func_def(emit, def); - nspc_pop_type(emit->env->curr); - } -env_pop(emit->env, 0); -def->func->code->stack_depth -= SZ_INT; - *(VM_Code*)shred->reg = def->func->code; - shred->reg += SZ_INT; - return; - - - -} + Type_List tl = tmpl_tl(emit->env, name); + m_uint scope = env_push_type(emit->env, v->owner_class); + m_bool ret = GW_ERROR; + if(traverse_func_template(emit->env, def, tl) > 0) { + ret = emit_func_def(emit, def); + nspc_pop_type(emit->env->curr); + } + env_pop(emit->env, scope); + free_type_list(tl); + if(ret > 0) { + *(VM_Code*)shred->reg = def->func->code; + shred->reg += SZ_INT; + return; + } + } } while((t = t->parent)); -// should not be reached - Except(shred, "MissigTmplException[internal]"); + Except(shred, "MissigTmplException[internal]"); //unreachable } diff --git a/src/parse/check.c b/src/parse/check.c index 0a369292..fc809229 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -434,22 +434,20 @@ end: return m_func; } ANN Func find_template_match(const Env env, const Value value, const Exp_Call* exp) { -// Value v = value; Type t = value->owner_class; const Func f = _find_template_match(env, value, exp); if(f) return f; while(t) { -//assert(t->nspc); - const Value v = nspc_lookup_value1(t->nspc, value->d.func_ref->def->name); -if(!v)goto next; - const Func f = _find_template_match(env, v, exp); - if(f) - return f; -next: -t = t->parent; -} - + Value v = nspc_lookup_value1(t->nspc, value->d.func_ref->def->name); + if(!v) + goto next; + const Func f = _find_template_match(env, v, exp); + if(f) + return f; + next: + t = t->parent; + } assert(exp->self); err_msg(exp->self->pos, "arguments do not match for template call"); return NULL; @@ -976,7 +974,9 @@ ANN static m_bool check_signature_match(const Func_Def f, const Func parent) { G c_name, f_name, p_name, c_name, GET_FLAG(f, static) ? c_name : p_name, f_name) } - return isa(f->ret_type, parent->def->ret_type); + if(!f->tmpl) // ??? + return isa(f->ret_type, parent->def->ret_type); + return GW_OK; } ANN static m_bool parent_match_actual(const Env env, const restrict Func_Def f, @@ -985,8 +985,10 @@ ANN static m_bool parent_match_actual(const Env env, const restrict Func_Def f, do { if(compat_func(f, parent_func->def) > 0) { CHECK_BB(check_signature_match(f, parent_func)) - f->func->vt_index = parent_func->vt_index; - vector_set(&env->curr->vtable, f->func->vt_index, (vtype)f->func); + if(!f->tmpl) { + f->func->vt_index = parent_func->vt_index; + vector_set(&env->curr->vtable, f->func->vt_index, (vtype)f->func); + } return GW_OK; } } while((parent_func = parent_func->next)); diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 46489700..05753c15 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -342,7 +342,7 @@ ANN2(1,2) static Value func_value(const Env env, const Func f, if(!overload) { ADD_REF(v); nspc_add_value(env->curr, f->def->name, v); - } else if(!GET_FLAG(f->def, template)) { + } else /* if(!GET_FLAG(f->def, template)) */ { f->next = overload->d.func_ref->next; overload->d.func_ref->next = f; } @@ -355,12 +355,43 @@ ANN2(1, 2) static m_bool scan2_func_def_template(const Env env, const Func_Def f const Value value = func_value(env, func, overload); SET_FLAG(value, checked | ae_flag_template); SET_FLAG(value->type, func); // the only types with func flag, name could be better - const Symbol sym = func_symbol(env->curr->name, func_name, "template", overload ? ++overload->offset : 0); + Type type = env->class_def; + Nspc nspc = env->curr; + uint i = 0; + do { + const Value v = nspc_lookup_value1(nspc, f->name); + if(v) { + Func ff = v->d.func_ref; + do { + if(ff->def == f) { + ++i; + continue; + } + m_bool ret = compat_func(ff->def, f); + if(ret > 0) { + const Symbol sym = func_symbol(env->curr->name, func_name, + "template", ff->vt_index); + nspc_add_value(env->curr, sym, value); + if(!overload) { + ADD_REF(value) + nspc_add_value(env->curr, f->name, value); + } + func->vt_index = ff->vt_index; + return GW_OK; + } + } while((ff = ff->next) && ++i); + } + } while(type && (type = type->parent) && (nspc = type->nspc)); + --i; + const Symbol sym = func_symbol(env->curr->name, func_name, "template", i); nspc_add_value(env->curr, sym, value); -if(!overload) { - ADD_REF(value) - nspc_add_value(env->curr, f->name, value); -} + nspc_add_value(env->curr, sym, value); + if(!overload) { + func->vt_index = i; + ADD_REF(value) + nspc_add_value(env->curr, f->name, value); + } else + func->vt_index = ++overload->offset; return GW_OK; }