From: Jérémie Astor Date: Mon, 18 May 2020 08:49:11 +0000 (+0200) Subject: :art: fptr and struct improv X-Git-Tag: nightly~1540 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=15717ce26f27bd485fab64d12587acf084f10c99;p=gwion.git :art: fptr and struct improv --- diff --git a/include/opcode.h b/include/opcode.h index 2b33fe5b..6fb4aba1 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -20,6 +20,8 @@ enum { eReg2RegAddr, eReg2RegDeref, eStructMember, + eStructMemberFloat, + eStructMemberOther, eStructMemberAddr, eMemSetImm, eRegPushMe, @@ -174,9 +176,9 @@ enum { eGackEnd, eGack, eNoOp, - eDotTmplVal, - eOP_MAX, eEOC, + eOP_MAX, + eDotTmplVal, }; #define RegSetImm (f_instr)eRegSetImm @@ -198,6 +200,8 @@ enum { #define Reg2RegAddr (f_instr)eReg2RegAddr #define Reg2RegDeref (f_instr)eReg2RegDeref #define StructMember (f_instr)eStructMember +#define StructMemberFloat (f_instr)eStructMemberFloat +#define StructMemberOther (f_instr)eStructMemberOther #define StructMemberAddr (f_instr)eStructMemberAddr #define MemSetImm (f_instr)eMemSetImm #define RegPushMe (f_instr)eRegPushMe @@ -352,7 +356,7 @@ enum { #define GackEnd (f_instr)eGackEnd #define Gack (f_instr)eGack #define NoOp (f_instr)eNoOp -#define DotTmplVal (f_instr)eDotTmplVal -#define OP_MAX (f_instr)eOP_MAX #define EOC (f_instr)eEOC +#define OP_MAX (f_instr)eOP_MAX +#define DotTmplVal (f_instr)eDotTmplVal #endif diff --git a/src/compile.c b/src/compile.c index 0b80a423..13e717b9 100644 --- a/src/compile.c +++ b/src/compile.c @@ -87,10 +87,10 @@ ANN static m_bool is_reg(const m_str path) { ANN static inline m_bool compiler_open(MemPool p, struct Compiler* c) { char name[strlen(c->name) + 1]; strcpy(name, c->name); - if(c->type == COMPILE_FILE && !is_reg(name)) { - gw_err(_("'%s': is a not a regular file\n"), name); - return GW_ERROR; - } +// if(c->type == COMPILE_FILE && !is_reg(name)) { +// gw_err(_("'%s': is a not a regular file\n"), name); +// return GW_ERROR; +// } if(_compiler_open(c) < 0) { compiler_error(p, c); gw_err(_("can't open '%s'\n"), name); diff --git a/src/emit/emit.c b/src/emit/emit.c index 01e6e9d5..a13f3c7a 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -301,6 +301,7 @@ static const f_instr regpushbase[] = { RegPushBase, RegPushBase2, RegPushBase3, static const f_instr dotstatic[] = { DotStatic, DotStatic2, DotStatic3, RegPushImm }; static const f_instr allocmember[] = { RegPushImm, RegPushImm2, RegPushImm3, AllocMember4 }; static const f_instr allocword[] = { AllocWord, AllocWord2, AllocWord3, RegPushMem4 }; +static const f_instr structmember[] = { StructMember, StructMemberFloat, StructMemberOther, StructMemberAddr }; ANN Exp symbol_owned_exp(const Gwion gwion, const Symbol *data); ANN static m_bool emit_symbol_owned(const Emitter emit, const Symbol *data) { @@ -608,11 +609,10 @@ ANN static m_bool emit_exp_decl_static(const Emitter emit, const Var_Decl var_de ANN static Instr emit_struct_decl(const Emitter emit, const Value v, const m_bool emit_addr) { emit_add_instr(emit, RegPushMem); - const Instr instr = emit_add_instr(emit, !emit_addr ? StructMember : StructMemberAddr); - instr->m_val2 = v->from->offset; + const Instr instr = emit_kind(emit, v->type->size, emit_addr, structmember); if(!emit_addr) regpush(emit, v->type->size - SZ_INT); - return instr; // m_val set after but ignored + return instr; } ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *decl, const Var_Decl var_decl, @@ -635,7 +635,7 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d } } const Instr instr = !(SAFE_FLAG(emit->env->class_def, struct) && !emit->env->scope->depth) ? - emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, exec) : emit_struct_decl(emit, v, emit_addr); + 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)) { emit_add_instr(emit, Assign); @@ -645,14 +645,10 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d push->m_val = -(missing_depth) * SZ_INT; } } else if(struct_ctor(v) /* && !GET_FLAG(decl->td, ref) */) { - if(GET_FLAG(v, member)) { - const Instr instr = emit_add_instr(emit, DotMember4); - instr->m_val = v->from->offset; - } emit_ext_ctor(emit, v->type->nspc->pre_ctor); if(!emit_addr) emit_struct_decl_finish(emit, v); - } + } return GW_OK; } diff --git a/src/lib/func.c b/src/lib/func.c index ce84739e..b2fc0e1f 100644 --- a/src/lib/func.c +++ b/src/lib/func.c @@ -13,11 +13,6 @@ #include "template.h" #include "parse.h" -static INSTR(LambdaAssign) { - POP_REG(shred, SZ_INT) - *(Func*)REG(-SZ_INT) = *(Func*)REG(0); -} - static OP_CHECK(opck_func_call) { Exp_Binary* bin = (Exp_Binary*)data; Exp_Call call = { .func=bin->rhs, .args=bin->lhs }; @@ -40,8 +35,10 @@ static OP_EMIT(opem_func_assign) { fptr_instr(emit, bin->lhs->info->type->e->d.func, 2); const Instr instr = emit_add_instr(emit, int_r_assign); if(!is_fptr(emit->gwion, bin->lhs->info->type) && GET_FLAG(bin->rhs->info->type->e->d.func, member)) { - const Instr pop = emit_add_instr(emit, LambdaAssign); + const Instr pop = emit_add_instr(emit, RegPop); pop->m_val = SZ_INT; + const Instr cpy = emit_add_instr(emit, Reg2Reg); + cpy->m_val = -SZ_INT; } return instr; } @@ -68,7 +65,6 @@ ANN static m_bool fptr_tmpl_push(const Env env, struct FptrInfo *info) { return GW_OK; } - static m_bool td_match(const Env env, Type_Decl *id[2]) { DECL_OB(const Type, t0, = known_type(env, id[0])) DECL_OB(const Type, t1, = known_type(env, id[1])) diff --git a/src/lib/instr.c b/src/lib/instr.c index de018cf1..8312c936 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -34,7 +34,7 @@ ANN static Func_Def from_base(const Env env, struct dottmpl_ *const dt, const Ns const Func_Def fdef = dt->def ?: dt->base; const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->xid), "template", dt->vt_index); - DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym)) + DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym) ?: nspc_lookup_value0(nspc, fdef->base->xid)) const Func_Def def = cpy_func_def(env->gwion->mp, v->d.func_ref->def); def->base->tmpl->call = cpy_type_list(env->gwion->mp, dt->tl); def->base->tmpl->base = dt->vt_index; diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 2d1932e5..1ae6d759 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -127,6 +127,8 @@ static OP_CHECK(opck_struct_scan) { } static const f_instr dotstatic[] = { DotStatic, DotStatic2, DotStatic3, RegPushImm }; +static const f_instr structmember[] = { StructMember, StructMemberFloat, StructMemberOther, StructMemberAddr }; + ANN Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]); ANN static void emit_dot_static_data(const Emitter emit, const Value v, const uint emit_var) { const m_uint size = v->type->size; @@ -181,27 +183,24 @@ ANN static inline void emit_member(const Emitter emit, const Value v, const uint ANN static inline void emit_struct_addr(const Emitter emit, const Value v) { const Instr set = emit_add_instr(emit, StructMemberAddr); - set->m_val = v->from->owner_class->size - v->type->size; - set->m_val2 = v->from->offset; + set->m_val = v->from->offset; } ANN static inline void emit_struct_var(const Emitter emit, const Value v) { for(m_uint i = 0; i < v->type->size; i += SZ_INT) { const Instr set = emit_add_instr(emit, Reg2Reg); - set->m_val = -v->type->size + i; - set->m_val2 = -v->type->size + v->from->offset + i; + set->m_val2 = -v->type->size + i; + set->m_val = -v->type->size + v->from->offset + i; } } ANN static inline void emit_struct_data(const Emitter emit, const Value v, const uint emit_addr) { - if(emit_addr) { - emit_struct_addr(emit, v); - return; + const Instr instr = emit_kind(emit, v->type->size, emit_addr, structmember); + instr->m_val = v->from->offset; + if(!emit_addr) { + const Instr instr = emit_add_instr(emit, RegPush); + instr->m_val = v->type->size -SZ_INT; } - const Instr push = emit_add_instr(emit, RegPush); - push->m_val = v->type->size - v->from->owner_class->size; - if(v->from->offset) - emit_struct_var(emit, v); } ANN m_bool not_from_owner_class(const Env env, const Type t, const Value v, const loc_t pos); @@ -260,7 +259,8 @@ OP_EMIT(opem_object_dot) { if(!GET_FLAG(t_base, struct)) emit_member(emit, value, exp_getvar(exp_self(member))); else { - exp_setvar(member->base, exp_getvar(exp_self(member))); +// exp_setvar(member->base, exp_getvar(exp_self(member))); + exp_setvar(member->base, 1); CHECK_BO(emit_exp(emit, member->base)) emit_struct_data(emit, value, exp_getvar(exp_self(member))); } diff --git a/src/parse/check.c b/src/parse/check.c index 67e824cd..69e9137c 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -747,6 +747,8 @@ ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) { } ANN Type check_exp_call1(const Env env, const Exp_Call *exp) { + if(exp->func->exp_type == ae_exp_decl) + ERR_O(exp_self(exp)->pos, _("It makes no sense to call a function pointer at declaration")) CHECK_OO(check_exp(env, exp->func)) if(isa(exp->func->info->type, env->gwion->type[et_function]) < 0) { // use func flag? diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 1624695e..72898b02 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -501,7 +501,7 @@ ANN2(1,2) m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value ove } ANN m_bool scan2_fdef(const Env env, const Func_Def f) { - const Value overload = nspc_lookup_value2(env->curr, f->base->xid); + const Value overload = nspc_lookup_value2(env->curr, f->base->xid); // try0 if(overload) CHECK_BB(scan2_func_def_overload(env, f, overload)) return (!tmpl_base(f->base->tmpl) ? scan2_fdef_std : scan2_fdef_tmpl)(env, f, overload); diff --git a/src/vm/vm.c b/src/vm/vm.c index f9207a29..3e65d43f 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -291,7 +291,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] &&pushnow, &&baseint, &&basefloat, &&baseother, &&baseaddr, &®toreg, &®toregaddr, &®toregderef, - &&structmember, &&structmemberaddr, + &&structmember, &&structmemberfloat, &&structmemberother, &&structmemberaddr, &&memsetimm, &®pushme, &®pushmaybe, &&funcreturn, @@ -332,7 +332,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] &&staticint, &&staticfloat, &&staticother, &&dotfunc, &&dotstaticfunc, &&pushstaticcode, &&gcini, &&gcadd, &&gcend, - &&gacktype, &&gackend, &&gack, &&noop, &®pushimm, &&other, &&eoc + &&gacktype, &&gackend, &&gack, &&noop, &&eoc, &&other, &®pushimm }; const Shreduler s = vm->shreduler; register VM_Shred shred; @@ -428,10 +428,16 @@ regtoregderef: memcpy(*(m_bit**)(reg - SZ_INT), *(m_bit**)(reg + (m_int)VAL), VAL2); DISPATCH() structmember: - *(m_bit**)(reg-SZ_INT) = *(m_bit**)(*(m_bit**)(reg-SZ_INT) + (m_int)VAL2); + *(m_bit**)(reg-SZ_INT) = *(m_bit**)(*(m_bit**)(reg-SZ_INT) + (m_int)VAL); + DISPATCH() +structmemberfloat: + *(m_bit**)(reg-SZ_INT) = *(m_bit**)(*(m_bit**)(reg-SZ_INT) + (m_int)VAL); + DISPATCH() +structmemberother: + *(m_bit**)(reg-SZ_INT) = *(m_bit**)(*(m_bit**)(reg-SZ_INT) + (m_int)VAL); DISPATCH() structmemberaddr: - *(m_bit**)(reg-SZ_INT) = &*(*(m_bit**)(reg-SZ_INT) + (m_int)VAL2); + *(m_bit**)(reg-SZ_INT) = &*(*(m_bit**)(reg-SZ_INT) + (m_int)VAL); DISPATCH() memsetimm: *(m_uint*)(mem+VAL) = VAL2; diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index e2b8f6c3..f571fe8b 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -51,6 +51,7 @@ ANN static m_bit* tobytecode(MemPool p, const VM_Code code) { memcpy(ptr + i*BYTECODE_SZ, instr, BYTECODE_SZ); else { *(m_bit*)(ptr + (i*BYTECODE_SZ)) = instr->opcode; +// *(m_bit*)(ptr + (i*BYTECODE_SZ)) = eOP_MAX; *(Instr*)(ptr + (i*BYTECODE_SZ) + SZ_INT) = instr; *(f_instr*)(ptr + (i*BYTECODE_SZ) + SZ_INT*2) = instr->execute; }