From 612b12e829f6f8cba1532bcb4d63864561e3e9f2 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Mon, 9 Jan 2023 14:53:47 +0100 Subject: [PATCH] :art: pre_ctor is now a function --- compile_flags.txt | 4 ++ include/env/func.h | 9 ++-- include/env/type.h | 4 +- include/instr.h | 1 + include/parse.h | 1 + include/vm.h | 3 +- src/emit/emit.c | 91 +++++++++++++++++++------------------ src/env/func.c | 1 + src/env/type.c | 1 - src/gwion.c | 13 ++++-- src/import/import_cdef.c | 26 +++++++---- src/lib/closure.c | 2 +- src/lib/dict.c | 8 ++-- src/lib/instr.c | 15 +++++++ src/lib/object.c | 2 +- src/parse/check.c | 96 +++++++++++++++++++++------------------- src/parse/scan1.c | 50 +++++++++++++++++++-- src/parse/scan2.c | 13 ++++-- src/vm/vm.c | 9 ++-- util | 2 +- 20 files changed, 221 insertions(+), 130 deletions(-) create mode 100644 compile_flags.txt diff --git a/compile_flags.txt b/compile_flags.txt new file mode 100644 index 00000000..9998e440 --- /dev/null +++ b/compile_flags.txt @@ -0,0 +1,4 @@ +-Iutil/include +-Iast/include +-Iinclude +-Ifmt/include diff --git a/include/env/func.h b/include/env/func.h index d0fa0724..4c45038e 100644 --- a/include/env/func.h +++ b/include/env/func.h @@ -17,12 +17,11 @@ struct Func_ { Value value_ref; Func next; m_str name; - uint32_t wait; + MP_Vector *_wait; float inline_mult; uint16_t weight; // used to mark gack use in scan1 uint16_t memoize; // used to mark return in scan1 uint16_t ref; -// uint16_t vt_index; ae_flag flag; enum fflag fflag; }; @@ -45,7 +44,11 @@ ANN static inline Value upvalues_lookup(const Upvalues *upvalues, const Symbol s } ANN static inline m_uint captures_sz(const Capture_List captures) { - const Capture *cap = mp_vector_at(captures, Capture, (captures->len - 1)); + const Capture *cap = mp_vector_back(captures, Capture); return cap->temp->from->offset + cap->temp->type->size; } + +ANN static inline bool is_ctor(const Func_Def fdef) { + return !strcmp(s_name(fdef->base->xid), "@ctor"); +} #endif diff --git a/include/env/type.h b/include/env/type.h index 85165b2f..6a1a6bba 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -50,9 +50,7 @@ struct Type_ { struct TypeInfo_ *info; uint64_t size; uint64_t actual_size; - struct Vector_ effects; // pre-ctor effects -// struct MP_Vector *wait; - uint32_t wait; +// struct Vector_ effects; // pre-ctor effects uint32_t array_depth; uint16_t ref; uint16_t weight; diff --git a/include/instr.h b/include/instr.h index 4217a4b6..72e733b5 100644 --- a/include/instr.h +++ b/include/instr.h @@ -69,6 +69,7 @@ ANN m_bool traverse_dot_tmpl(const Emitter emit, const Func_Def fdef, const Valu INSTR(SetFunc); INSTR(SetCtor); +INSTR(FuncWait); #include "opcode.h" INSTR(dict_ctor_alt); diff --git a/include/parse.h b/include/parse.h index f2c96926..b0b75621 100644 --- a/include/parse.h +++ b/include/parse.h @@ -117,6 +117,7 @@ static inline bool exp_is_zero(const Exp exp) { } ANN static inline bool not_upvalue(const Env env, const Value v) { + if (unlikely(is_class(env->gwion, v->type))) return true; return GET_FLAG(v, global) || vflag(v, vflag_fglobal) || (v->from->owner_class && isa(v->from->owner_class, env->class_def) > 0) || nspc_lookup_value1(env->curr, insert_symbol(v->name)); diff --git a/include/vm.h b/include/vm.h index 395c7378..c1a7597a 100644 --- a/include/vm.h +++ b/include/vm.h @@ -18,7 +18,6 @@ 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; @@ -136,7 +135,7 @@ ANN m_str code_name_set(MemPool p, const m_str, const m_str); ANN m_str code_name(const m_str, const bool); ANN uint32_t gw_rand(uint32_t s[2]); ANN void gw_seed(uint32_t s[2], const uint64_t); -ANN void handle(VM_Shred shred, const m_str effect); +ANN bool handle(VM_Shred shred, const m_str effect); #define xfun_handle(shred, effect) {\ shred->mem -= ((Instr)vector_at(&shred->code->instr, shred->pc-1))->m_val2; \ handle(shred, effect); \ diff --git a/src/emit/emit.c b/src/emit/emit.c index 406ab71b..9ec0bad7 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -122,7 +122,7 @@ ANN /*static */ m_bool emit_cdef(const Emitter, const Type); ANN /*static inline*/ m_bool ensure_emit(const Emitter emit, const Type t) { if (tflag(t, tflag_emit) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef))) return GW_OK; // clean callers -if(!tflag(t, tflag_tmpl))return GW_OK; + if(!tflag(t, tflag_tmpl))return GW_OK; struct EnvSet es = {.env = emit->env, .data = emit, .func = (_exp_func)emit_cdef, @@ -416,7 +416,7 @@ ANN void emit_ext_ctor(const Emitter emit, const Type t) { } const m_uint offset = emit_code_offset(emit); emit_setimm(emit, offset, SZ_INT*2); - emit_regmove(emit, SZ_INT * 2); + emit_regmove(emit, SZ_INT*2); const Instr prelude = emit_add_instr(emit, SetCode); prelude->m_val = -SZ_INT * 2; prelude->udata.one = 2; @@ -531,11 +531,6 @@ ANN static VM_Code finalyze(const Emitter emit, const f_instr exec) { 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); - 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; @@ -928,8 +923,7 @@ ANN static m_bool decl_static(const Emitter emit, const Exp_Decl *decl, } ANN static inline int struct_ctor(const Value v) { - return tflag(v->type, tflag_struct) && v->type->nspc && v->type->nspc->pre_ctor; -// return tflag(v->type, tflag_struct) && v->type->nspc->pre_ctor; + return tflag(v->type, tflag_struct) && tflag(v->type, tflag_ctor); } ANN static void decl_expand(const Emitter emit, const Type t) { @@ -952,7 +946,7 @@ ANN static m_bool struct_finish(const Emitter emit, const Exp_Decl *decl) { CHECK_BB(emit_exp(emit, decl->args)); if (emit_addr) { emit_regmove(emit, -t->size); - emit_regpushmem4(emit, 0, 0); + emit_regpushmem4(emit, decl->vd.value->from->offset, 0); } return GW_OK; } @@ -1008,10 +1002,24 @@ 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--; + const Instr instr = (Instr)vector_front(&f->code->instr); + instr->m_val2++; } } +ANN static void used_by(const Emitter emit, const Value v) { + MP_Vector *vec = new_mp_vector(emit->gwion->mp, Func, 0); + for(uint32_t i = 0; i < v->used_by->len; i++) { + const Func f = *mp_vector_at(v->used_by, Func, i); + if(f->_wait) mp_vector_add(emit->gwion->mp, &vec, Func, f); + } + free_mp_vector(emit->gwion->mp, Func, v->used_by); + v->used_by = vec; + if(vec->len) { + const Instr instr = emit_add_instr(emit, UsedBy); + instr->m_val = (m_uint)vec; + } +} ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *decl, const Var_Decl *var_decl, @@ -1022,17 +1030,13 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const bool is_obj = isa(type, emit->gwion->type[et_object]) > 0; const bool emit_addr = (!is_obj || is_ref) ? emit_var : true; if (is_obj && !is_ref && !exp_self(decl)->ref) { -// if (is_obj && ((is_array && !exp_self(decl)->ref) || !is_ref)) if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->td, is_ref)); else CHECK_BB(emit_exp(emit, decl->args)); } 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; -} + if(v->used_by) used_by(emit, v); v->from->offset = decl_non_static_offset(emit, decl, type); exec = (f_instr *)(allocword); if (GET_FLAG(v, late)) { // ref or emit_var ? @@ -1052,8 +1056,8 @@ if(v->used_by) { // maybe later const Instr instr = emit_add_instr(emit, Reg2Reg); instr->m_val = -SZ_INT; } - if(safe_tflag(emit->env->class_def, tflag_struct) && GET_FLAG(emit->env->class_def, global)) - emit_object_addref(emit, 0, emit_addr); +// if(safe_tflag(emit->env->class_def, tflag_struct) && GET_FLAG(emit->env->class_def, global)) +// emit_object_addref(emit, 0, emit_addr); } else if (tflag(v->type, tflag_struct)) CHECK_BB(struct_finish(emit, decl)); return GW_OK; @@ -1074,6 +1078,7 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl, 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 in check.c + if(v->used_by) used_by(emit, v); if (is_obj && !is_ref) { const Instr assign = emit_add_instr(emit, Assign); assign->m_val = emit_var; @@ -1144,8 +1149,6 @@ ANN /*static */ m_bool emit_exp_decl(const Emitter emit, Exp_Decl *const decl) { 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 = @@ -1320,7 +1323,7 @@ ANN static m_bool emit_new_struct(const Emitter emit,const Exp_Call *call) { else if(tflag(t, tflag_ctor)) emit_regpushmem4(emit, offset, 0); if(tflag(t, tflag_ctor)) emit_ext_ctor(emit, t); - else if(!back) { + else if(!back) { emit_regmove(emit, -SZ_INT + t->size); emit_regpushmem4(emit, offset, 0); } @@ -2672,6 +2675,10 @@ ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot *member) { ANN static inline void emit_func_def_init(const Emitter emit, const Func func) { emit_push_code(emit, func->name); + if(mp_vector_len(func->_wait)) { + const Instr instr = emit_add_instr(emit, FuncWait); + instr->m_val = (m_uint) func; + } } ANN static void emit_func_def_args(const Emitter emit, Arg_List args) { @@ -2699,19 +2706,16 @@ ANN static m_bool emit_func_def_return(const Emitter emit) { } 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_func(emit, DTOR_EOC, f); - vmcode_addref(f->code); - return f->code; - } else if (f->def->base->xid == insert_symbol("@gack")) { + if (f->def->base->xid == insert_symbol("@dtor")) + return emit->env->class_def->nspc->dtor = finalyze(emit, DTOR_EOC); + 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_func(emit, FuncReturn, f); + f->code = finalyze(emit, FuncReturn); return emit->env->class_def->info->gack = f->code; } - return finalyze_func(emit, FuncReturn, f); + return finalyze(emit, FuncReturn); } ANN static inline VM_Code _emit_func_def_code(const Emitter emit, @@ -2725,11 +2729,10 @@ ANN static inline VM_Code _emit_func_def_code(const Emitter emit, instr->m_val2 = t->size; } } -// 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) + const VM_Code code = !fbflag(func->def->base, fbflag_internal) ? finalyze(emit, FuncReturn) : emit_internal(emit, func); - code->wait = func->wait; + if(is_ctor(func->def) && !emit->env->class_def->nspc->pre_ctor) + emit->env->class_def->nspc->pre_ctor = code; return code; } @@ -2745,9 +2748,12 @@ ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) { if (fdef->base->args) emit_func_def_args(emit, fdef->base->args); if (fdef->d.code) { if(!fdef->builtin) { - scoped_ini(emit); + const bool ctor = is_ctor(fdef); + if(!ctor) + scoped_ini(emit); const m_bool ret = emit_stmt_list(emit, fdef->d.code); - scoped_end(emit); + if(!ctor) + scoped_end(emit); CHECK_BB(ret); } else fdef->base->func->code = (VM_Code)vector_at(&fdef->base->func->value_ref->from->owner_class->nspc->vtable, fdef->vt_index); @@ -2850,6 +2856,8 @@ ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) { if(fdef->builtin) { fdef->base->func->code = new_vmcode(emit->gwion->mp, NULL, NULL, func->name, fdef->stack_depth, true, false); fdef->base->func->code->native_func = (m_uint)fdef->d.dl_func_ptr; + if(is_ctor(fdef)) + emit->env->class_def->nspc->pre_ctor = fdef->base->func->code; return GW_OK; } if ((vflag(func->value_ref, vflag_builtin) && @@ -2941,17 +2949,8 @@ ANN static m_bool _emit_class_def(const Emitter emit, const Class_Def cdef) { if (c->base.ext && t->info->parent->info->cdef && !tflag(t->info->parent, tflag_emit)) // ????? CHECK_BB(cdef_parent(emit, c)); - if (c->body) { - emit_class_code(emit, t->name); - const m_bool ret = scanx_body(emit->env, c, (_exp_func)emit_section, emit); - if (ret > 0 && tflag(t, tflag_ctor)) - t->nspc->pre_ctor = finalyze(emit, FuncReturn); - else{ - free_code(emit->gwion->mp, emit->code); - emit_pop_code(emit); - } - return ret; - } + if (c->body) + return scanx_body(emit->env, c, (_exp_func)emit_section, emit); return GW_OK; } diff --git a/src/env/func.c b/src/env/func.c index 6e550e9d..4a17896e 100644 --- a/src/env/func.c +++ b/src/env/func.c @@ -8,6 +8,7 @@ ANN void free_func(Func a, Gwion gwion) { if (fflag(a, fflag_tmpl)) func_def_cleaner(gwion, a->def); if (a->code) vmcode_remref(a->code, gwion); + if (a->_wait) free_mp_vector(gwion->mp, Value, a->_wait); mp_free(gwion->mp, Func, a); } diff --git a/src/env/type.c b/src/env/type.c index fd1d8922..575e32a2 100644 --- a/src/env/type.c +++ b/src/env/type.c @@ -24,7 +24,6 @@ ANN void free_type(const Type a, struct Gwion_ *const gwion) { } // if (tflag(a, tflag_cdef) && a->info->parent) // type_remref(a->info->parent, gwion); - if (a->effects.ptr) vector_release(&a->effects); if (a->nspc) nspc_remref(a->nspc, gwion); if (a->info->tuple) free_tupleform(a->info->tuple, gwion); mp_free(gwion->mp, TypeInfo, a->info); diff --git a/src/gwion.c b/src/gwion.c index f01ae9c7..30db071f 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -175,10 +175,17 @@ ANN void gwion_end(const Gwion gwion) { } ANN void env_error_footer(const Env env) { - if (env->class_def && tflag(env->class_def, tflag_cdef)) + bool ctor = false; + if (env->func && env->func->def) { + if(!is_ctor(env->func->def)) + gwerr_secondary("in function", env->name, env->func->def->base->pos); + else { + gwerr_secondary("in class pre constructor", env->name, env->class_def->info->cdef->pos); + ctor = true; + } + } + if (!ctor && env->class_def && tflag(env->class_def, tflag_cdef)) gwerr_secondary("in class", env->name, env->class_def->info->cdef->pos); - if (env->func && env->func->def) - gwerr_secondary("in function", env->name, env->func->def->base->pos); } ANN static void env_xxx(const Env env, const loc_t pos, const m_str fmt, diff --git a/src/import/import_cdef.c b/src/import/import_cdef.c index 47c680b7..61140ef6 100644 --- a/src/import/import_cdef.c +++ b/src/import/import_cdef.c @@ -17,13 +17,10 @@ #include "specialid.h" #include "template.h" -ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, - const enum tflag e) { - VM_Code *code = e == tflag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor; - const m_str name = type->name; - *code = new_vmcode(p, NULL, NULL, name, SZ_INT, true, false); - (*code)->native_func = (m_uint)d; - type->tflag |= e; +ANN static m_bool mk_dtor(MemPool p, const Type t, const m_uint d) { + VM_Code code = t->nspc->dtor = new_vmcode(p, NULL, NULL, t->name, SZ_INT, true, false); + code->native_func = (m_uint)d; + set_tflag(t, tflag_dtor); return GW_OK; } @@ -46,8 +43,16 @@ ANN2(1) void add_template(const Env env, const Type t) { ANN2(1) void gwi_class_xtor(const Gwi gwi, const f_xtor ctor, const f_xtor dtor) { const Type t = gwi->gwion->env->class_def; - if (ctor) mk_xtor(gwi->gwion->mp, t, (m_uint)ctor, tflag_ctor); - if (dtor) mk_xtor(gwi->gwion->mp, t, (m_uint)dtor, tflag_dtor); + if (dtor) mk_dtor(gwi->gwion->mp, t, (m_uint)dtor); + if (ctor) { + gwi_func_ini(gwi, "void", "@ctor"); + gwi_func_end(gwi, ctor, ae_flag_none); + if(t->nspc->vtable.ptr) { + set_tflag(t, tflag_ctor); + const Func f = (Func)vector_front(&t->nspc->vtable); + t->nspc->pre_ctor = f->code; + } + } } ANN static inline void gwi_type_flag(const Type t) { @@ -141,11 +146,14 @@ ANN m_int gwi_class_end(const Gwi gwi) { --gwi->tmpls; nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr); } +/* +// we need to use @ctor if (gwi->effects.ptr) { vector_init(&t->effects); vector_copy2(&gwi->effects, &t->effects); vector_release(&gwi->effects); } +*/ env_pop(gwi->gwion->env, 0); return GW_OK; } diff --git a/src/lib/closure.c b/src/lib/closure.c index ed4b4e98..bf880f0d 100644 --- a/src/lib/closure.c +++ b/src/lib/closure.c @@ -687,7 +687,7 @@ static OP_CHECK(opck_closure_scan) { } static CTOR(fptr_ctor) { - *(VM_Code*)o->data = ((Func)vector_front(&o->type_ref->nspc->vtable))->code; + *(VM_Code*)o->data = ((Func)vector_at(&o->type_ref->nspc->vtable, 1))->code; } ANN m_bool tmpl_fptr(const Env env, const Fptr_Def fptr, const Func_Def fdef) { diff --git a/src/lib/dict.c b/src/lib/dict.c index 8418def8..b92a8fb2 100644 --- a/src/lib/dict.c +++ b/src/lib/dict.c @@ -357,7 +357,7 @@ static OP_CHECK(opck_dict_remove_toop) { HMapInfo *const hinfo = (HMapInfo*)t->nspc->class_data; if(isa(args->type, hinfo->key) < 0 || args->next) ERR_N(e->pos, "dict.remove must be called with one Key argument"); - return e->type = hinfo->val; + return e->type = env->gwion->type[et_void]; } ANN static m_bool emit_dict_iter(const Emitter emit, const HMapInfo *hinfo, @@ -640,6 +640,7 @@ static OP_CHECK(opck_dict_scan) { const Type t = cdef->base.type; t->nspc->class_data_size = sizeof(struct HMapInfo); const m_bool ret = traverse_cdef(env, t); + set_tflag(t, tflag_cdef); if(is_global) { env_pop(env, scope); type_addref(t); @@ -659,7 +660,7 @@ static OP_CHECK(opck_dict_scan) { add_op(env->gwion, &opi); { - const Func f = (Func)vector_front(&t->nspc->vtable); + const Func f = (Func)vector_at(&t->nspc->vtable, 1); const struct Op_Func opfunc = {.ck = opck_dict_remove_toop}; const struct Op_Import opi = { .rhs = f->value_ref->type, @@ -669,7 +670,6 @@ static OP_CHECK(opck_dict_scan) { CHECK_BN(add_op(env->gwion, &opi)); } - return ret > 0 ? t : NULL; } @@ -679,7 +679,7 @@ GWION_IMPORT(dict) { t_dict->nspc->offset += sizeof(struct HMap); gwi->gwion->type[et_dict] = t_dict; set_tflag(t_dict, tflag_infer); - GWI_BB(gwi_func_ini(gwi, "bool", "remove")); + GWI_BB(gwi_func_ini(gwi, "void", "remove")); GWI_BB(gwi_func_arg(gwi, "Key", "key")); GWI_BB(gwi_func_end(gwi, (f_xfun)1, ae_flag_none)); diff --git a/src/lib/instr.c b/src/lib/instr.c index 2cea5b4b..97162dd9 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -141,6 +141,21 @@ INSTR(SetCtor) { VAL2 = SZ_INT; } +INSTR(FuncWait) { + const Func f = (Func)instr->m_val; + if(f->_wait->len - instr->m_val2) { + if(!handle(shred, "UninitValue")) { + gw_err("{-}some values are not instantiated yet{0}\n"); + for(uint32_t i = instr->m_val2; i < f->_wait->len; i++) { + Value v = *mp_vector_at(f->_wait, Value, i); + defined_here(v); + } + } + } else { + BYTE(eNoOp); + } +} + INSTR(fast_except) { struct FastExceptInfo *info = (struct FastExceptInfo *)instr->m_val2; if(*(m_uint*)REG(-SZ_INT)) { diff --git a/src/lib/object.c b/src/lib/object.c index 0570dd83..77cb458e 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -121,7 +121,7 @@ static ID_EMIT(opem_this) { static ID_CHECK(opck_super) { const Exp self = exp_self(prim); - if(!env->func) + if(!env->func || is_ctor(env->func->def)) ERR_O(self->pos, "can't use 'super' outside of constructor"); const Type parent = env->class_def->info->parent; DECL_OO(const Value, v, = find_value(parent, insert_symbol("new"))); diff --git a/src/parse/check.c b/src/parse/check.c index 90c76eda..e34c31ec 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -83,14 +83,22 @@ ANN static m_uint get_decl_size(const Env env, const Value v) { describe_check_decl(member, offset, v->vflag |= vflag_member); describe_check_decl(static, class_data_size, SET_FLAG(v, static)); +ANN static void var_effects(const Env env, const Type t, const Symbol sym, const loc_t loc) { + if (t->info->parent) var_effects(env, t->info->parent, sym, loc); + if(!tflag(t, tflag_ctor)) return; + const Value ctor = nspc_lookup_value0(t->nspc, sym); + if(!ctor) return; // bit sus + const Func f = ctor->d.func_ref; + const Vector v = &f->def->base->effects; + if(!v->ptr) return; + for (m_uint i = 0; i < vector_size(v); i++) + env_add_effect(env, (Symbol)vector_at(v, i), loc); +} + ANN static m_bool check_var(const Env env, const Var_Decl *var) { if (env->class_def && !env->scope->depth && env->class_def->info->parent) CHECK_BB(check_exp_decl_parent(env, var)); - if (var->value->type->effects.ptr) { - const Vector v = &var->value->type->effects; - for (m_uint i = 0; i < vector_size(v); i++) - env_add_effect(env, (Symbol)vector_at(v, i), var->pos); - } + var_effects(env, var->value->type, insert_symbol("@ctor"), var->pos); return GW_OK; } @@ -308,8 +316,6 @@ ANN static Value check_non_res_value(const Env env, const Symbol *data) { 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) { @@ -394,11 +400,14 @@ ANN static Type prim_id_non_res(const Env env, const Symbol *data) { if (GET_FLAG(v, const)) exp_setmeta(prim_exp(data), 1); 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(vflag(v, vflag_fglobal) /*&& !vflag(v, vflag_builtin) */&& !is_func(env->gwion, v->type)) { + if((GET_FLAG(v, global) || vflag(v, vflag_fglobal)) && !vflag(v, vflag_builtin) && !is_func(env->gwion, v->type)) { + if(!env->func->_wait) + env->func->_wait = new_mp_vector(env->gwion->mp, Value, 0); 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++; + mp_vector_add(env->gwion->mp, &env->func->_wait, Value, v); } else { bool found = false; for(uint32_t i = 0; i < v->used_by->len; i++) { @@ -409,8 +418,8 @@ ANN static Type prim_id_non_res(const Env env, const Symbol *data) { } } if(!found) { - env->func->wait++; mp_vector_add(env->gwion->mp, &v->used_by, Func, env->func); + mp_vector_add(env->gwion->mp, &env->func->_wait, Value, v); } } } @@ -1812,14 +1821,6 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef, return GW_OK; } -ANN static bool effect_find(const MP_Vector *v, const Symbol sym) { - for(m_uint i = 0; i < v->len; i++) { - struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i); - if(eff->sym == sym) return true; - } - return false; -} - ANN static m_bool check_fdef_effects(const Env env, const Func_Def fdef) { MP_Vector *v = (MP_Vector*)vector_back(&env->scope->effects); if (v) { @@ -1829,7 +1830,7 @@ ANN static m_bool check_fdef_effects(const Env env, const Func_Def fdef) { if (!base->ptr) vector_init(base); for (uint32_t i = 0; i < v->len; i++) { struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i); - if(!effect_find(v, eff->sym)) + if(vector_find(base, (m_uint)eff->sym) == -1) vector_add(base, (m_uint)eff->sym); } free_mp_vector(env->gwion->mp, struct ScopeEffect, v); @@ -1841,11 +1842,16 @@ ANN m_bool check_fdef(const Env env, const Func_Def fdef) { if (fdef->base->args) CHECK_BB(check_func_args(env, fdef->base->args)); if(fdef->builtin) return GW_OK; if (fdef->d.code && fdef->d.code) { - env->scope->depth++; - nspc_push_value(env->gwion->mp, env->curr); + const bool ctor = is_ctor(fdef); + if(!ctor) { + env->scope->depth++; + nspc_push_value(env->gwion->mp, env->curr); + } const m_bool ret = check_stmt_list(env, fdef->d.code); - nspc_pop_value(env->gwion->mp, env->curr); - env->scope->depth--; + if(!ctor) { + nspc_pop_value(env->gwion->mp, env->curr); + env->scope->depth--; + } CHECK_BB(check_fdef_effects(env, fdef)); return ret; } @@ -2033,7 +2039,7 @@ ANN m_bool check_abstract(const Env env, const Class_Def cdef) { } return !err ? GW_OK : GW_ERROR; } - +/* ANN static inline void ctor_effects(const Env env) { const Vector v = &env->scope->effects; MP_Vector *const w = (MP_Vector*)vector_back(v); @@ -2046,33 +2052,32 @@ ANN static inline void ctor_effects(const Env env) { free_mp_vector(env->gwion->mp, struct ScopeEffect, w); vector_pop(v); } - +*/ ANN static m_bool check_body(const Env env, Section *const section) { const m_bool ret = check_section(env, section); - ctor_effects(env); +// ctor_effects(env); return ret; } ANN static bool class_def_has_body(Ast ast) { - for(m_uint i = 0; i < ast->len; i++) { - const Section *section = mp_vector_at(ast, Section, i); - if (section->section_type == ae_section_stmt) { - Stmt_List l = section->d.stmt_list; - for(m_uint i = 0; i < l->len; i++) { - const Stmt stmt = mp_vector_at(l, struct Stmt_, i); - if (stmt->stmt_type == ae_stmt_pp) continue; - if (stmt->stmt_type == ae_stmt_exp) { - const Exp exp = stmt->d.stmt_exp.val; - if (!exp) continue; - if (exp->exp_type != ae_exp_decl) return true; - if (GET_FLAG(exp->d.exp_decl.td, late)) continue; - Var_Decl vd = exp->d.exp_decl.vd; - if (GET_FLAG(vd.value, late)) continue; - if (tflag(vd.value->type, tflag_compound)) - return true; - } else return true; - } - } + const Section *section = mp_vector_at(ast, Section, 0); + if(section->section_type != ae_section_func) return false; + Func_Def f = section->d.func_def; + if(strcmp(s_name(f->base->xid), "@ctor"))return false; + Stmt_List l = f->d.code; + for(m_uint i = 0; i < l->len; i++) { + const Stmt stmt = mp_vector_at(l, struct Stmt_, i); + if (stmt->stmt_type == ae_stmt_pp) continue; + if (stmt->stmt_type == ae_stmt_exp) { + const Exp exp = stmt->d.stmt_exp.val; + if (!exp) continue; + if (exp->exp_type != ae_exp_decl) return true; + if (GET_FLAG(exp->d.exp_decl.td, late)) continue; + Var_Decl vd = exp->d.exp_decl.vd; + if (GET_FLAG(vd.value, late)) continue; + if (tflag(vd.value->type, tflag_compound)) + return true; + } else return true; } return false; } @@ -2160,6 +2165,7 @@ ANN static m_bool _check_class_def(const Env env, const Class_Def cdef) { if (cdef->body) { CHECK_BB(env_body(env, cdef, check_body)); if (cflag(cdef, cflag_struct) || class_def_has_body(cdef->body)) +// if (class_def_has_body(cdef->body)) set_tflag(t, tflag_ctor); } if (!GET_FLAG(cdef, abstract)) CHECK_BB(check_abstract(env, cdef)); diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 4f6602ff..c871bbd4 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -5,6 +5,10 @@ #include "traverse.h" #include "template.h" #include "parse.h" +#include "object.h" +#include "operator.h" +#include "instr.h" +#include "import.h" ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list); ANN static m_bool scan1_stmt(const Env env, Stmt stmt); @@ -133,7 +137,9 @@ ANN static m_bool scan1_decl(const Env env, Exp_Decl *const decl) { env->class_def->size += t->size; } } - } else if(env->context) + } else if (GET_FLAG(decl->td, global)) + SET_FLAG(v, global); + else if(env->context) set_vflag(v, vflag_fglobal); // file global } else if (GET_FLAG(decl->td, global)) SET_FLAG(v, global); @@ -317,7 +323,12 @@ ANN static inline m_bool shadow_arg(const Env env, const Symbol sym, Nspc nspc = env->curr; do { const Value v = nspc_lookup_value0(nspc, sym); - if (v && !env->func->def->builtin) return shadow_err(env, v, loc); + if (v && !env->func->def->builtin) { + const Type owner = v->from->owner_class; + if (owner && env->class_def && isa(env->class_def, owner) < 0) + continue; + return shadow_err(env, v, loc); + } } while ((nspc = nspc->parent)); return GW_OK; } @@ -644,7 +655,10 @@ ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) { CHECK_BB(scan_internal(env, fdef->base)); else if (fbflag(fdef->base, fbflag_op) && env->class_def) SET_FLAG(fdef->base, static); - RET_NSPC(scan1_fbody(env, fdef)) + if(!is_ctor(fdef)) { + RET_NSPC(scan1_fbody(env, fdef)) + } else if(!fdef->builtin) + CHECK_BB(scan1_stmt_list(env, fdef->d.code)); return GW_OK; } @@ -742,6 +756,34 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) { return ret; } +ANN static m_bool scan1_class_def_body(const Env env, const Class_Def cdef) { + if(!tmpl_base(cdef->base.tmpl) && isa(cdef->base.type, env->gwion->type[et_closure]) < 0 && + isa(cdef->base.type, env->gwion->type[et_dict]) < 0) { + MemPool mp = env->gwion->mp; + Ast base = cdef->body; + Stmt_List ctor = new_mp_vector(mp, struct Stmt_, 0); + Ast body = new_mp_vector(mp, Section, 1); // room for ctor + for(uint32_t i = 0; i < base->len; i++) { + Section section = *mp_vector_at(base, Section, i); + if(section.section_type == ae_section_stmt) { + Stmt_List list = section.d.stmt_list; + for(uint32_t j = 0; j < list->len; j++) { + Stmt stmt = mp_vector_at(list, struct Stmt_, j); + mp_vector_add(mp, &ctor, struct Stmt_, *stmt); + } + } else mp_vector_add(mp, &body, Section, section); + } + Type_Decl *td = type2td(env->gwion, env->gwion->type[et_void], cdef->base.pos); + Symbol sym = insert_symbol("@ctor"); + Func_Base *fb = new_func_base(mp, td, sym, NULL, ae_flag_none, cdef->base.pos); + Func_Def fdef = new_func_def(mp, fb, ctor); + mp_vector_set(body, Section, 0, MK_SECTION(func, func_def, fdef)); + free_mp_vector(mp, Section, base); + cdef->body = body; + } + return env_body(env, cdef, scan1_section); +} + ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) { if (tmpl_base(cdef->base.tmpl)) return GW_OK; const Type t = cdef->base.type; @@ -749,7 +791,7 @@ ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) { set_tflag(t, tflag_scan1); const Class_Def c = t->info->cdef; if (c->base.ext) CHECK_BB(cdef_parent(env, c)); - if (c->body) CHECK_BB(env_body(env, c, scan1_section)); + if (c->body) CHECK_BB(scan1_class_def_body(env, c)); return GW_OK; } diff --git a/src/parse/scan2.c b/src/parse/scan2.c index c6ea9a05..057bb9f2 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -414,11 +414,16 @@ ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f) { ANN static m_bool scan2_func_def_code(const Env env, const Func_Def f) { const Func former = env->func; env->func = f->base->func; - env->scope->depth++; - nspc_push_value(env->gwion->mp, env->curr); + const bool ctor = is_ctor(f); + if(!ctor) { + env->scope->depth++; + nspc_push_value(env->gwion->mp, env->curr); + } const m_bool ret = scan2_stmt_list(env, f->d.code); // scope depth? - nspc_pop_value(env->gwion->mp, env->curr); - env->scope->depth--; + if(!ctor) { + nspc_pop_value(env->gwion->mp, env->curr); + env->scope->depth--; + } env->func = former; return ret; } diff --git a/src/vm/vm.c b/src/vm/vm.c index 4433b413..df8c917a 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -156,7 +156,7 @@ ANN static inline void handle_fail(VM_Shred shred, const m_str effect, const str shreduler_remove(shred->tick->shreduler, shred, true); } -ANN void handle(VM_Shred shred, const m_str effect) { +ANN bool handle(VM_Shred shred, const m_str effect) { shreduler_remove(shred->tick->shreduler, shred, false); // store trace info struct TraceStart ts = { @@ -167,8 +167,11 @@ ANN void handle(VM_Shred shred, const m_str effect) { const m_uint size = shred->info->frame.ptr ? vector_size(&shred->info->frame) : 0; // maybe we should use a string to avoid the insert_symbol call - if (!unwind(shred, insert_symbol(shred->info->vm->gwion->st, effect), size)) + if (!unwind(shred, insert_symbol(shred->info->vm->gwion->st, effect), size)) { handle_fail(shred, effect, &ts); + return false; + } + return true; } ANN bool vm_remove(const VM *vm, const m_uint index) { @@ -1567,7 +1570,7 @@ _other: const f_instr exec = *(f_instr*)(prepare_code + SZ_INT *2); if(exec == DTOR_EOC)return; const Instr instr = *(Instr*)(prepare_code + SZ_INT); - if(exec == fast_except) + if(exec == fast_except || exec == FuncWait) instr->opcode = (m_uint)&&noop; else if(exec == SetFunc) instr->opcode = (m_uint)&®pushimm; diff --git a/util b/util index 8b264457..4588df17 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit 8b2644578a7489ef9c8d87cd19a6326fb775fd3f +Subproject commit 4588df17c998d18e8db40ce1391a714cd893b469 -- 2.43.0