From: Jérémie Astor Date: Sun, 13 Jun 2021 09:54:39 +0000 (+0200) Subject: :art: Improve function calling X-Git-Tag: nightly~599 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=3baa00369a70c0d1603bc5e1691a46ea73a1e0b3;p=gwion.git :art: Improve function calling --- diff --git a/ast b/ast index 269c5307..bbaaa66e 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 269c530719fc73ae9427a01b379b184f2596911e +Subproject commit bbaaa66e1ecae79f4b48c45e433cba1709dba938 diff --git a/plug b/plug index 98feefdb..1144c836 160000 --- a/plug +++ b/plug @@ -1 +1 @@ -Subproject commit 98feefdb89f5cdcedd50e9f39b8ada210b02ab55 +Subproject commit 1144c836130b2016626c3bd761f23eef6f7b3f3c diff --git a/src/emit/emit.c b/src/emit/emit.c index 526e4d96..1338094d 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -152,12 +152,13 @@ ANN static void emit_struct_ctor(const Emitter emit, const Type type, const m_ui const Instr set_code = regseti(emit, (m_uint)type->nspc->dtor); set_code->m_val2 = SZ_INT; const m_uint code_offset = emit_code_offset(emit); - const Instr regset = regseti(emit, code_offset); + const Instr regset = regseti(emit, code_offset /*+ SZ_INT*/ /*+ sizeof(frame_t)*/); regset->m_val2 = SZ_INT *2; regpush(emit, SZ_INT *2); const Instr prelude = emit_add_instr(emit, SetCode); - prelude->m_val2 = 2; prelude->m_val = -SZ_INT*4; + prelude->udata.one = 2; +// prelude->udata.two = emit_code_offset(emit) + SZ_INT + sizeof(frame_t); const Instr next = emit_add_instr(emit, Overflow); next->m_val2 = code_offset; emit->code->frame->curr_offset -= SZ_INT; @@ -385,12 +386,13 @@ ANN void emit_ext_ctor(const Emitter emit, const Type t) { instr->m_val = (m_uint)t; } const m_uint offset = emit_code_offset(emit); - const Instr regset = regseti(emit, offset); + const Instr regset = regseti(emit, offset /*+ SZ_INT */ /*+ sizeof(frame_t)*/); regset->m_val2 = SZ_INT *2; regpush(emit, SZ_INT*2); const Instr prelude = emit_add_instr(emit, SetCode); - prelude->m_val2 = 2; prelude->m_val = -SZ_INT * 2; + prelude->udata.one = 2; +// prelude->udata.two = emit_code_offset(emit) + SZ_INT + sizeof(frame_t); emit_add_instr(emit, Reg2Mem); const Instr next = emit_add_instr(emit, Overflow); next->m_val2 = offset; @@ -1079,7 +1081,7 @@ ANN static m_bool _emit_exp_call(const Emitter emit, const Exp_Call* exp_call) { else CHECK_BB(emit_func_args(emit, exp_call)); if(isa(t, emit->gwion->type[et_function]) > 0) - CHECK_BB(emit_exp_call1(emit, t->info->func)); + CHECK_BB(emit_exp_call1(emit, t->info->func, is_static_call(emit, exp_call->func))); else { struct Op_Import opi = { .op=insert_symbol("@ctor"), .rhs=t, .data=(uintptr_t)exp_call, .pos=exp_self(exp_call)->pos }; @@ -1246,21 +1248,21 @@ ANN static void tmpl_prelude(const Emitter emit, const Func f) { gtmpl->m_val2 = strlen(c); } -ANN static Instr get_prelude(const Emitter emit, const Func f) { +ANN static Instr get_prelude(const Emitter emit, const Func f, const bool is_static) { const Type t = actual_type(emit->gwion, f->value_ref->type); const bool fp = is_fptr(emit->gwion, t); if(is_fptr(emit->gwion, t)) { if(f->def->base->tmpl) tmpl_prelude(emit, f); } - if(fp || f != emit->env->func || f->value_ref->from->owner_class || strstr(emit->code->name, "ork~")) { + if(fp || f != emit->env->func || !is_static || strstr(emit->code->name, "ork~")) { const Instr instr = emit_add_instr(emit, SetCode); - instr->m_val2 = 1; + instr->udata.one = 1; return instr; } const Instr instr = emit_add_instr(emit, Recurs); - instr->m_val2 = 1; instr->m_val = SZ_INT; + instr->udata.one = 1; return instr; } @@ -1315,9 +1317,10 @@ ANN static m_bool me_arg(MemoizeEmitter *me) { return GW_OK; } -ANN static Instr emit_call(const Emitter emit, const Func f) { - const Instr prelude = get_prelude(emit, f); +ANN static Instr emit_call(const Emitter emit, const Func f, const bool is_static) { + const Instr prelude = get_prelude(emit, f, is_static); prelude->m_val += -f->def->stack_depth - SZ_INT; + prelude->udata.two = emit_code_offset(emit) + f->def->stack_depth + sizeof(frame_t); const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0; if(member) { const Instr instr = emit_add_instr(emit, Reg2Mem); @@ -1334,7 +1337,7 @@ ANN static Instr emit_call(const Emitter emit, const Func f) { return emit_add_instr(emit, Overflow); } -ANN m_bool emit_exp_call1(const Emitter emit, const Func f) { +ANN m_bool emit_exp_call1(const Emitter emit, const Func f, const bool is_static) { const m_uint this_offset = emit->this_offset; const m_uint vararg_offset = emit->vararg_offset; emit->this_offset = 0; @@ -1399,8 +1402,9 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f) { } } const m_uint offset = emit_code_offset(emit); - regseti(emit, offset); - const Instr instr = emit_call(emit, f); + if(f != emit->env->func || !is_static) + regseti(emit, offset /*+ f->def->stack_depth + */ /*+ sizeof(frame_t)*/); + const Instr instr = emit_call(emit, f, is_static); instr->m_val = f->def->base->ret_type->size; instr->m_val2 = offset; emit->this_offset = this_offset; @@ -1474,7 +1478,7 @@ ANN static m_bool spork_prepare_code(const Emitter emit, const struct Sporker *s ANN static m_bool spork_prepare_func(const Emitter emit, const struct Sporker *sp) { push_spork_code(emit, sp->is_spork ? SPORK_FUNC_PREFIX : FORK_CODE_PREFIX, sp->exp->pos); const Type t = actual_type(emit->gwion, sp->exp->d.exp_call.func->type); - return emit_exp_call1(emit, t->info->func); + return emit_exp_call1(emit, t->info->func, false); } ANN static VM_Code spork_prepare(const Emitter emit, const struct Sporker *sp) { diff --git a/src/env/type.c b/src/env/type.c index 24b8a7a9..2ac183fb 100644 --- a/src/env/type.c +++ b/src/env/type.c @@ -83,11 +83,12 @@ ANN Type array_base(Type type) { ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint depth) { if(src->array_depth == depth) return insert_symbol(src->name); + const m_uint total_depth = src->array_depth + depth; const Type t = array_base(src); size_t len = strlen(t->name); - char name[len + 2* depth + 1]; + char name[len + 2 * total_depth + 1]; strcpy(name, t->name); - m_uint i = src->array_depth + depth + 1; + m_uint i = total_depth + 1; while(--i) { strcpy(name+len, "[]"); len += 2; diff --git a/src/gwion.c b/src/gwion.c index 0ab82621..17b05f60 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -157,7 +157,7 @@ ANN void gwion_end(const Gwion gwion) { } ANN void env_error_footer(const Env env) { - if(env->class_def) + if(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); diff --git a/src/import/import_checker.c b/src/import/import_checker.c index 85628e66..45c297df 100644 --- a/src/import/import_checker.c +++ b/src/import/import_checker.c @@ -314,6 +314,8 @@ ANN static m_bool _ac_run(const Gwion gwion, struct AC *const ac) { CHECK_BB(ac_num(gwion, ac, num)); CHECK_BB(ac_exp(gwion, ac)); const Exp exp = new_prim_int(gwion->mp, num, ac->pos); + // set type: otherwise could fail at emit time + exp->type = gwion->type[et_int]; ac_add_exp(ac, exp); } else CHECK_BB(ac_noexp(gwion, ac)); diff --git a/src/import/import_enum.c b/src/import/import_enum.c index d1922c92..499d61a0 100644 --- a/src/import/import_enum.c +++ b/src/import/import_enum.c @@ -99,6 +99,7 @@ ANN Type gwi_enum_end(const Gwi gwi) { } ANN void ck_clean_edef(MemPool mp, ImportCK *ck) { +/* if(ck->tmpl) free_id_list(mp, ck->tmpl); if(ck->v.ptr) { @@ -106,5 +107,6 @@ ANN void ck_clean_edef(MemPool mp, ImportCK *ck) { mp_free2(mp, SZ_INT, (m_uint*)vector_at(&ck->v, i)); vector_release(&ck->v); } +*/ } diff --git a/src/import/import_internals.c b/src/import/import_internals.c index 467184bd..93f2587c 100644 --- a/src/import/import_internals.c +++ b/src/import/import_internals.c @@ -35,8 +35,11 @@ ANN static m_bool run_with_doc(const Gwi gwi, m_bool (*f)(const Gwi)) { gwi->lint = &linter; return f(gwi); } + ANN m_bool gwi_run(const Gwion gwion, m_bool (*f)(const Gwi)) { const m_str name = gwion->env->name; +// const Context ctx = gwion->env->context; +// gwion->env->context = NULL; OperCK oper = {}; struct Gwi_ gwi = { .gwion=gwion, .oper=&oper }; const m_bool ret = !gwion->data->cdoc ? @@ -44,5 +47,6 @@ ANN m_bool gwi_run(const Gwion gwion, m_bool (*f)(const Gwi)) { if(ret < 0) gwi_reset(&gwi); gwion->env->name = name; +// gwion->env->context = ctx; return ret; } diff --git a/src/import/import_special.c b/src/import/import_special.c index f1be4ebd..c062929c 100644 --- a/src/import/import_special.c +++ b/src/import/import_special.c @@ -37,6 +37,7 @@ ANN void gwi_specialid(const Gwi gwi, const m_str id, const SpecialId spid) { ANN void gwi_set_loc(const Gwi gwi, const m_str file, const uint line) { gwi->loc.first.line = gwi->loc.last.line = line; + gwi->loc.first.column = 1; gwi->loc.last.column = 2; gwi->gwion->env->name = file; } diff --git a/src/import/import_tdef.c b/src/import/import_tdef.c index 47ae7996..f08323cc 100644 --- a/src/import/import_tdef.c +++ b/src/import/import_tdef.c @@ -38,7 +38,8 @@ ANN Type gwi_typedef_end(const Gwi gwi, const ae_flag flag) { lint_type_def(gwi->lint, tdef); } const Type t = tdef->type; - set_tflag(t, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit); + if(ret > 0) + set_tflag(t, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit); free_type_def(gwi->gwion->mp, tdef); ck_end(gwi); return ret > 0 ? t : NULL; diff --git a/src/lib/array.c b/src/lib/array.c index 344f1f2c..d9852bb4 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -414,7 +414,7 @@ ANN static inline void _init(const VM_Shred shred, frame->code = shred->code; frame->offset = offset; frame->index = 0; - *(m_uint*)REG(SZ_INT) = offset; + *(m_uint*)REG(SZ_INT) = offset;// + sizeof(frame_t);// + shred->code->stack_depth; shred->code = (VM_Code)code; shred->pc = 0; shredule(shred->tick->shreduler, shred, 0); @@ -422,7 +422,7 @@ ANN static inline void _init(const VM_Shred shred, ANN static inline void _next(const VM_Shred shred, const m_uint offset) { shred->pc = 0; - *(m_uint*)REG(0) = offset; + *(m_uint*)REG(0) = offset;// + sizeof(frame_t); POP_REG(shred, SZ_INT); } @@ -711,7 +711,9 @@ ANN static void prepare_run(m_bit *const byte, const f_instr ini, const f_instr *(unsigned*)byte = eOP_MAX; *(f_instr*)(byte + SZ_INT*2) = ini; *(unsigned*)(byte+ BYTECODE_SZ) = eSetCode; - *(m_uint*)(byte + BYTECODE_SZ + SZ_INT*2) = 3; +// *(m_uint*)(byte + BYTECODE_SZ + SZ_INT*2) = 3; + *(uint16_t*)(byte + BYTECODE_SZ + SZ_INT*2) = 3; +// *(uint16_t*)(byte + BYTECODE_SZ + SZ_INT*2 + sizeof(uint16_t)) = sizeof(frame_t); *(unsigned*)(byte+ BYTECODE_SZ*2) = eOverflow; *(unsigned*)(byte+ BYTECODE_SZ*3) = eOP_MAX; *(f_instr*)(byte + BYTECODE_SZ*3 + SZ_INT*2) = end; diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 104d6532..05e15b44 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -98,14 +98,13 @@ ANN static void emit_member_func(const Emitter emit, const Exp_Dot* member) { const Func f = exp_self(member)->type->info->func; if(f->def->base->tmpl) emit_add_instr(emit, DotTmplVal); - else if(GET_FLAG(member->base->type, final) || is_class(emit->gwion, member->base->type) || member->base->exp_type == ae_exp_cast) { + else if(is_static_call(emit, exp_self(member))) { + if(f == emit->env->func) + return; const Instr func_i = emit_add_instr(emit, f->code ? RegPushImm : SetFunc); func_i->m_val = (m_uint)f->code ?: (m_uint)f; return; - } -// if(f->def->base->tmpl) -// emit_add_instr(emit, DotTmplVal); - else { + } else { if(tflag(member->base->type, tflag_struct)) { if(!GET_FLAG(f->def->base, static)) { exp_setvar(member->base, 1); diff --git a/src/parse/operator.c b/src/parse/operator.c index 76fab568..b1e20632 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -219,7 +219,7 @@ ANN static m_bool handle_instr(const Emitter emit, const M_Operator* mo) { if(mo->func) { const Instr push = emit_add_instr(emit, mo->func->code ? RegPushImm : SetFunc); push->m_val = ((m_uint)mo->func->code ?:(m_uint)mo->func); - CHECK_BB(emit_exp_call1(emit, mo->func)); + CHECK_BB(emit_exp_call1(emit, mo->func, true)); if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@conditional")) emit_add_instr(emit, BranchEqInt); else if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@unconditional")) diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 6fff9351..ef20822c 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -83,7 +83,7 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) { if(var->array) { if(var->array->exp) CHECK_BB(scan1_exp(env, var->array->exp)); - t = array_type(env, decl->type, var->array->depth); + CHECK_OB((t = array_type(env, decl->type, var->array->depth))); } if(GET_FLAG(array_base(t), abstract) && ((var->array && var->array->exp) || (decl->td->array && decl->td->array->exp))) diff --git a/src/vm/vm.c b/src/vm/vm.c index 37fb33e7..ae27350b 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -41,7 +41,7 @@ uint32_t gw_rand(uint32_t s[2]) { } ANN static inline void shred_unwind(const VM_Shred shred) { - register struct frame_t *frame = &*(struct frame_t*)(shred->mem - sizeof(struct frame_t)); + register frame_t *frame = &*(frame_t*)(shred->mem - sizeof(frame_t)); shred->code = frame->code; shred->pc = frame->pc; shred->mem -= frame->push; @@ -549,7 +549,7 @@ regpushmaybe: DISPATCH(); funcreturn: { - register struct frame_t frame = *(struct frame_t*)(mem - sizeof(struct frame_t)); + register frame_t frame = *(frame_t*)(mem - sizeof(frame_t)); bytecode = (code = frame.code)->bytecode; mem -= frame.push; PC_DISPATCH(frame.pc); @@ -713,9 +713,9 @@ timeadv: break; recurs: { - register const uint push = *(m_uint*)reg + code->stack_depth + sizeof(struct frame_t); + register const uint push = UVAL2; mem += push; - *(struct frame_t*)(mem - sizeof(struct frame_t)) = (struct frame_t){.code=code,.pc=VAL2,.push=push}; + *(frame_t*)(mem - sizeof(frame_t)) = (frame_t){.code=code,.pc=UVAL,.push=push}; reg += (m_int)VAL; next = eFuncUsrEnd2; } @@ -724,12 +724,12 @@ setcode: PRAGMA_PUSH() a.code = *(VM_Code*)(reg - SZ_INT); if(!a.code->builtin) { - register const uint push = *(m_uint*)reg + code->stack_depth + sizeof(struct frame_t); + register const uint push = *(m_uint*)reg + code->stack_depth + sizeof(frame_t); mem += push; - *(struct frame_t*)(mem - sizeof(struct frame_t)) = (struct frame_t){.code=code,.pc=PC+VAL2,.push=push}; + *(frame_t*)(mem - sizeof(frame_t)) = (frame_t){ .code=code, .pc=PC+UVAL, .push=push }; next = eFuncUsrEnd; } else { - mem += *(m_uint*)reg; + mem += *(m_uint*)reg /*- (code->stack_depth + */ /*- sizeof(frame_t)*/; next = eFuncMemberEnd; } PRAGMA_POP()