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
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;
#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 {
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;
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
}
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;
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,
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));
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;
}
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;
}