From 18f88e164cb28089f2b92c63882b4b741cedd55e Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Wed, 21 Jul 2021 20:55:12 +0200 Subject: [PATCH] :art: Improve constructor --- include/opcode.h | 6 ------ opcode.txt | 1 - src/emit/emit.c | 5 ++--- src/lib/object_op.c | 6 ++++-- src/lib/opfunc.c | 8 ++++---- src/parse/check.c | 9 ++++++--- src/vm/vm.c | 5 +---- 7 files changed, 17 insertions(+), 23 deletions(-) diff --git a/include/opcode.h b/include/opcode.h index 281fc9cd..3b2c28ed 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -30,7 +30,6 @@ enum { eRepeat, eRegPushMe, eRegPushMaybe, - eCtorReturn, eFuncReturn, eGoto, eAllocWord, @@ -249,7 +248,6 @@ enum { #define Repeat (f_instr)eRepeat #define RegPushMe (f_instr)eRegPushMe #define RegPushMaybe (f_instr)eRegPushMaybe -#define CtorReturn (f_instr)eCtorReturn #define FuncReturn (f_instr)eFuncReturn #define Goto (f_instr)eGoto #define AllocWord (f_instr)eAllocWord @@ -603,10 +601,6 @@ ANN static inline void dump_opcodes(const VM_Code code) { gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushMaybe", j); gw_out("\n"); break; - case eCtorReturn: - gw_out("{Y}┃{0}{-}% 4lu{0}: CtorReturn ", j); - gw_out("\n"); - break; case eFuncReturn: gw_out("{Y}┃{0}{-}% 4lu{0}: FuncReturn ", j); gw_out("\n"); diff --git a/opcode.txt b/opcode.txt index b173ce4c..2bd04b75 100644 --- a/opcode.txt +++ b/opcode.txt @@ -27,7 +27,6 @@ RepeatIdx~pc~u Repeat~pc RegPushMe RegPushMaybe -CtorReturn FuncReturn Goto~pc AllocWord~u diff --git a/src/emit/emit.c b/src/emit/emit.c index e0a3f600..274dac81 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1517,7 +1517,7 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f, } const m_uint offset = emit_code_offset(emit); if (f != emit->env->func || !is_static) - regseti(emit, offset /*+ f->def->stack_depth + */ /*+ sizeof(frame_t)*/); + 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; @@ -2560,8 +2560,7 @@ ANN static VM_Code emit_internal(const Emitter emit, const Func f) { ANN static inline VM_Code _emit_func_def_code(const Emitter emit, const Func func) { if(!strcmp(s_name(func->def->base->xid), "new")) - return finalyze(emit, CtorReturn); -// emit_add_instr(emit, RegPushMem); + emit_add_instr(emit, RegPushMem); return !fbflag(func->def->base, fbflag_internal) ? finalyze(emit, FuncReturn) : emit_internal(emit, func); } diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 6e6e8294..db87b977 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -97,8 +97,10 @@ ANN static void emit_member_func(const Emitter emit, const Exp_Dot *member) { const Func f = exp_self(member)->type->info->func; if(!strcmp(s_name(f->def->base->xid), "new")) { - const Instr instr = emit_add_instr(emit, RegPushImm); - instr->m_val = (m_uint)f->code; + if(f != emit->env->func) { + const Instr instr = emit_add_instr(emit, f->code ? RegPushImm : SetFunc); + instr->m_val = (m_uint)f->code ?: (m_uint)f; + } return; } if (f->def->base->tmpl) diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 0d3cfd7b..cd3ee0d0 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -128,9 +128,9 @@ OP_EMIT(opem_new) { const Exp_Unary *unary = (Exp_Unary *)data; CHECK_BB(emit_instantiate_object(emit, exp_self(unary)->type, unary->ctor.td->array, 0)); -// we don't need gc for arrays? -// also when in rewrote exp -// if(!(unary->ctor.td->array || unary->ctor.exp)) -// emit_gc(emit, -SZ_INT); + // we don't need gc for arrays? + // also when in rewrote exp + if(!(unary->ctor.td->array || unary->ctor.exp)) + emit_gc(emit, -SZ_INT); return GW_OK; } diff --git a/src/parse/check.c b/src/parse/check.c index 877a2608..dba0fca7 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -1220,11 +1220,14 @@ ANN static m_bool check_stmt_return(const Env env, const Stmt_Exp stmt) { if (!env->func) ERR_B(stmt_self(stmt)->pos, _("'return' statement found outside function definition")) - if (!strcmp(s_name(env->func->def->base->xid), "new")) - ERR_B(stmt_self(stmt)->pos, - _("'return' statement found inside constructor function")) if (env->scope->depth == 1) // so ops no dot set scope->depth ? set_fflag(env->func, fflag_return); + if (!strcmp(s_name(env->func->def->base->xid), "new")) { + if(stmt->val) + ERR_B(stmt_self(stmt)->pos, + _("'return' statement inside constructor function should have no expression")) + return GW_OK; + } DECL_OB(const Type, ret_type, = stmt->val ? check_exp(env, stmt->val) : env->gwion->type[et_void]); if (!env->func->def->base->ret_type) { diff --git a/src/vm/vm.c b/src/vm/vm.c index f1db7ba3..05b218ed 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -412,7 +412,7 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] &&baseaddr, &®toreg, &®toregother, &®toregaddr, &®toregderef, &&structmember, &&structmemberfloat, &&structmemberother, &&structmemberaddr, &&memsetimm, &&memaddimm, &&repeatidx, &&repeat, - &®pushme, &®pushmaybe, &&ctorreturn, &&funcreturn, &&_goto, &&allocint, + &®pushme, &®pushmaybe, &&funcreturn, &&_goto, &&allocint, &&allocfloat, &&allocother, &&intplus, &&intminus, &&intmul, &&intdiv, &&intmod, &&intplusimm, &&intminusimm, &&intmulimm, &&intdivimm, &&intmodimm, @@ -584,9 +584,6 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] *(m_uint *)reg = gw_rand((uint32_t *)vm->rand) > (UINT32_MAX / 2); reg += SZ_INT; DISPATCH(); -ctorreturn: -*(M_Object*)(reg) = *(M_Object*)mem; -reg += SZ_INT; funcreturn : { register frame_t frame = *(frame_t *)(mem - sizeof(frame_t)); bytecode = (code = frame.code)->bytecode; -- 2.43.0