From: fennecdjay Date: Sun, 16 Jun 2019 21:07:17 +0000 (+0200) Subject: :art: Improve memory model X-Git-Tag: nightly~2442^2~1 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=4af0d393fafd2180dbeab9abd06c53427cf7320d;p=gwion.git :art: Improve memory model --- diff --git a/include/operator.h b/include/operator.h index 533db1af..1e8b13b3 100644 --- a/include/operator.h +++ b/include/operator.h @@ -1,6 +1,9 @@ #ifndef __OPERATOR #define __OPERATOR #define OP_ANY_TYPE (Type)1 + +#define ERR_N(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return t_null; } + typedef Type (*opck)(const Env, void*); typedef m_bool (*opem)(const Emitter, void*); diff --git a/include/parse.h b/include/parse.h index 0eee6771..d9bf6c54 100644 --- a/include/parse.h +++ b/include/parse.h @@ -6,10 +6,9 @@ #undef ERR_B #define ERR_B(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return GW_ERROR; } + #undef ERR_O #define ERR_O(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return NULL; } -#undef ERR_N -#define ERR_N(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return t_null; } #define RET_NSPC(exp) \ ++env->scope->depth; \ diff --git a/src/emit/emit.c b/src/emit/emit.c index 8a556196..4ae60771 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -495,8 +495,6 @@ ANN static m_bool prim_gack(const Emitter emit, const Exp_Primary* primary) { do { vector_add(v, (vtype)e->type); offset += e->type->size; - if(e->type != emit->env->class_def) - ADD_REF(e->type); } while((e = e->next)); if(emit_exp(emit, exp, 0) < 0) { free_vector(emit->gwion->mp, v); @@ -570,8 +568,6 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Var_Decl va const Instr assign = emit_add_instr(emit, Assign); assign->m_val = emit_var; const size_t missing_depth = type->array_depth - (array ? array->depth : 0); - if((is_array || missing_depth) && !emit->env->scope->depth) - ADD_REF(type) if(missing_depth) { const Instr push = emit_add_instr(emit, Reg2Reg); push->m_val = -(1 + missing_depth) * SZ_INT; @@ -600,8 +596,6 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_de if(is_obj && (is_array || !is_ref)) { const Instr assign = emit_add_instr(emit, Assign); assign->m_val = emit_var; - if(is_array && !emit->env->scope->depth) - ADD_REF(type) if(isa(type, t_fork) < 0) { // beware fork const Instr instr = emit_add_instr(emit, RegAddRef); instr->m_val = emit_var; @@ -702,9 +696,10 @@ ANN static m_bool emit_exp_call_template(const Emitter emit, const Exp_Call* exp exp_call->m_func->def->base->tmpl->call = exp_call->tmpl->call; DECL_BB(const m_int,scope, = push_tmpl_func(emit, exp_call->m_func)) CHECK_BB(prepare_call(emit, exp_call)) - if(!is_fptr(exp_call->m_func->value_ref->type)) + if(!is_fptr(exp_call->m_func->value_ref->type)) { emit_pop_type(emit); - emit_pop(emit, (m_uint)scope); + emit_pop(emit, (m_uint)scope); + } UNSET_FLAG(exp_call->m_func, checked); return GW_OK; } @@ -762,9 +757,9 @@ ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) { emit_push_type(emit, dt->owner_class) : emit_push(emit, NULL, dt->owner); m_bool ret = GW_ERROR; dt->def->base->tmpl->call = dt->tl;// in INSTR - if(!dt->def->base->func &&traverse_func_template(emit->env, dt->def) > 0) { + if(!dt->def->base->func && traverse_func_template(emit->env, dt->def) > 0) { ret = emit_func_def(emit, dt->def); - nspc_pop_type(emit->gwion->mp, emit->env->curr); + emit_pop_type(emit); } emit_pop(emit, scope); return ret; @@ -1707,7 +1702,7 @@ ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) { ANN static m_bool tmpl_rettype(const Emitter emit, const Func_Def fdef) { CHECK_BB(template_push_types(emit->env, fdef->base->tmpl)) const m_bool ret = emit_parent_inner(emit, fdef->base->ret_type->e->def); - nspc_pop_type(emit->gwion->mp, emit->env->curr); + emit_pop_type(emit); return ret; } diff --git a/src/lib/array.c b/src/lib/array.c index 5ff9e614..7fe5036e 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -64,7 +64,6 @@ static DTOR(array_dtor) { for(m_uint i = 0; i < ARRAY_LEN(a); ++i) release(*(M_Object*)(ARRAY_PTR(a) + i * SZ_INT), shred); free_m_vector(shred->info->mp, a); - REM_REF(t, shred->info->vm->gwion) } ANN M_Object new_array(MemPool p, const Type t, const m_uint length) { @@ -72,7 +71,6 @@ ANN M_Object new_array(MemPool p, const Type t, const m_uint length) { const m_uint depth = t->array_depth; const m_uint size = depth > 1 ? SZ_INT : array_base(t)->size; ARRAY(a) = new_m_vector2(p, size,length); - ADD_REF(t); return a; } @@ -198,7 +196,6 @@ static OP_CHECK(opck_array_cast) { static FREEARG(freearg_array) { ArrayInfo* info = (ArrayInfo*)instr->m_val; - REM_REF((Type)vector_back(&info->type), gwion); vector_release(&info->type); mp_free(((Gwion)gwion)->mp, ArrayInfo, info); } diff --git a/src/lib/engine.c b/src/lib/engine.c index 1ba8fe2c..3e89351a 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -31,10 +31,7 @@ static FREEARG(freearg_switchbranch) { } static FREEARG(freearg_gack) { - const Vector v = (Vector)instr->m_val2; - for(m_uint i = vector_size(v) + 1; --i;) - REM_REF(((Type)vector_at(v, i - 1)), gwion); - free_vector(((Gwion)gwion)->mp, v); + free_vector(((Gwion)gwion)->mp, (Vector)instr->m_val2); } ANN static m_bool import_core_libs(const Gwi gwi) { diff --git a/src/lib/func.c b/src/lib/func.c index 85a103f7..d93ce1db 100644 --- a/src/lib/func.c +++ b/src/lib/func.c @@ -66,6 +66,7 @@ struct FptrInfo { ANN static m_bool fptr_tmpl_push(const Env env, struct FptrInfo *info) { if(!info->rhs->def->base->tmpl) return GW_OK; +// some kind of template_match ? ID_List t0 = info->lhs->def->base->tmpl->list, t1 = info->rhs->def->base->tmpl->list; while(t0) { @@ -74,8 +75,7 @@ ANN static m_bool fptr_tmpl_push(const Env env, struct FptrInfo *info) { t1 = t1->next; } CHECK_BB(template_push_types(env, info->lhs->def->base->tmpl)) - CHECK_BB(template_push_types(env, info->rhs->def->base->tmpl)) - return GW_OK; + return template_push_types(env, info->rhs->def->base->tmpl); } @@ -137,12 +137,14 @@ ANN static Type fptr_type(const Env env, struct FptrInfo *info) { func_symbol(env, nspc->name, c, stmpl, i) : info->lhs->def->base->xid; CHECK_OO((info->lhs = nspc_lookup_func1(nspc, sym))) struct Func_Base_ *base[2] = { info->lhs->def->base, info->rhs->def->base }; - if(fptr_tmpl_push(env, info) > 0 && fptr_rettype(env, info) > 0 && - fptr_arity(info) && fptr_args(env, base) > 0) + if(fptr_tmpl_push(env, info) > 0) { + if(fptr_rettype(env, info) > 0 && + fptr_arity(info) && fptr_args(env, base) > 0) type = info->lhs->value_ref->type; - if(info->rhs->def->base->tmpl) { - nspc_pop_type(env->gwion->mp, env->curr); - nspc_pop_type(env->gwion->mp, env->curr); + if(info->rhs->def->base->tmpl) { + nspc_pop_type(env->gwion->mp, env->curr); + nspc_pop_type(env->gwion->mp, env->curr); + } } } return type; diff --git a/src/lib/instr.c b/src/lib/instr.c index 1a183c5e..e9342d21 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -55,7 +55,6 @@ INSTR(PopArrayClass) { const M_Object tmp = *(M_Object*)REG(0); ARRAY(obj) = ARRAY(tmp); free_object(shred->info->mp, tmp); - ADD_REF(obj->type_ref) // add ref to typedef array type } ANN static Func_Def from_base(const Env env, const struct dottmpl_ *dt, const Nspc nspc) { diff --git a/src/lib/object.c b/src/lib/object.c index 6ac47a7d..54a08159 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -118,8 +118,11 @@ static OP_CHECK(at_object) { static inline Type new_force_type(MemPool p, const Type t, const Symbol sym) { const Type ret = type_copy(p, t); +// ret->name = s_name(sym); SET_FLAG(ret, force); - nspc_add_type(t->e->owner, sym, ret); +// nspc_add_type(t->e->owner, sym, ret); +// map_set(&t->e->owner->info->type->map, sym, ret); + map_set(vector_front(&t->e->owner->info->type->ptr), sym, ret); return ret; } @@ -129,7 +132,8 @@ static Type get_force_type(const Env env, const Type t) { strcpy(name, t->name); strcpy(name + len, STR_FORCE); const Symbol sym = insert_symbol(env->gwion->st, name); - return nspc_lookup_type0(t->e->owner, sym) ?: new_force_type(env->gwion->mp, t, sym); + return nspc_lookup_type1(t->e->owner, sym) ?: new_force_type(env->gwion->mp, t, sym); +// return nspc_lookup_type0(t->e->owner, sym) ?: new_force_type(env, t, sym); } static OP_CHECK(opck_object_cast) { diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 6c3f6f2a..df756db1 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -11,6 +11,7 @@ #include "emit.h" #include "traverse.h" #include "parse.h" +#include "operator.h" static inline m_str access(ae_Exp_Meta meta) { return meta == ae_meta_value ? "non-mutable" : "protected"; diff --git a/src/lib/ptr.c b/src/lib/ptr.c index 36cddd28..c8dd80c6 100644 --- a/src/lib/ptr.c +++ b/src/lib/ptr.c @@ -16,17 +16,13 @@ static OP_CHECK(opck_ptr_assign) { const Exp_Binary* bin = (Exp_Binary*)data; + if(bin->lhs->meta != ae_meta_var) + ERR_N(exp_self(bin)->pos, "left side operand is constant"); + bin->lhs->emit_var = 1; Type t = bin->lhs->type; - do { - if(!strcmp(t->name, get_type_name(env, bin->rhs->type->name, 1))) { - if(bin->lhs->meta != ae_meta_var) { - env_err(env, exp_self(bin)->pos, "left side operand is constant"); - return t_null; - } - bin->lhs->emit_var = 1; - return bin->lhs->type; - } - } while((t = t->e->parent)); + do if(!strcmp(t->name, get_type_name(env, bin->rhs->type->name, 1))) + return bin->lhs->type; + while((t = t->e->parent)); return t_null; } @@ -46,10 +42,8 @@ static OP_CHECK(opck_implicit_ptr) { const struct Implicit* imp = (struct Implicit*)data; const Exp e = (Exp)imp->e; if(!strcmp(get_type_name(env, imp->t->name, 1), e->type->name)) { - if(e->meta == ae_meta_value) { - env_err(env, 0, "can't cast constant to Ptr"); - return t_null; - } + if(e->meta == ae_meta_value) + ERR_N(e->pos, "can't cast constant to Ptr"); e->cast_to = imp->t; e->emit_var = 1; return imp->t; diff --git a/src/oo/env.c b/src/oo/env.c index f7e305f7..04536574 100644 --- a/src/oo/env.c +++ b/src/oo/env.c @@ -94,6 +94,7 @@ ANN void env_add_type(const Env env, const Type type) { v_type->e->d.base_type = type; SET_FLAG(type, builtin); nspc_add_type(env->curr, insert_symbol(type->name), type); +// map_set(&env->curr->info->type->map, insert_symbol(type->name), type); const Value v = new_value(env->gwion->mp, v_type, type->name); SET_FLAG(v, checked | ae_flag_const | ae_flag_global | ae_flag_builtin); nspc_add_value(env->curr, insert_symbol(type->name), v); diff --git a/src/oo/nspc.c b/src/oo/nspc.c index 993b6a3e..4ecba648 100644 --- a/src/oo/nspc.c +++ b/src/oo/nspc.c @@ -53,16 +53,16 @@ describe_nspc_free(Func, func) describe_nspc_free(Type, type) ANN static void free_nspc(Nspc a, Gwion gwion) { + free_nspc_value(a, gwion); nspc_free_func(a, gwion); + if(a->info->op_map.ptr) + free_op_map(&a->info->op_map, gwion); nspc_free_type(a, gwion); - free_nspc_value(a, gwion); if(a->info->class_data) mp_free2(gwion->mp, a->info->class_data_size, a->info->class_data); if(a->info->vtable.ptr) vector_release(&a->info->vtable); - if(a->info->op_map.ptr) - free_op_map(&a->info->op_map, gwion); mp_free(gwion->mp, NspcInfo, a->info); if(a->pre_ctor) REM_REF(a->pre_ctor, gwion); diff --git a/src/oo/type.c b/src/oo/type.c index 1778b122..f8bc74af 100644 --- a/src/oo/type.c +++ b/src/oo/type.c @@ -18,15 +18,17 @@ ANN static void free_type(Type a, Gwion gwion) { free_stmt(gwion->mp, a->e->def->stmt); } a->e->def->stmt = NULL; - } - free_class_def(gwion->mp, a->e->def); + } else + free_class_def(gwion->mp, a->e->def); } if(a->nspc) REM_REF(a->nspc, gwion); - if(a->e->contains.ptr) + if(a->e->contains.ptr) { + for(m_uint i = 0; i < vector_size(&a->e->contains); ++i) + REM_REF((Type)vector_at(&a->e->contains, i), gwion); vector_release(&a->e->contains); -// TODO: commenting this should not happen -// mp_free(gwion->mp, TypeInfo, a->e); + } + mp_free(gwion->mp, TypeInfo, a->e); mp_free(gwion->mp, Type, a); } @@ -86,6 +88,8 @@ ANN Type array_base(Type type) { ANN Type array_type(const Env env, const Type base, const m_uint depth) { m_uint i = depth + 1; + if(depth > 1) + array_type(env, base, depth-1); size_t len = strlen(base->name); char name[len + 2* depth + 1]; strcpy(name, base->name); diff --git a/src/oo/value.c b/src/oo/value.c index 3ef89738..225a4c0c 100644 --- a/src/oo/value.c +++ b/src/oo/value.c @@ -13,7 +13,7 @@ ANN static void free_value(Value a, Gwion gwion) { !(GET_FLAG(a, enum) && GET_FLAG(a, builtin) && a->owner_class) && isa(a->type, t_object) < 0) _mp_free(gwion->mp, a->type->size, a->d.ptr); - if(isa(a->type, t_class) > 0 || isa(a->type, t_function) > 0 || GET_FLAG(a->type, op)) + if(isa(a->type, t_class) > 0/* || isa(a->type, t_function) > 0*/) REM_REF(a->type, gwion) mp_free(gwion->mp, Value, a); } diff --git a/src/parse/check.c b/src/parse/check.c index c07cf452..29a683a9 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -409,16 +409,21 @@ ANN static inline Value template_get_ready(const Env env, const Value v, const m nspc_lookup_value1(v->owner, sym); } -static Func ensure_tmpl(const Env env, const Func f, const Exp_Call *exp) { +static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *exp) { + CHECK_BO(template_push_types(env, fdef->base->tmpl)) + const m_bool ret = traverse_func_def(env, fdef); nspc_pop_type(env->gwion->mp, env->curr); - if(check_call(env, exp) > 0) { - const Func next = f->next; - f->next = NULL; - const Func func = find_func_match(env, f, exp->args); - f->next = next; - if(func) { - SET_FLAG(func, checked | ae_flag_template); - return func; + if(ret > 0) { + const Func f = fdef->base->func; + if(check_call(env, exp) > 0) { + const Func next = f->next; + f->next = NULL; + const Func func = find_func_match(env, f, exp->args); + f->next = next; + if(func) { + SET_FLAG(func, checked | ae_flag_template); + return func; + } } } return NULL; @@ -447,59 +452,57 @@ ANN static Func _find_template_match(const Env env, const Value v, const Exp_Cal const Symbol sym = func_symbol(env, v->owner->name, v->name, tmpl_name, 0); const Value value = nspc_lookup_value1(v->owner, sym); Func_Def base = v->d.func_ref->def; - struct Func_Base_ *fbase = /*value ? value->type->e->d.func->def :*/ - new_func_base(env->gwion->mp, base->base->td, sym, base->base->args); + struct Func_Base_ *fbase = new_func_base(env->gwion->mp, base->base->td, sym, base->base->args); fbase->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, 0); fbase->tmpl->call = types; - CHECK_BO(template_push_types(env, fbase->tmpl)) - const Stmt stmt = new_stmt_fptr(env->gwion->mp, fbase, base->flag); - if(value) { - stmt->d.stmt_fptr.type = actual_type(value->type); - stmt->d.stmt_fptr.value = value; - } - CHECK_BO(traverse_stmt_fptr(env, &stmt->d.stmt_fptr)) - free_stmt(env->gwion->mp, stmt); - CHECK_OO((base->base->ret_type = known_type(env, base->base->td))) - if(exp->args) - CHECK_OO(check_exp(env, exp->args)) - const Func func = find_func_match(env, fbase->func, exp->args); - if(!value) - map_set(&v->owner->info->type->map, (vtype)sym, (vtype)actual_type(func->value_ref->type)); - nspc_pop_type(env->gwion->mp, env->curr); - xfree(tmpl_name); - env->func = former; - return func; - } - for(m_uint i = 0; i < v->offset + 1; ++i) { - Func_Def fdef = NULL; - Func_Def base = NULL; - Value value = template_get_ready(env, v, tmpl_name, i); + if(template_push_types(env, fbase->tmpl) > 0) { + const Stmt stmt = new_stmt_fptr(env->gwion->mp, fbase, base->flag); if(value) { - if(env->func == value->d.func_ref) { - CHECK_BO(check_call(env, exp)) - m_func = env->func; - break; - } - base = fdef = value->d.func_ref->def; - if(!fdef->base->tmpl) { + stmt->d.stmt_fptr.type = actual_type(value->type); + stmt->d.stmt_fptr.value = value; + } + if(traverse_stmt_fptr(env, &stmt->d.stmt_fptr) > 0 && + (base->base->ret_type = known_type(env, base->base->td)) && + (!exp->args || !!check_exp(env, exp->args))) { + m_func = find_func_match(env, fbase->func, exp->args); + nspc_pop_type(env->gwion->mp, env->curr); + if(!value) + map_set(&v->owner->info->type->map, (vtype)sym, (vtype)actual_type(m_func->value_ref->type)); + } + free_stmt(env->gwion->mp, stmt); + } + } else { + for(m_uint i = 0; i < v->offset + 1; ++i) { + Func_Def fdef = NULL; + Func_Def base = NULL; + Value value = template_get_ready(env, v, tmpl_name, i); + if(value) { + if(env->func == value->d.func_ref) { + if(check_call(env, exp) < 0) + continue; + m_func = env->func; + break; + } + fdef = value->d.func_ref->def; + if(!fdef->base->tmpl) { + if(!(value = template_get_ready(env, v, "template", i))) + continue; + base = value->d.func_ref->def; + fdef->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, (m_int)i); + } + } else { if(!(value = template_get_ready(env, v, "template", i))) continue; base = value->d.func_ref->def; + fdef = new_func_def(env->gwion->mp, new_func_base(env->gwion->mp, base->base->td, insert_symbol(v->name), + base->base->args), base->d.code, base->flag, loc_cpy(env->gwion->mp, base->pos)); fdef->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, (m_int)i); + SET_FLAG(fdef, template); } - } else { - if(!(value = template_get_ready(env, v, "template", i))) - continue; - base = value->d.func_ref->def; - fdef = new_func_def(env->gwion->mp, new_func_base(env->gwion->mp, base->base->td, insert_symbol(v->name), - base->base->args), base->d.code, base->flag, loc_cpy(env->gwion->mp, base->pos)); - fdef->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, (m_int)i); - SET_FLAG(fdef, template); + fdef->base->tmpl->call = types; + if((m_func = ensure_tmpl(env, fdef, exp))) + break; } - fdef->base->tmpl->call = types; - if(traverse_func_template(env, fdef) > 0 && - (m_func = ensure_tmpl(env, fdef->base->func, exp))) - break; } xfree(tmpl_name); env_pop(env, scope); @@ -1190,7 +1193,7 @@ ANN static m_bool check_class_parent(const Env env, const Class_Def cdef) { return GW_OK; } -ANN static inline void inherit(const Type t) { +ANN /*static inline */void inherit(const Type t) { const Nspc nspc = t->nspc, parent = t->e->parent->nspc; nspc->info->offset = parent->info->offset; if(parent->info->vtable.ptr) diff --git a/src/parse/func.c b/src/parse/func.c index ec76499e..7aebd43d 100644 --- a/src/parse/func.c +++ b/src/parse/func.c @@ -11,7 +11,8 @@ #include "value.h" ANN static void free_func(Func a, Gwion gwion) { - if(GET_FLAG(a, template) && !is_fptr(a->value_ref->type)) { +// if(GET_FLAG(a, template) && !is_fptr(a->value_ref->type)) { + if(GET_FLAG(a, template) && !GET_FLAG(a, builtin) && a->def->d.code) { free_tmpl(gwion->mp, a->def->base->tmpl); free_func_base(gwion->mp, a->def->base); free_loc(gwion->mp, a->def->pos); diff --git a/src/parse/operator.c b/src/parse/operator.c index 74d9d259..fe2ffe91 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -25,23 +25,13 @@ typedef struct M_Operator_{ m_bool mut; } M_Operator; -ANN static void free_op(M_Operator* a, Gwion gwion) { - if(a->lhs && a->lhs != OP_ANY_TYPE) - REM_REF(a->lhs, gwion) - if(a->rhs && a->rhs != OP_ANY_TYPE) - REM_REF(a->rhs, gwion) - if(a->ret) - REM_REF(a->ret, gwion) - mp_free(gwion->mp, M_Operator, a); -} - ANN void free_op_map(Map map, struct Gwion_ *gwion) { LOOP_OPTIM for(m_uint i = map_size(map) + 1; --i;) { const restrict Vector v = (Vector)map_at(map, (vtype)i - 1); LOOP_OPTIM for(m_uint j = vector_size(v) + 1; --j;) - free_op((M_Operator*)vector_at(v, j - 1), gwion); + mp_free(gwion->mp, M_Operator, (M_Operator*)vector_at(v, j - 1)); free_vector(gwion->mp, v); } map_release(map); @@ -106,15 +96,7 @@ ANN m_bool add_op(const Gwion gwion, const Nspc nspc, const struct Op_Import* op mo->ck = opi->ck; mo->em = opi->em; mo->mut = opi->mut; -// add vector_add(v, (vtype)mo); -// mo_type_ref - if(opi->lhs && opi->lhs != OP_ANY_TYPE) - ADD_REF(opi->lhs) - if(opi->rhs && opi->rhs != OP_ANY_TYPE) - ADD_REF(opi->rhs) - if(opi->ret) - ADD_REF(opi->ret) return GW_OK; } diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 1684e2d2..4d6dda9d 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -12,6 +12,11 @@ #include "template.h" #include "parse.h" +static inline void add_type(const Env env, const Nspc nspc, const Type t) { + map_set(&nspc->info->type->map, (m_uint)insert_symbol(t->name), (m_uint)t); + map_set(vector_front(&nspc->info->type->ptr), (m_uint)insert_symbol(t->name), (m_uint)t); +} + ANN static Value mk_class(const Env env, const Type base) { const Type t = type_copy(env->gwion->mp, t_class); const Value v = new_value(env->gwion->mp, t, base->name); @@ -38,8 +43,8 @@ ANN m_bool scan0_stmt_fptr(const Env env, const Stmt_Fptr stmt) { t->nspc = new_nspc(env->gwion->mp, name); t->flag = stmt->base->td->flag; stmt->type = t; - nspc_add_type(t->e->owner, stmt->base->xid, t); stmt->value = mk_class(env, t); + add_type(env, t->e->owner, t); return GW_OK; } @@ -52,7 +57,7 @@ ANN m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt) { t->size = base->size; const Nspc nspc = (!env->class_def && GET_FLAG(stmt->ext, global)) ? env->global_nspc : env->curr; - nspc_add_type(nspc, stmt->xid, t); + add_type(env, nspc, t); t->e->owner = nspc; stmt->type = t; t->flag = stmt->ext->flag | ae_flag_checked; @@ -87,7 +92,7 @@ ANN m_bool scan0_stmt_enum(const Env env, const Stmt_Enum stmt) { t->e->owner = nspc; stmt->t = t; if(stmt->xid) { - nspc_add_type(nspc, stmt->xid, t); + add_type(env, nspc, t); mk_class(env, t); } return GW_OK; @@ -104,7 +109,7 @@ ANN static Type union_type(const Env env, const Nspc nspc, const Symbol s, const t->e->owner = nspc; t->e->parent = t_union; if(add) { - nspc_add_type(nspc, s, t); + add_type(env, nspc, t); mk_class(env, t); } return t; @@ -124,13 +129,12 @@ ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { stmt->value->owner_class = env->class_def; stmt->value->owner = nspc; nspc_add_value(nspc, stmt->xid, stmt->value); + add_type(env, nspc, t); SET_FLAG(stmt->value, checked | stmt->flag); if(env->class_def && !GET_FLAG(stmt, static)) { SET_FLAG(stmt->value, member); SET_FLAG(stmt, member); } - if(!stmt->type_xid) - SET_FLAG(t, op); } else if(stmt->type_xid) { CHECK_BB(scan0_defined(env, stmt->type_xid, stmt_self(stmt)->pos)) const Nspc nspc = !GET_FLAG(stmt, global) ? @@ -145,6 +149,9 @@ ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { stmt->value->owner_class = env->class_def; stmt->value->owner = nspc; nspc_add_value(nspc, stmt->xid, stmt->value); + char c[16]; + sprintf(c, "%p", stmt); + nspc_add_type(nspc, insert_symbol(c), t); SET_FLAG(stmt->value, checked | stmt->flag); } if(stmt->tmpl) { @@ -213,11 +220,11 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) { const Type t = new_type(env->gwion->mp, ++env->scope->type_xid, s_name(cdef->base.xid), t_object); t->e->owner = env->curr; t->nspc = new_nspc(env->gwion->mp, t->name); - t->nspc->parent = GET_FLAG(cdef, global) ? env_nspc(env) : env->curr; + t->nspc->parent = (GET_FLAG(cdef, global) ? env_nspc(env) : env->curr); t->e->def = cdef; t->flag = cdef->flag; if(!strstr(t->name, "<")) - nspc_add_type(env->curr, cdef->base.xid, t); + add_type(env, t->e->owner, t); if(cdef->base.tmpl) { SET_FLAG(t, template); SET_FLAG(cdef, template); diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 7dbcd6d9..4240b335 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -27,22 +27,35 @@ ANN static inline Type get_base_type(const Env env, const Type t) { return nspc_lookup_type1(env->curr, insert_symbol(decl_name)); } +ANN static inline void contains(const Type base, const Type t) { + if(vector_find(&base->e->contains, (vtype)t) == GW_ERROR) { + vector_add(&base->e->contains, (vtype)t); + ADD_REF(t); + } +} + +ANN static inline void type_contains(const Type base, const Type t) { + if(!base->e->contains.ptr) + vector_init(&base->e->contains); +printf("%s => %s\n", t->name, base->name); + contains(base, t); +} + ANN static m_bool type_recursive(const Env env, Exp_Decl* decl, const Type t) { const Type decl_base = get_base_type(env, t); const Type base = get_base_type(env, env->class_def); if(decl_base && base) { - if(!base->e->contains.ptr) - vector_init(&base->e->contains); - vector_add(&base->e->contains, (vtype)decl_base); + type_contains(base, decl_base); // NEEDED + type_contains(env->class_def, t); if(decl_base->e->contains.ptr) { - for(m_uint i = 0; i < vector_size(&decl_base->e->contains); ++i) { - if(base == (Type)vector_at(&decl_base->e->contains, i) && !GET_FLAG(decl->td, ref)) + for(m_uint i = 0; i < vector_size(&t->e->contains); ++i) { + if(env->class_def == (Type)vector_at(&t->e->contains, i) && !GET_FLAG(decl->td, ref)) ERR_B(exp_self(decl)->pos, "%s declared inside %s\n. (make it a ref ?)", decl_base->name, decl_base == base ? "itself" : base->name); } } } - return GW_OK; + return GW_OK; } ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) { @@ -210,10 +223,10 @@ ANN m_bool scan1_stmt_enum(const Env env, const Stmt_Enum stmt) { const Value v = new_value(env->gwion->mp, stmt->t, s_name(list->xid)); if(env->class_def) { v->owner_class = env->class_def; - v->owner = env->curr; SET_FLAG(v, static); SET_ACCESS(stmt, v) } + v->owner = env->curr; SET_FLAG(v, const | ae_flag_enum | ae_flag_checked); nspc_add_value(stmt->t->e->owner, list->xid, v); vector_add(&stmt->values, (vtype)v); diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 8d51208f..b800ee17 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -111,7 +111,7 @@ ANN m_bool scan2_stmt_fptr(const Env env, const Stmt_Fptr ptr) { } if(ptr->base->tmpl) SET_FLAG(ptr->type, func); - nspc_add_value(env->curr, ptr->base->xid, ptr->value); +// nspc_add_value(env->curr, ptr->base->xid, ptr->value); nspc_add_func(ptr->type->e->owner, ptr->base->xid, ptr->base->func); return GW_OK; } @@ -413,14 +413,6 @@ ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f) { f->base->args->next ? f->base->args->next->var_decl->value->type : NULL; struct Op_Import opi = { .op=op, .lhs=l, .rhs=r, .ret=f->base->ret_type, .pos=f->pos }; CHECK_BB(env_add_op(env, &opi)) - if(env->class_def) { - if(env->class_def == l) - REM_REF(l, env->gwion) - if(env->class_def == r) - REM_REF(r, env->gwion) - if(env->class_def == f->base->ret_type) - REM_REF(f->base->ret_type, env->gwion) - } return GW_OK; } diff --git a/src/parse/template.c b/src/parse/template.c index 50af46b3..51805843 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -165,8 +165,8 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) { a->base.tmpl->call = type->types; if(isa(t, t_union) < 0) { CHECK_BO(scan0_class_def(env, a)) - map_set(&t->e->owner->info->type->map, (vtype)insert_symbol(a->base.type->name), - (vtype)a->base.type); + map_set(&t->e->owner->info->type->map, (vtype)a->base.xid, (vtype)a->base.type); + map_set((Map)vector_front((Vector)&t->e->owner->info->type->ptr), (vtype)a->base.xid, (vtype)a->base.type); } else { a->stmt = new_stmt_union(env->gwion->mp, (Decl_List)a->body, t->e->def->pos); a->stmt->d.stmt_union.type_xid = a->base.xid; diff --git a/src/parse/traverse_template.c b/src/parse/traverse_template.c index 1a49596a..8b32476f 100644 --- a/src/parse/traverse_template.c +++ b/src/parse/traverse_template.c @@ -10,8 +10,5 @@ ANN m_bool traverse_func_template(const Env env, const Func_Def def) { CHECK_BB(template_push_types(env, def->base->tmpl)) - if(traverse_func_def(env, def) > 0) - return GW_OK; - nspc_pop_type(env->gwion->mp, env->curr); - return GW_ERROR; + return traverse_func_def(env, def); } diff --git a/tests/import/array.c b/tests/import/array.c index 43ba2ad8..635ea3da 100644 --- a/tests/import/array.c +++ b/tests/import/array.c @@ -14,7 +14,7 @@ GWION_IMPORT(array_test) { Type t_invalid_var_name; CHECK_OB((t_invalid_var_name = gwi_mk_type(gwi, "invalid_var_name", SZ_INT, t_object))) CHECK_BB(gwi_class_ini(gwi, t_invalid_var_name, NULL, NULL)) - CHECK_BB(gwi_item_ini(gwi,"int[]", "int_array")) + CHECK_BB(gwi_item_ini(gwi, "int[]", "int_array")) CHECK_BB(gwi_item_end(gwi, 0, NULL)) // import array var CHECK_BB(gwi_func_ini(gwi, "float[][]", "f", test_mfun)) CHECK_BB(gwi_func_end(gwi, 0))