From: fennecdjay Date: Fri, 6 Jan 2023 02:07:31 +0000 (+0100) Subject: On ctor/and/stuff: hahabutbetter X-Git-Tag: nightly~207^2~22 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=af3f07a49d0775f73fd503f859d7af83e92cb772;p=gwion.git On ctor/and/stuff: hahabutbetter --- af3f07a49d0775f73fd503f859d7af83e92cb772 diff --cc include/env/func.h index 7f3a7425,7f3a7425..d0fa0724 --- a/include/env/func.h +++ b/include/env/func.h @@@ -17,6 -17,6 +17,7 @@@ struct Func_ Value value_ref; Func next; m_str name; ++ uint32_t wait; float inline_mult; uint16_t weight; // used to mark gack use in scan1 uint16_t memoize; // used to mark return in scan1 diff --cc include/env/nspc.h index 63e1b8b7,63e1b8b7..e63fc131 --- a/include/env/nspc.h +++ b/include/env/nspc.h @@@ -18,7 -18,7 +18,7 @@@ struct Nspc_ m_str name; NspcInfo *info; uint16_t offset; -- uint16_t ref; ++ uint16_t ref; uint16_t class_data_size; }; diff --cc include/env/type.h index d6cb26f9,d6cb26f9..85165b2f --- a/include/env/type.h +++ b/include/env/type.h @@@ -51,7 -51,7 +51,9 @@@ struct Type_ uint64_t size; uint64_t actual_size; struct Vector_ effects; // pre-ctor effects -- uint32_t array_depth; ++// struct MP_Vector *wait; ++ uint32_t wait; ++ uint32_t array_depth; uint16_t ref; uint16_t weight; ae_flag flag; diff --cc include/env/value.h index 1e89694f,1e89694f..67d24b39 --- a/include/env/value.h +++ b/include/env/value.h @@@ -34,6 -34,6 +34,7 @@@ struct Value_ Type type; m_str name; ValueFrom *from; ++ MP_Vector *used_by; // list of functions using this global union value_data d; uint16_t ref; ae_flag flag; diff --cc include/vm.h index 6ef06b77,6ef06b77..395c7378 --- a/include/vm.h +++ b/include/vm.h @@@ -18,6 -18,6 +18,7 @@@ struct VM_Code_ m_str name; struct Map_ handlers; struct M_Vector_ live_values; ++ uint32_t wait; uint16_t stack_depth; uint16_t ref; // bool is_prepared; diff --cc src/emit/emit.c index 7838adcd,7838adcd..100c6514 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@@ -223,6 -223,6 +223,7 @@@ ANEW static Code *new_code(const Emitte } ANN static void free_code(MemPool p, Code *code) { ++// we should use instr destructors if(code->instr.ptr) vector_release(&code->instr); vector_release(&code->stack_break); vector_release(&code->stack_cont); @@@ -438,7 -438,7 +439,8 @@@ m_bool emit_instantiate_object(const Em is_ref)); return GW_OK; } else if (!is_ref) { -- if(!tflag(type, tflag_typedef) || isa(type, emit->gwion->type[et_closure]) > 0) { ++ if(!tflag(type, tflag_typedef) || isa(type, emit->gwion->type[et_closure]) > 0 || ++ tflag(type, tflag_union)) { const Instr instr = emit_add_instr(emit, ObjectInstantiate); instr->m_val2 = (m_uint)type; } // maybe we should instantiate the first actual type @@@ -474,6 -474,6 +476,12 @@@ ANN static m_bool emit_symbol_builtin(c ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) { const Value v = prim_self(data)->value; ++ ++//else ++if(emit->env->class_def && safe_vflag(v, vflag_fglobal) && !emit->env->scope->depth) { ++emit->env->class_def->wait--; ++printf("=> %s\n", s_name(*data)); ++ } if (is_class(emit->gwion, v->type)) { emit_pushimm(emit, (m_uint)actual_type(emit->gwion, v->type)); return GW_OK; @@@ -529,6 -529,6 +537,12 @@@ ANN static VM_Code finalyze(const Emitt return code; } ++ANN static VM_Code finalyze_func(const Emitter emit, const f_instr exec, const Func f) { ++ const VM_Code code = finalyze(emit, exec); ++ code->wait = f->wait; ++ return code; ++} ++ ANN static inline m_uint exp_size(const Exp e) { if (exp_getvar(e)) return SZ_INT; const Type type = e->cast_to ?: e->type; @@@ -806,6 -806,6 +820,7 @@@ ANN static void emit_gack_type(const Em ANN /*static*/ m_bool emit_interp(const Emitter emit, const Exp exp) { emit_pushimm(emit, 0); ++ emit_local(emit, emit->gwion->type[et_int]); Exp e = exp, next = NULL; do { next = e->next; @@@ -876,6 -876,6 +891,7 @@@ ANN static m_bool emit_prim_locale(cons vm_run(emit->gwion->vm); emit->gwion->vm->bbq->is_running = true; const m_float ret = *(m_float*)shred->reg; ++ release(shred->info->me, shred); if(ret == -1.0) ERR_B(prim_pos(id), "error in locale"); const Instr instr = emit_add_instr(emit, RegPushImm2); @@@ -994,6 -994,6 +1010,14 @@@ ANN void unset_local(const Emitter emit } } ++static INSTR(UsedBy) { ++ const MP_Vector *v =(MP_Vector*)instr->m_val; ++ for(uint32_t i = 0; i < v->len; i++) { ++ const Func f = *mp_vector_at(v, Func, i); ++ f->code->wait--; ++ } ++} ++ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *decl, const Var_Decl *var_decl, @@@ -1011,6 -1011,6 +1035,10 @@@ f_instr *exec = (f_instr *)allocmember; if (!emit->env->scope->depth) emit_debug(emit, v); if (!vflag(v, vflag_member)) { ++if(v->used_by) { // maybe later ++ const Instr instr = emit_add_instr(emit, UsedBy); ++ instr->m_val = (m_uint)v->used_by; ++} v->from->offset = decl_non_static_offset(emit, decl, type); exec = (f_instr *)(allocword); if (GET_FLAG(v, late)) { // ref or emit_var ? @@@ -1051,7 -1051,7 +1079,7 @@@ ANN static m_bool emit_exp_decl_global( if (type->size > SZ_INT) v->d.ptr = mp_calloc2(emit->gwion->mp, v->type->size); emit_dotstatic(emit, (m_uint)&v->d.ptr, v->type->size, !struct_ctor(v) ? emit_addr : 1); -- set_vflag(v, vflag_direct); // mpalloc ++// set_vflag(v, vflag_direct); // mpalloc // set in check.c if (is_obj && !is_ref) { const Instr assign = emit_add_instr(emit, Assign); assign->m_val = emit_var; @@@ -1122,13 -1122,13 +1150,15 @@@ ANN /*static */ m_bool emit_exp_decl(co const Type t = decl->type; if(decl->args && !strncmp(decl->args->type->name, "partial:", 8)) ERR_B(decl->args->pos, "unresolved partial"); ++// if(t->wait) exit(3); ++ if(t->wait) { puts(t->name); puts(decl->vd.value->name); /*exit(3); */} CHECK_BB(ensure_emit(emit, t)); const m_bool global = GET_FLAG(decl->td, global); const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit); const m_bool ret = emit_decl(emit, decl); if (global) emit_pop(emit, scope); -- if(isa(t, emit->gwion->type[et_object]) > 0 && emit->status.in_return && GET_FLAG(decl->vd.value, late)) ++ if(emit->status.in_return && GET_FLAG(decl->vd.value, late) && isa(t, emit->gwion->type[et_object]) > 0) emit_add_instr(emit, GWOP_EXCEPT); return ret; } @@@ -1329,7 -1329,7 +1359,6 @@@ ANN static m_bool _emit_exp_call(const .pos = exp_self(call)->pos}; CHECK_BB(op_emit(emit, &opi)); } -- const Func f = t->info->func; if(unlikely(is_new_struct(f, exp_self(call)->type))) emit_new_struct(emit, call); @@@ -1388,9 -1388,9 +1417,6 @@@ ANN static m_bool emit_exp_binary(cons const Exp rhs = bin->rhs; CHECK_BB(emit_exp_pop_next(emit, lhs)); CHECK_BB(emit_exp_pop_next(emit, rhs)); -- // const m_int size = exp_size(rhs); -- // emit_exp_addref1(emit, lhs, -exp_size(lhs) - size); -- // emit_exp_addref1(emit, rhs, -size); struct Op_Import opi = {.op = bin->op, .lhs = lhs->type, .rhs = rhs->type, @@@ -1623,7 -1623,7 +1649,14 @@@ ANN m_bool emit_exp_call1(const Emitte if(unlikely(fflag(f, fflag_fptr))) emit_fptr_call(emit, f); else if (unlikely(!f->code && emit->env->func != f)) { if (fflag(f, fflag_tmpl)) CHECK_BB(emit_template_code(emit, f)); -- else CHECK_BB(emit_ensure_func(emit, f)); ++ else //if(is_new(f->def))//if(tflag(f->value_ref->type, tflag_ftmpl)) ++{ ++const Type t = f->value_ref->from->owner_class; ++if(t && (!emit->env->curr || isa(t, emit->env->class_def) < 0)) ++//!is_new(f->def) || f->value_ref->from->owner_class->array_depth) ++//if(f->value_ref->from->owner_class->array_depth) ++CHECK_BB(emit_ensure_func(emit, f)); ++} } else if(is_static) push_func_code(emit, f); call_finish(emit, f, is_static); @@@ -2672,18 -2672,18 +2705,19 @@@ ANN static m_bool emit_func_def_return( } ANN static VM_Code emit_internal(const Emitter emit, const Func f) { ++// use wait everywhere if (f->def->base->xid == insert_symbol("@dtor")) { -- emit->env->class_def->nspc->dtor = f->code = finalyze(emit, DTOR_EOC); ++ emit->env->class_def->nspc->dtor = f->code = finalyze_func(emit, DTOR_EOC, f); vmcode_addref(f->code); return f->code; } else if (f->def->base->xid == insert_symbol("@gack")) { emit_regmove(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); ++ f->code = finalyze_func(emit, FuncReturn, f); return emit->env->class_def->info->gack = f->code; } -- return finalyze(emit, FuncReturn); ++ return finalyze_func(emit, FuncReturn, f); } ANN static inline VM_Code _emit_func_def_code(const Emitter emit, @@@ -2697,8 -2697,8 +2731,12 @@@ instr->m_val2 = t->size; } } -- return !fbflag(func->def->base, fbflag_internal) ? finalyze(emit, FuncReturn) ++// return !fbflag(func->def->base, fbflag_internal) ? finalyze(emit, FuncReturn) ++// : emit_internal(emit, func); ++ const VM_Code code = !fbflag(func->def->base, fbflag_internal) ? finalyze_func(emit, FuncReturn, func) : emit_internal(emit, func); ++ code->wait = func->wait; ++ return code; } ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) { diff --cc src/env/value.c index 0c06360d,0c06360d..e5b96913 --- a/src/env/value.c +++ b/src/env/value.c @@@ -10,6 -10,6 +10,7 @@@ ANN void free_value(Value a, Gwion gwio _mp_free(gwion->mp, t->size, a->d.ptr); else if (is_class(gwion, t)) type_remref(t, gwion); ++ if(a->used_by) free_mp_vector(gwion->mp, Func, a->used_by); mp_free(gwion->mp, ValueFrom, a->from); mp_free(gwion->mp, Value, a); } diff --cc src/lib/closure.c index b747f0a3,b747f0a3..ed4b4e98 --- a/src/lib/closure.c +++ b/src/lib/closure.c @@@ -51,9 -51,9 +51,9 @@@ ANN static Exp uncurry(const Env env, c } ANN static Type mk_call(const Env env, const Exp e, const Exp func, const Exp args) { -- Exp_Call call = {.func = func, .args = args }; -- e->exp_type = ae_exp_call; -- memcpy(&e->d.exp_call, &call, sizeof(Exp_Call)); ++ Exp_Call call = {.func = func, .args = args }; ++ e->exp_type = ae_exp_call; ++ e->d.exp_call = call; return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error]; } diff --cc src/lib/lib_class.c index 6aa7df5a,6aa7df5a..2def08a0 --- a/src/lib/lib_class.c +++ b/src/lib/lib_class.c @@@ -37,20 -37,20 +37,21 @@@ static OP_CHECK(opck_basic_ctor) // change to *no know constructor for {+G}%s{0}*? ERR_N(call->func->pos, _("can't call a non-callable value")); } -- ++/* static OP_EMIT(opem_implicit_class) { struct Implicit *imp = (struct Implicit*)data; const Type t = actual_type(emit->gwion, imp->e->type); emit_pushimm(emit, map_size(&t->nspc->info->value->map)); -- return GW_OK; emit_exp(emit, imp->e); ++ return GW_OK; } static OP_CHECK(opck_implicit_class) { struct Implicit *imp = (struct Implicit*)data; const Type t = actual_type(env->gwion, imp->e->type); ++ if(isa(t, env->gwion->type[et_enum]) > 0) return imp->e->type; return env->gwion->type[et_error]; } -- ++*/ GWION_IMPORT(class) { gwidoc(gwi, "Operators class types."); @@@ -71,12 -71,12 +72,12 @@@ GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL)) GWI_BB(gwi_oper_add(gwi, opck_basic_ctor)) GWI_BB(gwi_oper_end(gwi, "@ctor", NULL)) -- ++/* gwidoc(gwi, "Allow enum for array size"); GWI_BB(gwi_oper_ini(gwi, "Class", "int", NULL)) GWI_BB(gwi_oper_add(gwi, opck_implicit_class)) GWI_BB(gwi_oper_emi(gwi, opem_implicit_class)) GWI_BB(gwi_oper_end(gwi, "@implicit", NULL)) -- ++*/ return GW_OK; } diff --cc src/lib/ref.c index 6f75b68d,6f75b68d..521822b8 --- a/src/lib/ref.c +++ b/src/lib/ref.c @@@ -93,8 -93,8 +93,7 @@@ static OP_EMIT(opem_ref_contract_simila emit_regmove(emit, -imp->e->type->size); exp_setvar(imp->e, true); imp->e->cast_to = NULL; -- emit_exp(emit, imp->e); -- return GW_OK; ++ return emit_exp(emit, imp->e); } ANN static void base2ref(Env env, const Type lhs, const Type rhs) { diff --cc src/parse/check.c index 6089c281,6089c281..90c76eda --- a/src/parse/check.c +++ b/src/parse/check.c @@@ -304,9 -304,9 +304,13 @@@ ANN static Value check_non_res_value(co const Symbol var = *data; const Value value = get_value(env, var); if (env->class_def) { -- if (value && value->from->owner_class) -- CHECK_BO( -- not_from_owner_class(env, env->class_def, value, prim_pos(data))); ++ if (value) { ++ if(value->from->owner_class) ++ CHECK_BO(not_from_owner_class(env, ++ env->class_def, value, prim_pos(data))); ++ else if(safe_vflag(value, vflag_fglobal) && !env->scope->depth) ++ env->class_def->wait++; ++ } const Value v = value ?: find_value(env->class_def, var); if (v) { if (env->func && GET_FLAG(env->func->def->base, static) && @@@ -388,7 -388,7 +392,29 @@@ ANN static Type prim_id_non_res(const E prim_self(data)->value = v; if (v->from->owner_class) return prim_owned(env, data); if (GET_FLAG(v, const)) exp_setmeta(prim_exp(data), 1); -- if (env->func) { ++ ++ if (env->func && strcmp(env->func->name, "in spork")) { ++ if(vflag(v, vflag_fglobal) /*&& !vflag(v, vflag_builtin) */&& !is_func(env->gwion, v->type)) { ++ if (!v->used_by) { ++ v->used_by = new_mp_vector(env->gwion->mp, Func, 1); ++ mp_vector_set(v->used_by, Func, 0, env->func); ++ env->func->wait++; ++ } else { ++ bool found = false; ++ for(uint32_t i = 0; i < v->used_by->len; i++) { ++ const Func f = *mp_vector_at(v->used_by, Func, i); ++ if(f == env->func) { ++ found = true; ++ break; ++ } ++ } ++ if(!found) { ++ env->func->wait++; ++ mp_vector_add(env->gwion->mp, &v->used_by, Func, env->func); ++ } ++ } ++ } ++ if (!GET_FLAG(v, const) && v->from->owner) unset_fflag(env->func, fflag_pure); if (fbflag(env->func->def->base, fbflag_lambda)) @@@ -886,7 -886,7 +912,8 @@@ ANN m_bool func_check(const Env env, Ex .rhs = t, .pos = e->pos, .data = (uintptr_t)e}; -- CHECK_NB(op_check(env, &opi)); // doesn't really return NULL ++ if(op_get(env, &opi)) ++ CHECK_OB(op_check(env, &opi)); if (e->exp_type != ae_exp_call) return 0; return e->type != env->gwion->type[et_error] ? GW_OK : GW_ERROR; } diff --cc src/parse/operator.c index d6c21521,d6c21521..23e9db12 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@@ -305,6 -305,6 +305,12 @@@ ANN static Type chuck_rewrite(const En char c[len - 1]; strncpy(c, op, len - 2); c[len - 2] = '\0'; ++ // are there other expressions that would need such a test? ++ if(!strcmp(c, "$")) { ++ env_err(env, opi->pos, "can't rewrite cast operations"); ++ env_set_error(env, true); ++ return NULL; ++ } const Exp bin = new_exp_binary(env->gwion->mp, lhs, insert_symbol(env->gwion->st, c), call, exp_self(base)->pos); base->lhs = bin; base->op = insert_symbol(env->gwion->st, "=>"); diff --cc src/parse/scan1.c index a537a7da,a537a7da..4f6602ff --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@@ -37,17 -37,17 +37,15 @@@ ANN static m_bool check_global(const En const ValueFrom *from = t->info->value->from; if(from->owner_class && isa(from->owner_class, env->class_def) > 0) return true; -- if(!GET_FLAG(t, global) && !from_global_nspc(env, from->owner)) { -- if(from->owner_class && type_global(env, from->owner_class)) ++ if(from_global_nspc(env, from->owner) || ++ (from->owner_class && type_global(env, from->owner_class))) return true; -- gwerr_basic("can't use non-global type in a global class", NULL, NULL, env->name, pos, 0); -- gwerr_secondary_from("not declared global", from); -- const ValueFrom *ownerFrom = env->class_def->info->value->from; -- gwerr_secondary_from("is global", ownerFrom); -- env_set_error(env, true); -- return false; -- } -- return true; ++ gwerr_basic("can't use non-global type in a global class", NULL, NULL, env->name, pos, 0); ++ gwerr_secondary_from("not declared global", from); ++ const ValueFrom *ownerFrom = env->class_def->info->value->from; ++ gwerr_secondary_from("is global", ownerFrom); ++ env_set_error(env, true); ++ return false; } ANN static Type scan1_type(const Env env, Type_Decl *td) { @@@ -81,10 -81,10 +79,11 @@@ ANN static Type scan1_exp_decl_type(con static inline m_bool scan1_defined(const Env env, const Var_Decl *var) { if (var->value) // from an auto declaration return GW_OK; -- if (((!env->class_def || !GET_FLAG(env->class_def, final) || ++ const Value v = ((!env->class_def || !GET_FLAG(env->class_def, final) || env->scope->depth) ? nspc_lookup_value1 -- : nspc_lookup_value2)(env->curr, var->xid)) ++ : nspc_lookup_value2)(env->curr, var->xid); ++ if(v && (!v->from->owner_class || isa(env->class_def, v->from->owner_class) > 0)) ERR_B(var->pos, _("variable %s has already been defined in the same scope..."), s_name(var->xid)) diff --cc src/vm/vm.c index e3c5c3e3,e3c5c3e3..0df19eff --- a/src/vm/vm.c +++ b/src/vm/vm.c @@@ -912,6 -912,6 +912,11 @@@ vm_prepare(const VM *vm, m_bit *prepare DISPATCH(); setcode: a.code = *(VM_Code *)(reg - SZ_INT); ++if(a.code->wait) { ++handle(shred, "FuncWithGlobalUninit"); ++break; ++} ++ if (!a.code->builtin) { register const uint push = *(m_uint *)reg /*+ code->stack_depth*/ + sizeof(frame_t);