From: fennecdjay Date: Thu, 27 Oct 2022 15:37:24 +0000 (+0200) Subject: :art: waaayyy to much for a commit X-Git-Tag: nightly~207^2~115 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=85431d23392db2bffcfadb944314bc5309971334;p=gwion.git :art: waaayyy to much for a commit --- diff --git a/ast b/ast index ad317398..1b4e5783 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit ad317398e44e3b8c70b1695acc1991c0778644c6 +Subproject commit 1b4e5783de6964b23da7e02e79fd4003863437b6 diff --git a/include/emit.h b/include/emit.h index 89bc1ecc..62b5de38 100644 --- a/include/emit.h +++ b/include/emit.h @@ -137,9 +137,15 @@ ANN static inline void emit_pushimm(const Emitter emit, const m_uint value) { instr->m_val = value; } -ANN static inline void emit_setimm(const Emitter emit, const m_uint value, const m_uint value2) { - const Instr instr = emit_add_instr(emit, RegSetImm); - instr->m_val = value; - instr->m_val2 = value2; -} +#define mk_emit_instr(name, instruction) \ +ANN static inline Instr emit_##name(const Emitter emit, const m_uint value, const m_uint value2) { \ + const Instr instr = emit_add_instr(emit, instruction); \ + instr->m_val = value; \ + instr->m_val2 = value2; \ + return instr; \ + } +mk_emit_instr(setimm, RegSetImm); +mk_emit_instr(regtomem, Reg2Mem); +mk_emit_instr(regtomem4, Reg2Mem4); +mk_emit_instr(regpushmem4, RegPushMem4); #endif diff --git a/include/opcode.h b/include/opcode.h index 7daf9908..69679ea3 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -18,7 +18,6 @@ enum { eRegPushBase4, eReg2Reg, eReg2RegOther, - eReg2RegOther2, eReg2RegAddr, eReg2RegDeref, eStructMember, @@ -157,7 +156,6 @@ enum { eSporkIni, eForkIni, eSporkFunc, - eSporkMemberFptr, eSporkExp, eSporkCode, eForkEnd, @@ -236,7 +234,6 @@ enum { #define RegPushBase4 (f_instr)eRegPushBase4 #define Reg2Reg (f_instr)eReg2Reg #define Reg2RegOther (f_instr)eReg2RegOther -#define Reg2RegOther2 (f_instr)eReg2RegOther2 #define Reg2RegAddr (f_instr)eReg2RegAddr #define Reg2RegDeref (f_instr)eReg2RegDeref #define StructMember (f_instr)eStructMember @@ -375,7 +372,6 @@ enum { #define SporkIni (f_instr)eSporkIni #define ForkIni (f_instr)eForkIni #define SporkFunc (f_instr)eSporkFunc -#define SporkMemberFptr (f_instr)eSporkMemberFptr #define SporkExp (f_instr)eSporkExp #define SporkCode (f_instr)eSporkCode #define ForkEnd (f_instr)eForkEnd @@ -539,12 +535,6 @@ ANN static inline void dump_opcodes(const VM_Code code) { gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2); gw_out("\n"); break; - case eReg2RegOther2: - gw_out("{Y}┃{0}{-}% 4lu{0}: Reg2RegOther2", j); - gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val); - gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2); - gw_out("\n"); - break; case eReg2RegAddr: gw_out("{Y}┃{0}{-}% 4lu{0}: Reg2RegAddr ", j); gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val); @@ -1145,11 +1135,6 @@ ANN static inline void dump_opcodes(const VM_Code code) { gw_out("{Y}┃{0}{-}% 4lu{0}: SporkFunc ", j); gw_out("\n"); break; - case eSporkMemberFptr: - gw_out("{Y}┃{0}{-}% 4lu{0}: SporkMemberFptr", j); - gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val); - gw_out("\n"); - break; case eSporkExp: gw_out("{Y}┃{0}{-}% 4lu{0}: SporkExp ", j); gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val); diff --git a/opcode.txt b/opcode.txt index 9cbb9db3..ddd0ebe8 100644 --- a/opcode.txt +++ b/opcode.txt @@ -15,7 +15,6 @@ RegPushBase3~p RegPushBase4~p Reg2Reg~u~u Reg2RegOther~u~u -Reg2RegOther2~u~u Reg2RegAddr~u~u Reg2RegDeref~u~u StructMember~u @@ -154,7 +153,6 @@ FuncMemberEnd~u~↓ SporkIni~p ForkIni~p~i SporkFunc -SporkMemberFptr~u SporkExp~u SporkCode~u ForkEnd diff --git a/src/emit/emit.c b/src/emit/emit.c index aab4a820..faff630e 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -130,25 +130,16 @@ if(!tflag(t, tflag_tmpl))return GW_OK; .flag = tflag_emit}; return envset_run(&es, t); } -/* -ANN static inline m_uint emit_code_size(const Emitter emit) { - return vector_size(&emit->code->instr); -} -*/ + ANN static void emit_struct_dtor(const Emitter emit, const Type type, const m_uint offset) { + const m_uint code_offset = emit_code_offset(emit); emit->code->frame->curr_offset += SZ_INT; - const Instr instr = emit_add_instr(emit, RegPushMem4); - instr->m_val = offset; - const Instr tomem = emit_add_instr(emit, Reg2Mem); - tomem->m_val = emit->code->frame->curr_offset; - tomem->m_val2 = -SZ_INT; + emit_regpushmem4(emit, offset, 0); + emit_regtomem(emit, code_offset, -SZ_INT); emit_pushimm(emit, (m_uint)type); - const Instr tomem2 = emit_add_instr(emit, Reg2Mem); - tomem2->m_val = emit->code->frame->curr_offset + SZ_INT; - tomem2->m_val2 = -SZ_INT; + emit_regtomem(emit, code_offset + SZ_INT, -SZ_INT); emit_setimm(emit, (m_uint)type->nspc->dtor, SZ_INT); - const m_uint code_offset = emit_code_offset(emit); emit_setimm(emit, code_offset, SZ_INT*2); emit_regmove(emit, SZ_INT * 2); const Instr prelude = emit_add_instr(emit, SetCode); @@ -159,35 +150,50 @@ ANN static void emit_struct_dtor(const Emitter emit, const Type type, emit->code->frame->curr_offset -= SZ_INT; } -ANN static void struct_pop(const Emitter emit, const Type type, - const m_uint offset) { +ANN void emit_object_release(const Emitter emit, const m_uint offset) { + const Instr instr = emit_add_instr(emit, ObjectRelease); + instr->m_val = offset; +} + +ANN void emit_compound_release(const Emitter emit, const Type t, const m_uint offset) { + if(isa(t, emit->gwion->type[et_compound]) > 0) + return emit_object_release(emit, offset); + emit_struct_release(emit, t, offset); +} + +ANN void emit_struct_release(const Emitter emit, const Type type, + const m_uint offset) { if (!type->info->tuple) return; if (type->nspc->dtor) emit_struct_dtor(emit, type, offset); - for (m_uint i = 0; i < vector_size(&type->info->tuple->types); ++i) { - const Type t = (Type)vector_at(&type->info->tuple->types, i); - if (isa(t, emit->gwion->type[et_object]) > 0) { - const Instr instr = emit_add_instr(emit, ObjectRelease); - instr->m_val = offset + vector_at(&type->info->tuple->offset, i); - } else if (tflag(t, tflag_struct)) - struct_pop(emit, t, offset + vector_at(&type->info->tuple->offset, i)); + const Vector v = &type->info->tuple->types; + for (m_uint i = 0; i < vector_size(v); i++) { + const Type t = (Type)vector_at(v, i); + if (isa(t, emit->gwion->type[et_compound]) > 0) + emit_compound_release(emit, t, offset + vector_at(&type->info->tuple->offset, i)); } } ANN static m_bool emit_stmt(const Emitter emit, const Stmt stmt); ANN static m_bool emit_defers(const Emitter emit) { - if (!vector_size(&emit->code->frame->defer)) return GW_OK; - Stmt stmt; - while ((stmt = (Stmt)vector_pop(&emit->code->frame->defer))) - CHECK_BB(emit_stmt(emit, stmt)); + const Vector v = &emit->code->frame->defer; + if (!vector_size(v)) return GW_OK; + m_uint i; + for(i = vector_size(v) + 1; --i;) { + const Stmt s = (Stmt)vector_at(v, i - 1); + if(s) CHECK_BB(emit_stmt(emit, s)); + } + VLEN(v) = i; + vector_realloc(v); return GW_OK; } ANN static m_bool emit_defers2(const Emitter emit) { - for (m_uint i = vector_size(&emit->code->frame->defer) + 1; --i;) { - const Stmt stmt = (Stmt)vector_at(&emit->code->frame->defer, i - 1); - if (!stmt) break; - CHECK_BB(emit_stmt(emit, stmt)); + const Vector v = &emit->code->frame->defer; + for (m_uint i = vector_size(v) + 1; --i;) { + const Stmt s = (Stmt)vector_at(v, i - 1); + if (!s) break; + CHECK_BB(emit_stmt(emit, s)); } return GW_OK; } @@ -202,7 +208,7 @@ ANN static m_int _frame_pop(const Emitter emit) { (VMValue *)m_vector_addr(&emit->code->live_values, --frame->value_count); vmval->end = emit_code_size(emit); if (!tflag(l->type, tflag_struct)) return (m_int)l->offset; - struct_pop(emit, l->type, l->offset); + emit_struct_release(emit, l->type, l->offset); return _frame_pop(emit); } @@ -212,10 +218,7 @@ ANN static void emit_maybe_release(const Emitter emit, MP_Vector *const ms) { struct M_Vector_ vals = { .ptr = mv->ptr }; for(m_uint j = 0; j < m_vector_size(&vals); j++) { const VMValue val = *(VMValue*)(vals.ptr + ARRAY_OFFSET + j * sizeof(VMValue)); - if(!tflag(val.t, tflag_struct)) { - const Instr instr = emit_add_instr(emit, ObjectRelease); - instr->m_val = val.offset; - } else struct_pop(emit, val.t, val.offset); + emit_compound_release(emit, val.t, val.offset); } } } @@ -264,8 +267,7 @@ ANN void emit_pop_scope(const Emitter emit) { if(!vector_size(&v)) vector_release(&v); else if(vector_size(&v) == 1) { - Instr instr = emit_add_instr(emit, ObjectRelease); - instr->m_val = vector_front(&v); + emit_object_release(emit, vector_front(&v)); vector_release(&v); } else { Instr instr = emit_add_instr(emit, ObjectRelease2); @@ -300,7 +302,10 @@ ANN m_uint emit_local(const Emitter emit, const Type t) { if (isa(t, emit->gwion->type[et_compound]) > 0) { l->is_compound = true; VMValue vmval = { - .t = t, .offset = l->offset, .start = emit_code_size(emit)}; + .t = t, + .offset = l->offset, + .start = emit_code_size(emit) + }; m_vector_add(&emit->code->live_values, &vmval); ++emit->code->frame->value_count; } @@ -311,19 +316,19 @@ ANN void* emit_localx(const Emitter emit, const Type t) { Local *const l = frame_local(emit->gwion->mp, emit->code->frame, t); l->is_compound = true; VMValue vmval = { - .t = t, .offset = l->offset, .start = emit_code_size(emit)}; + .t = t, + .offset = l->offset, + .start = emit_code_size(emit) + }; m_vector_add(&emit->code->live_values, &vmval); ++emit->code->frame->value_count; - l->instr = emit_add_instr(emit, Reg2Mem); - l->instr->m_val = l->offset; - l->instr->m_val2 = -SZ_INT; + l->instr = emit_regtomem(emit, l->offset, -SZ_INT); return l; } ANN m_uint emit_local_exp(const Emitter emit, const Exp e) { Local *const l = emit_localx(emit, e->type); - if(e->ref) - e->ref->data = l; + if(e->ref) e->ref->data = l; return l->offset; } @@ -441,7 +446,7 @@ ANN void emit_ext_ctor(const Emitter emit, const Type t) { const Instr prelude = emit_add_instr(emit, SetCode); prelude->m_val = -SZ_INT * 2; prelude->udata.one = 2; - emit_add_instr(emit, Reg2Mem); + (void)emit_regtomem(emit, 0, 0); const Instr next = emit_add_instr(emit, Overflow); next->m_val2 = offset; } @@ -492,7 +497,6 @@ ANN static m_bool emit_symbol_builtin(const Emitter emit, const Symbol *data) { instr->f = v->d.fnum; else instr->m_val = v->d.num; - instr->m_val2 = size; } return GW_OK; } @@ -589,8 +593,6 @@ ANN2(1) static void emit_exp_addref1(const Emitter emit, const Exp exp, m_int size) { const Type t = exp->cast_to ?: exp->type; if (isa(t, emit->gwion->type[et_compound]) > 0) - // emit_object_addref(emit, size, exp_getvar(exp)); - // else if(tflag(t, tflag_struct)) emit_compound_addref(emit, exp->type, size, exp_getvar(exp)); } @@ -643,14 +645,11 @@ ANN static inline m_bool emit_exp_pop_next(const Emitter emit, Exp e); ANN static m_bool emit_range(const Emitter emit, Range *range) { if (range->start) -// CHECK_BB(emit_exp_pop_next(emit, range->start)); CHECK_BB(emit_exp(emit, range->start)); - else - emit_pushimm(emit, 0); + else emit_pushimm(emit, 0); if (range->end) CHECK_BB(emit_exp(emit, range->end)); - else - emit_pushimm(emit, -1); + else emit_pushimm(emit, -1); return GW_OK; } @@ -700,7 +699,7 @@ ANN static m_bool emit_prim_dict(const Emitter emit, Exp *data) { instr->m_val2 = -SZ_INT - val->size; emit_regmove(emit, SZ_INT); } else { - const Instr instr = emit_add_instr(emit, Reg2RegOther2); + const Instr instr = emit_add_instr(emit, Reg2RegOther); instr->m_val = -key->size; instr->m_val2 = key->size; emit_regmove(emit, key->size); @@ -736,7 +735,7 @@ ANN m_bool emit_array_access(const Emitter emit, } ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array *array) { - const Exp e = exp_self(array); + const Exp e = exp_self(array); exp_setvar(array->base, get_emit_var(emit, array->base->type, exp_getvar(e))); CHECK_BB(emit_exp(emit, array->base)); struct ArrayAccessInfo info = { @@ -771,7 +770,7 @@ ANN static inline Instr specialid_instr(const Emitter emit, ANN static m_bool emit_prim_id(const Emitter emit, const Symbol *data) { const Exp_Primary *prim = prim_self(data); struct SpecialId_ *spid = specialid_get(emit->gwion, *data); - if (spid) + if (unlikely(spid)) return specialid_instr(emit, spid, prim_self(data)) ? GW_OK : GW_ERROR; if(vflag(prim->value, vflag_fglobal)) exp_self(prim)->acquire = 1; return emit_symbol(emit, prim_self(data)); @@ -862,11 +861,7 @@ ANN static m_bool emit_prim_hack(const Emitter emit, const Exp *exp) { if (!(emit->env->func && emit->env->func->def->base->xid == insert_symbol("@gack"))) emit_add_instr(emit, GackEnd); - else { - const Instr instr = emit_add_instr(emit, Reg2Mem); - instr->m_val = SZ_INT; - instr->m_val2 = -SZ_INT; - } + else emit_regtomem(emit, SZ_INT, -SZ_INT); return GW_OK; } @@ -975,17 +970,10 @@ ANN static m_bool struct_finish(const Emitter emit, const Exp_Decl *decl) { const Type t = decl->type; const bool emit_addr = exp_getvar(exp_self(decl)); if (decl->args) { -//exp_setvar(decl->args, emit_addr); - const Instr instr = (Instr)vector_back(&emit->code->instr); CHECK_BB(emit_exp(emit, decl->args)); if (emit_addr) { emit_regmove(emit, -t->size); -// emit_regmove(emit, SZ_INT -t->size); -// const Instr instr = emit_add_instr(emit, Reg2RegAddr); - const Instr instr = emit_add_instr(emit, RegPushMem4); -// emit_add_instr(emit, EOC); -// instr->m_val = -SZ_INT; -// vector_add(&emit->code->instr, (m_uint)instr); + emit_regpushmem4(emit, 0, 0); } return GW_OK; } @@ -1078,11 +1066,8 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, } 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)) { -// if (!emit_var) -// decl->vd.value->from->offset = decl_non_static_offset(emit, decl, type); - CHECK_BB(struct_finish(emit, decl)); - } + } else if (tflag(v->type, tflag_struct)) + CHECK_BB(struct_finish(emit, decl)); return GW_OK; } @@ -1274,9 +1259,7 @@ ANN static inline void inline_args_ini(const Emitter emit, const Func f, nspc_add_value(emit->env->curr, arg->var_decl.xid, value); } emit_regmove(emit, -f->code->stack_depth); - const Instr cpy = emit_add_instr(emit, Reg2Mem4); - cpy->m_val2 = f->code->stack_depth; - cpy->m_val = start_offset; + emit_regtomem4(emit, f->code->stack_depth, start_offset); } ANN static inline void inline_args_end(const Func f, const Vector v) { @@ -1345,15 +1328,12 @@ ANN static m_bool emit_new_struct(const Emitter emit,const Exp_Call *call) { CHECK_BB(emit_func_args(emit, call)); if(back) vector_add(&emit->code->instr, (m_uint)back); - else if(tflag(t, tflag_ctor)) { - const Instr instr = emit_add_instr(emit, RegPushMem4); - instr->m_val = offset; - } + else if(tflag(t, tflag_ctor)) + emit_regpushmem4(emit, offset, 0); if(tflag(t, tflag_ctor)) emit_ext_ctor(emit, t); else if(!back) { emit_regmove(emit, -SZ_INT + t->size); - const Instr instr = emit_add_instr(emit, RegPushMem4); - instr->m_val = offset; + emit_regpushmem4(emit, offset, 0); } emit_add_instr(emit, NoOp); return GW_OK; @@ -1566,14 +1546,10 @@ ANN static Instr get_prelude(const Emitter emit, const Func f, ANN static void emit_args(const Emitter emit, const Func f) { const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0; - if ((f->def->stack_depth - member) == SZ_INT) { - const Instr instr = emit_add_instr(emit, Reg2Mem); - instr->m_val = member; - } else { - const Instr instr = emit_add_instr(emit, Reg2Mem4); - instr->m_val = member; - instr->m_val2 = f->def->stack_depth - member; - } + if ((f->def->stack_depth - member) == SZ_INT) + emit_regtomem(emit, member, 0); + else + emit_regtomem4(emit, member, f->def->stack_depth - member); } typedef struct { @@ -1652,8 +1628,7 @@ ANN static Instr emit_call(const Emitter emit, const Func f, prelude->m_val += -f->def->stack_depth - SZ_INT; const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0; if (member) { - const Instr instr = emit_add_instr(emit, Reg2Mem); - instr->m_val2 = f->def->stack_depth - SZ_INT; + emit_regtomem(emit, 0, f->def->stack_depth - SZ_INT); ++prelude->m_val2; } if (f->def->stack_depth - member) { @@ -2138,14 +2113,20 @@ ANN static inline void emit_push_stack(const Emitter emit) { vector_add(&emit->code->stack_break, (vtype)NULL); } -ANN static void pop_vector(Vector v, const m_uint pc) { - Instr instr; - while ((instr = (Instr)vector_pop(v))) instr->m_val = pc; +ANN static void set_pcs(const Vector v, const m_uint pc) { + m_uint i; + for(i = vector_size(v) + 1; --i;) { + Instr instr = (Instr)vector_at(v, i - 1); + if(!instr) break; + instr->m_val = pc; + } + VLEN(v) = i - 1; + vector_realloc(v); } ANN static void emit_pop_stack(const Emitter emit, const m_uint index) { - pop_vector(&emit->code->stack_cont, index); - pop_vector(&emit->code->stack_break, emit_code_size(emit)); + set_pcs(&emit->code->stack_cont, index); + set_pcs(&emit->code->stack_break, emit_code_size(emit)); emit_pop_scope(emit); } @@ -2297,8 +2278,7 @@ ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt, ? */emit_local(emit, emit->gwion->type[et_int]) /*: emit_local(emit, stmt->idx->v->type)*/; const m_uint val_offset = emit_localn(emit, stmt->v->type); // localn ? - const Instr tomem = emit_add_instr(emit, Reg2Mem); - tomem->m_val = arr_offset; + emit_regtomem(emit, arr_offset, 0); const Instr loop_idx = emit_add_instr(emit, MemSetImm); loop_idx->m_val = key_offset; loop_idx->m_val2 = -1; @@ -2390,8 +2370,7 @@ ANN static m_bool _emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt, } CHECK_BB(emit_exp_pop_next(emit, stmt->cond)); emit_regmove(emit, -SZ_INT); - const Instr tomem = emit_add_instr(emit, Reg2Mem); - tomem->m_val = offset + (!stmt->idx ? 0 : SZ_INT); + emit_regtomem(emit, offset + !!stmt->idx * SZ_INT, 0); *index = emit_code_size(emit); struct Looper loop = {.exp = stmt->cond, .stmt = stmt->body, @@ -2527,10 +2506,7 @@ ANN static m_bool emit_case_body(const Emitter emit, ANN static m_bool case_value(const Emitter emit, const Exp base, const Exp e) { const Value v = e->d.prim.value; v->from->offset = emit_local(emit, base->type); - emit_debug(emit, v); - const Instr instr = emit_add_instr(emit, Reg2Mem4); - instr->m_val = v->from->offset; - instr->m_val2 = base->type->size; + emit_regtomem4(emit, v->from->offset, base->type->size); return GW_OK; } @@ -2816,8 +2792,7 @@ ANN static void me_end(MemoizeEmitter *me, const m_uint pc) { } ANN static void me_bottom(MemoizeEmitter *me, const m_uint pc) { - const Instr idx = emit_add_instr(me->emit, RegPushMem4); - idx->m_val = me->offset; + emit_regpushmem4(me->emit, me->offset, 0); emit_add_instr(me->emit, int_pre_inc); emit_regmove(me->emit, -SZ_INT); const Instr loop = emit_add_instr(me->emit, Goto); @@ -2879,9 +2854,8 @@ ANN static void emit_lambda_capture(const Emitter emit, const Func_Def fdef) { for(uint32_t i = 0; i < fdef->captures->len - 1; i++) (void)get_capture(emit, fdef->captures, i); const Capture *cap = get_capture(emit, fdef->captures, fdef->captures->len - 1); - const Instr instr = emit_add_instr(emit, Reg2Mem4); - instr->m_val = fdef->stack_depth; - instr->m_val2 = cap->temp->from->offset + cap->temp->type->size - fdef->stack_depth; + const m_uint offset = cap->temp->from->offset + cap->temp->type->size - fdef->stack_depth; + emit_regtomem4(emit, fdef->stack_depth, offset); } ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) { diff --git a/src/lib/deep_equal.c b/src/lib/deep_equal.c index d5d0f293..e13bcde9 100644 --- a/src/lib/deep_equal.c +++ b/src/lib/deep_equal.c @@ -164,9 +164,8 @@ ANN static void deep_emit_init(const Emitter emit, struct DeepEmit *d, const m_i d->tmp->d.prim.value = d->val; d->tmp->type = d->val->type; check_deep_equal_exp(emit->env, d->exp, &d->vec); - const Instr instr = emit_add_instr(emit, Reg2Mem); - instr->m_val2 = offset; - d->val->from->offset = instr->m_val = emit_localn(emit, d->val->type); + d->val->from->offset = emit_localn(emit, d->val->type); + emit_regtomem(emit, d->val->from->offset, offset); } ANN static void deep_emit_release(const Emitter emit, struct DeepEmit *d) { diff --git a/src/lib/lib_gack.c b/src/lib/lib_gack.c index fc0edcd9..e736d484 100644 --- a/src/lib/lib_gack.c +++ b/src/lib/lib_gack.c @@ -22,7 +22,7 @@ static OP_EMIT(opem_gack_implicit) { const struct Implicit *imp = (struct Implicit *)data; const Type t = imp->e->d.prim.d.exp->cast_to ?: imp->e->d.prim.d.exp->type; if(t == imp->t) { - const Instr cpy = emit_add_instr(emit, Reg2RegOther2); // kind + const Instr cpy = emit_add_instr(emit, Reg2RegOther); // kind cpy->m_val2 = SZ_INT; emit_regmove(emit, imp->t->size - SZ_INT); } else { @@ -32,7 +32,7 @@ static OP_EMIT(opem_gack_implicit) { .rhs = imp->t}; CHECK_BB(op_emit(emit, &opi)); emit_regmove(emit, -SZ_INT); - const Instr cpy = emit_add_instr(emit, Reg2RegOther2); // kind + const Instr cpy = emit_add_instr(emit, Reg2RegOther); // kind cpy->m_val = cpy->m_val2 = imp->t->size; } return GW_OK; diff --git a/src/parse/check.c b/src/parse/check.c index 9d3ee8d8..2927616e 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -593,8 +593,10 @@ ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) { const m_uint scope = env->scope->depth; env->scope->depth = 0; vector_init(&v); - while (vector_size((Vector)&env->curr->info->value->ptr) > 1) - vector_add(&v, vector_pop((Vector)&env->curr->info->value->ptr)); + Vector w = (Vector)&env->curr->info->value->ptr; + m_uint i = vector_size(w); + while (i-- > 1) vector_add(&v, vector_at(w, i)); + vector_realloc(w); const m_bool ret = traverse_func_def(env, fdef); for (m_uint i = vector_size(&v) + 1; --i;) vector_add((Vector)&env->curr->info->value->ptr, vector_at(&v, i - 1)); @@ -893,24 +895,24 @@ ANN void call_add_effect(const Env env, const Func func, const loc_t pos) { } } -ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) { - Type t = exp->func->type; - if (!is_func(env->gwion, t)) { // use func flag? - if(isa(exp->func->type, env->gwion->type[et_closure]) > 0) - t = closure_def(t)->base->func->value_ref->type; - else if(is_class(env->gwion, t) && tflag(t->info->base_type, tflag_struct)) { - const Value v = nspc_lookup_value0(t->info->base_type->nspc, insert_symbol("new")); - if(v) t = exp->func->type = v->type; - else return NULL; - } else { - struct Op_Import opi = {.op = insert_symbol("@ctor"), - .rhs = actual_type(env->gwion, exp->func->type), - .data = (uintptr_t)exp, - .pos = exp_self(exp)->pos}; - const Type t = op_check(env, &opi); - return t; - } +ANN Type call_type(const Env env, Exp_Call *const exp) { + const Type t = exp->func->type; + if (is_func(env->gwion, t)) return t; + if(isa(exp->func->type, env->gwion->type[et_closure]) > 0) + return closure_def(t)->base->func->value_ref->type; + if(is_class(env->gwion, t) && tflag(t->info->base_type, tflag_struct)) { + const Value v = nspc_lookup_value0(t->info->base_type->nspc, insert_symbol("new")); + if(v) return exp->func->type = v->type; } + struct Op_Import opi = {.op = insert_symbol("@ctor"), + .rhs = actual_type(env->gwion, exp->func->type), + .data = (uintptr_t)exp, + .pos = exp_self(exp)->pos}; + return op_check(env, &opi); +} + +ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) { + DECL_OO(const Type, t, = call_type(env, exp)); if (t == env->gwion->type[et_op]) return check_op_call(env, exp); if (!t->info->func) // TODO: effects? return check_lambda_call(env, exp); diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 13fc1d60..2ecd4f2e 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -514,15 +514,37 @@ ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) { return ret; } +ANN static m_bool reemit_and_release(const Emitter emit, const Exp e) { + exp_setvar(e, false); + CHECK_BB(emit_exp(emit, e)); + exp_setvar(e, true); + return GW_OK; +} + ANN Ast spread_class(const Env env, const Ast body); +ANN static void exp_rewind(const Emitter emit, const uint32_t start) { + const Vector v = &emit->code->instr; + for(m_int i = vector_size(v); --i > start && i;) { + const Instr instr = (Instr)vector_at(v, i-1); + free_instr(emit->gwion, instr); + } + VLEN(&emit->code->instr) = start; +} + static OP_EMIT(opem_struct_assign) { const Exp_Binary *bin = data; const Type t = bin->lhs->type; const Exp e = exp_self(bin); + CHECK_BB(reemit_and_release(emit, bin->rhs)); + const Type rhs = bin->rhs->type; + emit_struct_release(emit, rhs, 0); + emit_regmove(emit, -rhs->size); if(unlikely(exp_getvar(e))) { - for(m_int i = vector_size(&emit->code->instr); --i > e->start && i;) { - const Instr instr = (Instr)vector_at(&emit->code->instr, i-1); + exp_rewind(emit, e->start); + const Vector v = &emit->code->instr; + for(m_int i = vector_size(v); --i > e->start && i;) { + const Instr instr = (Instr)vector_at(v, i-1); free_instr(emit->gwion, instr); } VLEN(&emit->code->instr) = e->start; @@ -532,14 +554,12 @@ static OP_EMIT(opem_struct_assign) { emit_add_instr(emit, Assign); return GW_OK; } -// need to add ref counting (release former) if(t->size == SZ_INT) emit_add_instr(emit, int_r_assign); else if(t->size == SZ_FLOAT) emit_add_instr(emit, float_r_assign); else { const Instr instr = (Instr)emit_add_instr(emit, Reg2RegOther); - instr->m_val = -(t->size + SZ_INT); + instr->m_val = -t->size * 2; instr->m_val2 = t->size; - emit_regmove(emit, -SZ_INT); } emit_struct_addref(emit, t, 0, false); return GW_OK; diff --git a/src/vm/vm.c b/src/vm/vm.c index 5f44ab9e..446e4772 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -423,7 +423,7 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto] &®setimm, &®pushimm, &®pushfloat, &®pushother, &®pushaddr, &®pushmem, &®pushmemfloat, &®pushmemother, &®pushmemaddr, &®pushmemderef, &&pushnow, &&baseint, &&basefloat, &&baseother, - &&baseaddr, &®toreg, &®toregother, &®toregother2, &®toregaddr, &®toregderef, + &&baseaddr, &®toreg, &®toregother2, &®toregaddr, &®toregderef, &&structmember, &&structmemberfloat, &&structmemberother, &&structmemberaddr, &&memsetimm, &&memaddimm, &&repeatidx, &&repeat, &®pushme, &®pushmaybe, &&funcreturn, &&_goto, &&allocint, @@ -454,7 +454,7 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto] &®tomem, &®tomemother, &&overflow, &&funcusrend, &&funcusrend2, &&funcmemberend, - &&sporkini, &&forkini, &&sporkfunc, &&sporkmemberfptr, &&sporkexp, &&sporkcode, + &&sporkini, &&forkini, &&sporkfunc, &&sporkexp, &&sporkcode, &&forkend, &&sporkend, &&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat, &&unroll, &&arrayappend, &&autounrollinit, &&autoloop, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&newobj, &&addref, @@ -564,9 +564,6 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto] regtoreg: *(m_uint *)(reg + IVAL) = *(m_uint *)(reg + IVAL2); DISPATCH() - regtoregother: - memcpy(*(m_bit **)(reg - SZ_INT), reg + IVAL, VAL2); - DISPATCH() regtoregother2: memcpy(reg - VAL2, reg + IVAL, VAL2); DISPATCH() @@ -897,7 +894,8 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto] *(m_float *)(reg - SZ_FLOAT) += vm->bbq->pos; VM_OUT break; - recurs : { + recurs: + { register const uint push = SVAL2; mem += push; *(frame_t *)(mem - sizeof(frame_t)) = @@ -962,14 +960,6 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto] *(m_uint *)(child->reg + i) = *(m_uint *)(reg + i + IVAL2); child->reg += VAL; DISPATCH() - sporkmemberfptr: - for (m_uint i = SZ_INT; i < VAL; i += SZ_INT) - *(m_uint *)(child->reg + i) = *(m_uint *)(reg - VAL + i); - *(M_Object *)(child->reg + VAL) = *(M_Object *)(reg + VAL + SZ_INT); - *(m_uint *)(child->reg + VAL + SZ_INT) = - *(m_uint *)(reg + VAL - SZ_INT * 2); - child->reg += VAL + SZ_INT * 2; - DISPATCH() sporkexp: // LOOP_OPTIM for (m_uint i = 0; i < VAL; i += SZ_INT) @@ -1106,20 +1096,20 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto] reg += SZ_INT; DISPATCH() dotmembermem: - reg += SZ_INT; - *(m_uint *)(reg - SZ_INT) = + *(m_uint *)reg = *(m_uint *)((*(M_Object *)(mem + VAL2))->data + VAL); + reg += SZ_INT; DISPATCH() dotmembermem2: - reg += SZ_INT - SZ_FLOAT; - *(m_float *)(reg - SZ_FLOAT) = + *(m_float *)(reg + SZ_INT) = *(m_float *)((*(M_Object *)(mem + VAL2))->data + VAL); + reg += SZ_INT - SZ_FLOAT; DISPATCH() // dotmembermem3: dotmembermem4: - reg += SZ_INT; - *(m_bit **)(reg - SZ_INT) = + *(m_bit **)reg = ((*(M_Object *)(mem + VAL2))->data + VAL); + reg += SZ_INT; DISPATCH() dotmember: *(m_uint *)(reg - SZ_INT) = @@ -1278,7 +1268,7 @@ static void *_dispatch[] = { &&_regsetimm, &&_regpushimm, &&_regpushfloat, &&_regpushother, &&_regpushaddr, &&_regpushmem, &&_regpushmemfloat, &&_regpushmemother, &&_regpushmemaddr, &&_regpushmemderef, &&_pushnow, &&_baseint, &&_basefloat, &&_baseother, - &&_baseaddr, &&_regtoreg, &&_regtoregother, &&_regtoregother2, &&_regtoregaddr, &&_regtoregderef, + &&_baseaddr, &&_regtoreg, &&_regtoregother2, &&_regtoregaddr, &&_regtoregderef, &&_structmember, &&_structmemberfloat, &&_structmemberother, &&_structmemberaddr, &&_memsetimm, &&_memaddimm, &&_repeatidx, &&_repeat, &&_regpushme, &&_regpushmaybe, &&_funcreturn, &&__goto, &&_allocint, @@ -1309,7 +1299,7 @@ static void *_dispatch[] = { &&_regtomem, &&_regtomemother, &&_overflow, &&_funcusrend, &&_funcusrend2, &&_funcmemberend, - &&_sporkini, &&_forkini, &&_sporkfunc, &&_sporkmemberfptr, &&_sporkexp, &&_sporkcode, &&_forkend, + &&_sporkini, &&_forkini, &&_sporkfunc, &&_sporkexp, &&_sporkcode, &&_forkend, &&_sporkend, &&_brancheqint, &&_branchneint, &&_brancheqfloat, &&_branchnefloat, &&_unroll, &&_arrayappend, &&_autounrollinit, &&_autoloop, &&_arraytop, &&_arrayaccess, &&_arrayget, &&_arrayaddr, &&_newobj, &&_addref, @@ -1347,7 +1337,6 @@ goto *_dispatch[*(m_bit*)prepare_code]; PREPARE(baseother); PREPARE(baseaddr); PREPARE(regtoreg); - PREPARE(regtoregother); PREPARE(regtoregother2); PREPARE(regtoregaddr); PREPARE(regtoregderef); @@ -1512,7 +1501,6 @@ return; PREPARE(sporkini); PREPARE(forkini); PREPARE(sporkfunc); - PREPARE(sporkmemberfptr); PREPARE(sporkexp); PREPARE(sporkcode); PREPARE(forkend); diff --git a/tests/struct_ctor/struct_ctor_assign_get.gw b/tests/struct_ctor/struct_ctor_assign_get.gw index 72a69801..2262994a 100644 --- a/tests/struct_ctor/struct_ctor_assign_get.gw +++ b/tests/struct_ctor/struct_ctor_assign_get.gw @@ -8,5 +8,4 @@ struct S { } } -S(21,21) :=> var auto s; -<<< s.i >>>; +<<< (S(21,21) :=> var auto s).i >>>; diff --git a/tests/struct_ctor/struct_ctor_assign_set.gw b/tests/struct_ctor/struct_ctor_assign_set.gw index e845d721..97b33f2e 100644 --- a/tests/struct_ctor/struct_ctor_assign_set.gw +++ b/tests/struct_ctor/struct_ctor_assign_set.gw @@ -1,4 +1,4 @@ -#! [contains] 42 +#! [contains] 13 struct S { 12 :=> var int i; @@ -8,4 +8,4 @@ struct S { } } -<<< 12 :=> (S(21,21) :=> var auto s).i >>>; +<<< 13 :=> (S(21,21) :=> var auto s).i >>>; diff --git a/tests/struct_ctor/struct_ctor_decl_get.gw b/tests/struct_ctor/struct_ctor_decl_get.gw index 99a01685..c4d5bffa 100644 --- a/tests/struct_ctor/struct_ctor_decl_get.gw +++ b/tests/struct_ctor/struct_ctor_decl_get.gw @@ -8,5 +8,4 @@ struct S { } } -var S(21,21) w; -<<< w.i >>>; +<<< (var S(21,21) w).i >>>; diff --git a/tests/struct_ctor/struct_ctor_decl_set.gw b/tests/struct_ctor/struct_ctor_decl_set.gw index 1af53acc..63322a39 100644 --- a/tests/struct_ctor/struct_ctor_decl_set.gw +++ b/tests/struct_ctor/struct_ctor_decl_set.gw @@ -1,4 +1,4 @@ -#! [contains] 42 +#! [contains] 13 struct S { 12 :=> var int i; @@ -8,5 +8,4 @@ struct S { } } -12 :=> (var S(21,21) w).i; -<<< w.i >>>; +<<< 13 :=> (var S(21,21) w).i >>>; diff --git a/tests/struct_ctor/struct_ctor_new_get.gw b/tests/struct_ctor/struct_ctor_new_get.gw index ece50c87..a154e7ba 100644 --- a/tests/struct_ctor/struct_ctor_new_get.gw +++ b/tests/struct_ctor/struct_ctor_new_get.gw @@ -8,4 +8,4 @@ struct S { } } -(new S(21,21)).i; +<<< (new S(21,21)).i >>>;