From: Jérémie Astor Date: Wed, 22 Jul 2020 15:16:15 +0000 (+0200) Subject: :bomb: Improve struct releasing X-Git-Tag: nightly~1433 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=17cb0613950165c008ce2e31204233c6ed8e480f;p=gwion.git :bomb: Improve struct releasing --- diff --git a/include/object.h b/include/object.h index e199b54b..c065c9fd 100644 --- a/include/object.h +++ b/include/object.h @@ -36,4 +36,9 @@ static inline void _release(const restrict M_Object obj, const restrict VM_Shred static inline void release(const restrict M_Object obj, const restrict VM_Shred shred) { if(obj)_release(obj, shred); } +typedef void (f_release)(const VM_Shred shred, const Type t NUSED, const m_bit* ptr); +#define RELEASE_FUNC(a) void (a)(const VM_Shred shred, const Type t NUSED, const m_bit* ptr) +static inline RELEASE_FUNC(object_release) { release(*(M_Object*)ptr, shred); } +RELEASE_FUNC(struct_release); + #endif diff --git a/src/emit/emit.c b/src/emit/emit.c index 8c2d3fd6..7a55d21c 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -187,17 +187,33 @@ regxxx(push, Push) regxxx(pushi, PushImm) regxxx(seti, SetImm) +ANN static void struct_expand(const Emitter emit, const Type t) { + const Instr instr = emit_add_instr(emit, Reg2RegDeref); + instr->m_val = -SZ_INT; + instr->m_val2 = t->size; +// regpush(emit, t->size - SZ_INT); +} + + +INSTR(ArrayStruct); + ANN static void emit_pre_constructor_array(const Emitter emit, const Type type) { const m_uint start_index = emit_code_size(emit); const Instr top = emit_add_instr(emit, ArrayTop); top->m_val2 = (m_uint)type; + if(GET_FLAG(type, struct)) { + const Instr instr = emit_add_instr(emit, ArrayStruct); + instr->m_val = type->size; + } emit_pre_ctor(emit, type); - const Instr bottom = emit_add_instr(emit, ArrayBottom); + if(!GET_FLAG(type, struct)) + emit_add_instr(emit, ArrayBottom); + else + regpop(emit, SZ_INT); regpop(emit, SZ_INT); const Instr pc = emit_add_instr(emit, Goto); pc->m_val = start_index; top->m_val = emit_code_size(emit); - bottom->m_val = start_index; regpop(emit, SZ_INT*3); emit_add_instr(emit, ArrayPost); } @@ -229,9 +245,9 @@ ANEW ANN static ArrayInfo* new_arrayinfo(const Emitter emit, const Type t) { ANN static inline void arrayinfo_ctor(const Emitter emit, ArrayInfo *info) { const Type base = info->base; -// TODO: needed for coumpund? - if(isa(base, emit->gwion->type[et_object]) > 0 && !GET_FLAG(base, abstract)) { + if(isa(base, emit->gwion->type[et_compound]) > 0 && !GET_FLAG(base, abstract)) { emit_pre_constructor_array(emit, base); +// if(isa(base, emit->gwion->type[et_object]) > 0) info->is_obj = 1; } } @@ -514,11 +530,8 @@ ANN static void interp_multi(const Emitter emit, const Exp e) { regpop(emit, offset); } -ANN static void interp_size(const Emitter emit, const Type t) { - const m_uint sz = (isa(t, emit->gwion->type[et_object]) < 0 || - (!GET_FLAG(t, builtin) && isa(t, emit->gwion->type[et_compound]) > 0))? - t->size : SZ_INT; - const Instr instr = regseti(emit, sz); +ANN static inline void interp_size(const Emitter emit, const Type t) { + const Instr instr = regseti(emit, t->size); instr->m_val2 = SZ_INT; } @@ -537,10 +550,8 @@ ANN static m_bool emit_interp(const Emitter emit, const Exp exp) { regseti(emit, (m_uint)e->info->type); interp_size(emit, e->info->type); const m_bool isobj = isa(e->info->type, emit->gwion->type[et_object]) > 0; - if(isobj) { - if(!GET_FLAG(e->info->type, force)) - emit_add_instr(emit, GackType); - } + if(isobj && !GET_FLAG(e->info->type, force)) + emit_add_instr(emit, GackType); const Instr instr = emit_add_instr(emit, Gack); instr->m_val = emit_code_offset(emit); } while((e = e->next = next)); @@ -594,13 +605,11 @@ ANN static m_bool decl_static(const Emitter emit, const Var_Decl var_decl, const } ANN static inline int struct_ctor(const Value v) { - return GET_FLAG(v->type, struct) && !GET_FLAG(v->type, builtin); + return GET_FLAG(v->type, struct) && v->type->nspc->pre_ctor; } ANN static void decl_expand(const Emitter emit, const Type t) { - const Instr instr = emit_add_instr(emit, Reg2RegDeref); - instr->m_val = -SZ_INT; - instr->m_val2 = t->size; + struct_expand(emit, t); regpush(emit, t->size - SZ_INT); } @@ -653,7 +662,13 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, exec) : emit_struct_decl(emit, v, !struct_ctor(v) ? emit_addr : 1); instr->m_val = v->from->offset; if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref)) { - emit_add_instr(emit, Assign); + if(!emit_var) + emit_add_instr(emit, Assign); + else { + regpop(emit, SZ_INT); + const Instr instr = emit_add_instr(emit, Reg2Reg); + instr->m_val = -SZ_INT; + } const size_t missing_depth = type->array_depth - (array ? array->depth : 0); if(missing_depth && !GET_FLAG(decl->td, force)) { const Instr push = emit_add_instr(emit, Reg2Reg); @@ -793,6 +808,7 @@ ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call* exp_call) { } const Exp e = exp_self(exp_call); if(exp_getvar(e)) { +puts("here"); regpop(emit, exp_self(exp_call)->info->type->size - SZ_INT); const Instr instr = emit_add_instr(emit, Reg2RegAddr); instr->m_val = -SZ_INT; @@ -1810,8 +1826,9 @@ DECL_STMT_FUNC(emit, m_bool , Emitter) ANN static m_bool emit_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) { CHECK_BB(emit_stmt_func[stmt->stmt_type](emit, &stmt->d)) - if(pop && stmt->stmt_type == ae_stmt_exp && stmt->d.stmt_exp.val) + if(pop && stmt->stmt_type == ae_stmt_exp && stmt->d.stmt_exp.val) { pop_exp(emit, stmt->d.stmt_exp.val); + } return GW_OK; } @@ -1877,7 +1894,7 @@ ANN static VM_Code emit_internal(const Emitter emit, const Func f) { ADD_REF(f->code) return f->code; } else if(f->def->base->xid == insert_symbol("@gack")) { - regpop(emit, SZ_INT*2); + regpop(emit, SZ_INT + f->value_ref->from->owner_class->size); const Instr instr = emit_add_instr(emit, RegPushMem); instr->m_val = SZ_INT; f->code = finalyze(emit, FuncReturn); @@ -2026,7 +2043,7 @@ ANN Code* emit_class_code(const Emitter emit, const m_str name) { ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) { const Type parent = cdef->base.type->e->parent; - return !GET_FLAG(parent, emit) ? scanx_parent(parent, emit_cdef, emit) : GW_OK; + return !GET_FLAG(parent, emit) ? ensure_emit(emit, parent) : GW_OK; } ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) { @@ -2042,7 +2059,7 @@ ANN void emit_class_finish(const Emitter emit, const Nspc nspc) { ANN static m_bool cdef_parent(const Emitter emit, const Class_Def cdef) { if(cdef->base.tmpl && cdef->base.tmpl->list) CHECK_BB(template_push_types(emit->env, cdef->base.tmpl)) - const m_bool ret = scanx_parent(cdef->base.type, emit_parent, emit); + const m_bool ret = emit_parent(emit, cdef); if(cdef->base.tmpl && cdef->base.tmpl->list) nspc_pop_type(emit->gwion->mp, emit->env->curr); return ret; @@ -2055,6 +2072,8 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) { if(GET_FLAG(t, emit)) return GW_OK; SET_FLAG(t, emit); + if(t->e->owner_class && !GET_FLAG(t->e->owner_class, emit)) + CHECK_BB(ensure_emit(emit, t->e->owner_class)) if(cdef->base.ext && t->e->parent->e->def && !GET_FLAG(t->e->parent, emit)) CHECK_BB(cdef_parent(emit, cdef)) nspc_allocdata(emit->gwion->mp, t->nspc); diff --git a/src/env/type.c b/src/env/type.c index a8eede91..6cefe46f 100644 --- a/src/env/type.c +++ b/src/env/type.c @@ -6,6 +6,7 @@ #include "parse.h" #include "gwion.h" #include "clean.h" +#include "object.h" ANN static inline m_bool freeable(const Type a) { return !GET_FLAG(a, nonnull) && GET_FLAG(a, template); @@ -110,6 +111,14 @@ ANN Type array_type(const Env env, const Type src, const m_uint depth) { t->array_depth = depth + src->array_depth; t->e->d.base_type = array_base(src) ?: src; t->e->owner = src->e->owner; + if(depth > 1 || isa(src, env->gwion->type[et_compound]) > 0) { + t->nspc = new_nspc(env->gwion->mp, s_name(sym)); + inherit(t); + t->nspc->info->class_data_size = SZ_INT; + nspc_allocdata(env->gwion->mp, t->nspc); + *(f_release**)(t->nspc->info->class_data) = (depth > 1 || !GET_FLAG(src, struct)) ? + object_release : struct_release; + } else ADD_REF((t->nspc = env->gwion->type[et_array]->nspc)) SET_FLAG(t, valid); mk_class(env, t); diff --git a/src/import/cdef.c b/src/import/cdef.c index 6a96d2e9..814ffa5b 100644 --- a/src/import/cdef.c +++ b/src/import/cdef.c @@ -26,12 +26,11 @@ ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const ae_f return GW_OK; } -ANN2(1,2) static inline m_bool class_parent(const Env env, const Type t) { - Type parent = t->e->parent; - while(parent && !GET_FLAG(parent, valid)) { +ANN2(1,2) static inline m_bool class_parent(const Env env, Type t) { + while(t && !GET_FLAG(t, valid)) { if(t->e->def) CHECK_BB(traverse_class_def(env, t->e->def)) - parent = parent->e->parent; + t = t->e->parent; } return GW_OK; } @@ -70,11 +69,16 @@ ANN static inline void gwi_type_flag(const Type t) { ANN static Type type_finish(const Gwi gwi, const Type t) { gwi_add_type(gwi, t); - CHECK_BO(class_parent(gwi->gwion->env, t)) import_class_ini(gwi->gwion->env, t); return t; } +ANN2(1,2) Type handle_class(const Gwi gwi, Type_Decl *td) { + DECL_OO(const Type, p, = known_type(gwi->gwion->env, td)) + CHECK_BO(class_parent(gwi->gwion->env, p)) + return p; +} + ANN2(1,2) Type gwi_class_ini(const Gwi gwi, const m_str name, const m_str parent) { struct ImportCK ck = { .name=name }; CHECK_BO(check_typename_def(gwi, &ck)) @@ -82,13 +86,15 @@ ANN2(1,2) Type gwi_class_ini(const Gwi gwi, const m_str name, const m_str parent Tmpl* tmpl = ck.tmpl ? new_tmpl_base(gwi->gwion->mp, ck.tmpl) : NULL; if(tmpl) CHECK_BO(template_push_types(gwi->gwion->env, tmpl)) - const Type p = known_type(gwi->gwion->env, td); // check - if(!p) { - env_pop(gwi->gwion->env, 0); - return NULL; - } + const Type base = find_type(gwi->gwion->env, td); + const Type_List tl = td->types; + if(GET_FLAG(base, unary)) + td->types = NULL; + const Type p = !td->types ? handle_class(gwi, td) : NULL; + td->types = tl; if(tmpl) nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr); + CHECK_OO(p) const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, s_name(ck.sym), p); t->e->def = new_class_def(gwi->gwion->mp, 0, ck.sym, td, NULL, loc(gwi)); t->e->def->base.tmpl = tmpl; diff --git a/src/lib/array.c b/src/lib/array.c index d9bd19a9..57f55ed6 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -53,16 +53,16 @@ ANN static inline int is_array(const Type *types, const Type type) { } static DTOR(array_dtor) { - const Type t = !GET_FLAG(o->type_ref, nonnull) ? - o->type_ref : o->type_ref->e->parent; + const Type t = unflag_type(o->type_ref); if(*(void**)(o->data + SZ_INT)) xfree(*(void**)(o->data + SZ_INT)); struct M_Vector_* a = ARRAY(o); if(!a) return; - if(t->array_depth > 1 || is_array(shred->info->vm->gwion->type, t)) + if(t->nspc->info->class_data_size) { for(m_uint i = 0; i < ARRAY_LEN(a); ++i) - release(*(M_Object*)(ARRAY_PTR(a) + i * SZ_INT), shred); + (*(f_release**)t->nspc->info->class_data)(shred, array_base(t), ARRAY_PTR(a) + i * ARRAY_SIZE(a)); + } free_m_vector(shred->info->mp, a); } @@ -95,8 +95,9 @@ ANN void m_vector_set(const M_Vector v, const m_uint i, const void* data) { ANN void m_vector_rem(const M_Vector v, m_uint index) { const m_uint size = ARRAY_SIZE(v); - memmove(ARRAY_PTR(v) + index * size, ARRAY_PTR(v) + (index + 1) * size, - (ARRAY_SIZE(v) - index - 1) *size); + if(index < ARRAY_LEN(v) - 1) + memmove(ARRAY_PTR(v) + index * size, ARRAY_PTR(v) + (index + 1) * size, + (ARRAY_SIZE(v) - index - 1) *size); --ARRAY_LEN(v); if(ARRAY_LEN(v) < ARRAY_CAP(v) / 2) { const m_uint cap = ARRAY_CAP(v) /= 2; @@ -109,11 +110,9 @@ static MFUN(vm_vector_rem) { const M_Vector v = ARRAY(o); if(index < 0 || (m_uint)index >= ARRAY_LEN(v)) return; - if(isa(o->type_ref, shred->info->vm->gwion->type[et_object]) > 0) { - M_Object obj; - m_vector_get(v, (vtype)index, &obj); - release(obj,shred); - } + const Type t = unflag_type(o->type_ref); + if(t->nspc->info->class_data_size) + (*(f_release**)t->nspc->info->class_data)(shred, array_base(t), ARRAY_PTR(v) + index * ARRAY_SIZE(v)); m_vector_rem(v, (vtype)index); } @@ -371,6 +370,13 @@ GWION_IMPORT(array) { return GW_OK; } +INSTR(ArrayStruct) { + const M_Object ref = *(M_Object*)(REG(-SZ_INT * 5)); + const m_int idx = (*(m_int*)((shred->reg -SZ_INT * 3)))++; + *(m_bit**)(shred->reg) = m_vector_addr(ARRAY(ref), idx); + shred->reg += SZ_INT; // regpush +} + INSTR(ArrayBottom) { *(M_Object*)(*(m_uint**)REG(-SZ_INT * 4))[(*(m_int*)REG(-SZ_INT * 3))++] = *(M_Object*)REG(-SZ_INT); } @@ -439,7 +445,7 @@ ANN static M_Object* init_array(const VM_Shred shred, const ArrayInfo* info, m_u *num_obj *= *(m_uint*)REG(SZ_INT * curr); ++curr; } - return *num_obj > 0 ? (M_Object*)xcalloc(*num_obj, SZ_INT) : NULL; + return *num_obj > 0 ? (M_Object*)xcalloc(*num_obj, info->base->size) : NULL; } INSTR(ArrayAlloc) { @@ -470,3 +476,4 @@ INSTR(ArrayAlloc) { *(m_uint*) REG(-SZ_INT) = num_obj; } } + diff --git a/src/lib/engine.c b/src/lib/engine.c index 35d3b454..efc50803 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -56,7 +56,7 @@ static GACK(gack_float) { } static GACK(gack_compound) { - INTERP_PRINTF("%p", *(void**)VALUE); + INTERP_PRINTF("%p", VALUE); } #define mk_class_instr(op, arg0, arg1, ...) \ static INSTR(instr_class_##op) { \ diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 8cf1352a..e12894ca 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -113,7 +113,7 @@ static OP_EMIT(opem_implicit_null2obj) { return (Instr)GW_OK; } -ANN static Type scan_class(const Env env, const Type t, const Type_Decl* td); +ANN /*static*/ Type scan_class(const Env env, const Type t, const Type_Decl* td); static Type opck_object_scan(const Env env, const struct TemplateScan *ts) { if(ts->td->types) @@ -384,7 +384,7 @@ ANN static m_bool _scan_class(const Env env, const Type t, const Class_Def a) { return GW_OK; } -ANN static Type scan_class(const Env env, const Type t, const Type_Decl* td) { +ANN Type scan_class(const Env env, const Type t, const Type_Decl* td) { if(template_match(t->e->def->base.tmpl->list, td->types) < 0) ERR_O(td->pos, _("invalid template types number")) DECL_OO(const Class_Def, a, = template_class(env, t->e->def, td->types)) @@ -422,6 +422,21 @@ ANN Exp symbol_owned_exp(const Gwion gwion, const Symbol *data) { return dot; } +ANN void struct_release(const VM_Shred shred, const Type base, const m_bit *ptr) { + const Vector types = &base->e->tuple->types; + const Vector offsets = &base->e->tuple->offset; + for(m_uint i = 0; i < vector_size(types); ++i) { + const Type t = (Type)vector_at(types, i); + if(isa(t, shred->info->vm->gwion->type[et_compound]) < 0) + continue; + const m_uint offset = vector_at(offsets, i); + if(!GET_FLAG(t, struct)) + release(*(M_Object*)(ptr + offset), shred); + else + struct_release(shred, t, *(m_bit**)(ptr + offset)); + } +} + GWION_IMPORT(object_op) { const Type t_null = gwi_mk_type(gwi, "@null", SZ_INT, "Object"); gwi->gwion->type[et_null] = t_null; diff --git a/src/lib/ptr.c b/src/lib/ptr.c index fc931530..84158e10 100644 --- a/src/lib/ptr.c +++ b/src/lib/ptr.c @@ -28,11 +28,13 @@ static OP_CHECK(opck_ptr_assign) { exp_setvar(bin->lhs, 1); Type t = bin->lhs->info->type; do { +// t = unflag_type(t); Type u = bin->rhs->info->type; do { +// u = unflag_type(u); const m_str str = get_type_name(env, u, 1); if(str && !strcmp(t->name, str)) - return bin->lhs->info->type; + return bin->lhs->info->type; // use rhs? } while((u = u->e->parent)); } while((t = t->e->parent)); return env->gwion->type[et_null]; @@ -42,6 +44,7 @@ static INSTR(instr_ptr_assign) { POP_REG(shred, SZ_INT) const M_Object o = *(M_Object*)REG(0); *(m_uint**)o->data = *(m_uint**)REG(-SZ_INT); + _release(o, shred); } static OP_CHECK(opck_ptr_deref) { @@ -122,8 +125,41 @@ static OP_EMIT(opem_ptr_deref) { return instr; } +ANN Type scan_class(const Env env, const Type t, const Type_Decl* td); + +static DTOR(ptr_object_dtor) { + release(*(M_Object*)o->data, shred); +} + +static DTOR(ptr_struct_dtor) { + const Type t = (Type)vector_front(&o->type_ref->e->tuple->types); + struct_release(shred, t, *(m_bit**)o->data); +} + +static OP_CHECK(opck_ptr_scan) { + struct TemplateScan *ts = (struct TemplateScan*)data; + const Type t = (Type)scan_class(env, ts->t, ts->td); + const Type base = known_type(env, t->e->def->base.tmpl->call->td); + if(isa(base, env->gwion->type[et_compound]) > 0 && !t->nspc->dtor) { + t->nspc->dtor = new_vm_code(env->gwion->mp, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@PtrDtor"); + if(!GET_FLAG(t, struct)) + t->nspc->dtor->native_func = (m_uint)ptr_object_dtor; + else + t->nspc->dtor->native_func = (m_uint)ptr_struct_dtor; + SET_FLAG(t, dtor); + } + return t; +} + GWION_IMPORT(ptr) { - const Type t_ptr = gwi_class_ini(gwi, "<~A~>Ptr", NULL); + const Type _t_ptr = gwi_class_ini(gwi, "@Ptr", NULL); + GWI_BB(gwi_class_end(gwi)) + SET_FLAG(_t_ptr, unary); + GWI_BB(gwi_oper_ini(gwi, "@Ptr", NULL, NULL)) + GWI_BB(gwi_oper_add(gwi, opck_ptr_scan)) + GWI_BB(gwi_oper_end(gwi, "@scan", NULL)) + const Type t_ptr = gwi_class_ini(gwi, "<~A~>Ptr", "@Ptr"); +// const Type t_ptr = gwi_class_ini(gwi, "<~A~>Ptr", NULL); gwi->gwion->type[et_ptr] = t_ptr; GWI_BB(gwi_item_ini(gwi, "@internal", "@val")) GWI_BB(gwi_item_end(gwi, 0, NULL)) diff --git a/src/lib/vararg.c b/src/lib/vararg.c index aa1db9f9..ecb19db7 100644 --- a/src/lib/vararg.c +++ b/src/lib/vararg.c @@ -31,6 +31,8 @@ static DTOR(vararg_dtor) { const Type t = (Type)vector_at(&arg->t, i); if(isa(t, shred->info->vm->gwion->type[et_object]) > 0) release(*(M_Object*)(arg->d + offset), shred); + else if(GET_FLAG(t, struct)) + struct_release(shred, t, *(m_bit**)(arg->d + offset)); offset += t->size; } } diff --git a/src/parse/check.c b/src/parse/check.c index e904d781..bbeee460 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -357,10 +357,6 @@ ANN static Type check_prim_typeof(const Env env, const Exp *exp) { ANN static Type check_prim_interp(const Env env, const Exp* exp) { CHECK_OO(check_exp(env, *exp)) - Exp e = *exp; - do if(GET_FLAG(e->info->type, struct) && !GET_FLAG(e->info->type, builtin)) - exp_setvar(e, 1); - while((e = e->next)); return env->gwion->type[et_string]; } @@ -1416,7 +1412,7 @@ ANN static m_bool check_parent(const Env env, const Class_Def cdef) { if(td->array) CHECK_BB(check_subscripts(env, td->array, 1)) if(parent->e->def && !GET_FLAG(parent, check)) - CHECK_BB(scanx_parent(parent, check_cdef, env)) + CHECK_BB(ensure_check(env, parent)) if(GET_FLAG(parent, typedef)) SET_FLAG(cdef->base.type, typedef); return GW_OK; @@ -1425,7 +1421,7 @@ ANN static m_bool check_parent(const Env env, const Class_Def cdef) { ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) { if(cdef->base.tmpl && cdef->base.tmpl->list) CHECK_BB(template_push_types(env, cdef->base.tmpl)) - const m_bool ret = scanx_parent(cdef->base.type, check_parent, env); + const m_bool ret = check_parent(env, cdef); if(cdef->base.tmpl && cdef->base.tmpl->list) nspc_pop_type(env->gwion->mp, env->curr); return ret; @@ -1436,7 +1432,7 @@ ANN m_bool check_class_def(const Env env, const Class_Def cdef) { return GW_OK; const Type t = cdef->base.type; if(t->e->owner_class && !GET_FLAG(t->e->owner_class, check)) - CHECK_BB(check_class_def(env, t->e->owner_class->e->def)) + CHECK_BB(ensure_check(env, t->e->owner_class)) if(GET_FLAG(t, check))return GW_OK; SET_FLAG(t, check); if(cdef->base.ext) diff --git a/src/parse/scan1.c b/src/parse/scan1.c index c4e6e919..16da2425 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -547,7 +547,7 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) { if(isa(parent, env->gwion->type[et_object]) < 0) ERR_B(pos, _("cannot extend primitive type '%s'"), parent->name) if(parent->e->def && !GET_FLAG(parent, scan1)) - CHECK_BB(scanx_parent(parent, scan1_cdef, env)) + CHECK_BB(ensure_scan1(env, parent)) if(type_ref(parent)) ERR_B(pos, _("can't use ref type in class extend")) if(GET_FLAG(parent, nonnull)) @@ -558,7 +558,7 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) { ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) { if(cdef->base.tmpl && cdef->base.tmpl->list) CHECK_BB(template_push_types(env, cdef->base.tmpl)) - const m_bool ret = scanx_parent(cdef->base.type, scan1_parent, env); + const m_bool ret = scan1_parent(env, cdef); if(cdef->base.tmpl && cdef->base.tmpl->list) nspc_pop_type(env->gwion->mp, env->curr); return ret; diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 3bb0c31e..e927843c 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -550,9 +550,8 @@ HANDLE_SECTION_FUNC(scan2, m_bool, Env) ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) { const Type parent = cdef->base.type->e->parent; -// if(parent->e->def && !GET_FLAG(parent, scan2)) if(parent->e->def && !GET_FLAG(parent, scan2)) - CHECK_BB(scanx_parent(parent, scan2_cdef, env)) + CHECK_BB(ensure_scan2(env, parent)) if(cdef->base.ext->array) CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp)) return GW_OK; @@ -561,7 +560,8 @@ ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) { ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) { if(cdef->base.tmpl && cdef->base.tmpl->list) CHECK_BB(template_push_types(env, cdef->base.tmpl)) - const m_bool ret = scanx_parent(cdef->base.type, scan2_parent, env); +// const m_bool ret = scanx_parent(cdef->base.type, scan2_parent, env); + const m_bool ret = scan2_parent(env, cdef); if(cdef->base.tmpl && cdef->base.tmpl->list) nspc_pop_type(env->gwion->mp, env->curr); return ret; @@ -573,7 +573,7 @@ ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) { const Type t = cdef->base.type; if(GET_FLAG(t, scan2))return GW_OK; if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan2)) - CHECK_BB(scan2_class_def(env, t->e->owner_class->e->def)) + CHECK_BB(ensure_scan2(env, t->e->owner_class)) SET_FLAG(t, scan2); if(cdef->base.ext) CHECK_BB(cdef_parent(env, cdef)) diff --git a/src/parse/template.c b/src/parse/template.c index 932c63a1..ec8b8180 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -116,7 +116,7 @@ ANN Type scan_type(const Env env, const Type t, Type_Decl* td) { struct EnvSet es = { .env=env, .data=env, .scope=env->scope->depth, .flag=ae_flag_none }; envset_push(&es, owner, owner->nspc); - (void)env_push(env, owner, owner->nspc); + (void)env_push(env, owner, owner->nspc);// TODO: is this needed? const Type ret = scan_type(env, t, td->next); env_pop(env, es.scope); if(es.run) diff --git a/src/vm/gack.c b/src/vm/gack.c index 4a63cd07..203dbee3 100644 --- a/src/vm/gack.c +++ b/src/vm/gack.c @@ -53,7 +53,6 @@ ANN static void prepare_call(const VM_Shred shred, const m_uint offset) { *(m_uint*)(shred->mem + SZ_INT*3) = shred->pc; *(m_uint*)(shred->mem + SZ_INT*4) = SZ_INT; shred->mem += SZ_INT*5; - *(M_Object*)(shred->mem) = *(M_Object*)(shred->reg - SZ_INT); shred->pc = 0; } @@ -66,6 +65,10 @@ ANN void gack(const VM_Shred shred, const m_uint offset) { POP_REG(shred, sz); } else { prepare_call(shred, offset); + if(GET_FLAG(t, struct)) + *(void**)(shred->mem) = (void*)(shred->reg - t->size); + else + *(M_Object*)(shred->mem) = *(M_Object*)(shred->reg - SZ_INT); shred->code = code; } return; diff --git a/src/vm/vm.c b/src/vm/vm.c index b4582fcf..887e6d04 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -429,6 +429,7 @@ structmember: *(m_bit**)(reg-SZ_INT) = *(m_bit**)(*(m_bit**)(reg-SZ_INT) + (m_int)VAL); DISPATCH() structmemberfloat: +printf("struct: %p\n", *(m_bit**)(reg-SZ_INT)); *(m_bit**)(reg-SZ_INT) = *(m_bit**)(*(m_bit**)(reg-SZ_INT) + (m_int)VAL); DISPATCH() structmemberother: @@ -466,6 +467,7 @@ allocfloat: reg += SZ_FLOAT; DISPATCH() allocother: +puts("here!!!"); // LOOP_OPTIM for(m_uint i = 0; i <= VAL2; i += SZ_INT) *(m_uint*)(reg+i) = (*(m_uint*)(mem+VAL+i) = 0);