From 230009bb02675a5a60dc1fe7fd8d26c1875b6826 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Thu, 28 Apr 2022 20:06:33 +0200 Subject: [PATCH] :art: remove closure data and fix scope offset --- include/env/func.h | 7 +++++- include/opcode.h | 29 ----------------------- include/vm.h | 13 +--------- opcode.txt | 4 ---- src/clean.c | 2 +- src/emit/emit.c | 56 ++------------------------------------------ src/lib/deep_equal.c | 4 ++-- src/lib/lib_func.c | 28 +++++++++++----------- src/vm/closure.c | 30 ------------------------ src/vm/vm.c | 26 ++------------------ src/vm/vm_code.c | 8 +------ 11 files changed, 29 insertions(+), 178 deletions(-) delete mode 100644 src/vm/closure.c diff --git a/include/env/func.h b/include/env/func.h index 113f8140..9ce27c7a 100644 --- a/include/env/func.h +++ b/include/env/func.h @@ -37,9 +37,14 @@ ANN m_bool check_lambda(const Env, const Type, Exp_Lambda *); ANN Type check_op_call(const Env env, Exp_Call *const exp); ANN void builtin_func(const MemPool mp, const Func f, void *func_ptr); -static inline Value upvalues_lookup(const Upvalues *upvalues, const Symbol sym) { +ANN static inline Value upvalues_lookup(const Upvalues *upvalues, const Symbol sym) { const Value v = (Value)scope_lookup1(upvalues->values, (m_uint)sym); if(v) return v; return upvalues->parent ? upvalues_lookup(upvalues->parent, sym) : NULL; } + +ANN static inline m_uint captures_sz(const Capture_List captures) { + const Capture *cap = mp_vector_at(captures, Capture, (captures->len - 1)); + return cap->new->from->offset + cap->new->type->size; +} #endif diff --git a/include/opcode.h b/include/opcode.h index a9e0912e..812785bf 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -197,10 +197,6 @@ enum { eDotStatic, eDotStatic2, eDotStatic3, - eUpvalueInt, - eUpvalueFloat, - eUpvalueOther, - eUpvalueAddr, eDotFunc, eGackType, eGackEnd, @@ -416,10 +412,6 @@ enum { #define DotStatic (f_instr)eDotStatic #define DotStatic2 (f_instr)eDotStatic2 #define DotStatic3 (f_instr)eDotStatic3 -#define UpvalueInt (f_instr)eUpvalueInt -#define UpvalueFloat (f_instr)eUpvalueFloat -#define UpvalueOther (f_instr)eUpvalueOther -#define UpvalueAddr (f_instr)eUpvalueAddr #define DotFunc (f_instr)eDotFunc #define GackType (f_instr)eGackType #define GackEnd (f_instr)eGackEnd @@ -1355,27 +1347,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 eUpvalueInt: - gw_out("{Y}┃{0}{-}% 4lu{0}: UpvalueInt ", j); - gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val); - gw_out("\n"); - break; - case eUpvalueFloat: - gw_out("{Y}┃{0}{-}% 4lu{0}: UpvalueFloat", j); - gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val); - gw_out("\n"); - break; - case eUpvalueOther: - gw_out("{Y}┃{0}{-}% 4lu{0}: UpvalueOther", 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 eUpvalueAddr: - gw_out("{Y}┃{0}{-}% 4lu{0}: UpvalueAddr ", j); - gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val); - gw_out("\n"); - break; case eDotFunc: gw_out("{Y}┃{0}{-}% 4lu{0}: DotFunc ", j); gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val); diff --git a/include/vm.h b/include/vm.h index c5d4ae22..0ce89d89 100644 --- a/include/vm.h +++ b/include/vm.h @@ -1,14 +1,6 @@ #ifndef __VM #define __VM -typedef struct Closure_ { - struct Map_ m; - m_uint sz; - m_bit data[]; -} Closure; -ANN Closure *new_closure(MemPool mp, const m_uint sz); -ANN void free_closure(Closure *a, const Gwion gwion); - typedef struct VM_Code_ *VM_Code; struct VM_Code_ { m_bit *bytecode; @@ -17,10 +9,7 @@ struct VM_Code_ { m_uint native_func; }; Type ret_type; // could be `struct Vector_ tmpl_types;` - union { - void * memoize; - Closure *closure; - }; + void * memoize; m_str name; struct Map_ handlers; struct M_Vector_ live_values; diff --git a/opcode.txt b/opcode.txt index 2de1c0f6..6040d9a0 100644 --- a/opcode.txt +++ b/opcode.txt @@ -194,10 +194,6 @@ UnionMember4~u~u DotStatic~p DotStatic2~p DotStatic3~p~u -UpvalueInt~u -UpvalueFloat~u -UpvalueOther~u~u -UpvalueAddr~u DotFunc~u~u GackType GackEnd~u diff --git a/src/clean.c b/src/clean.c index aabacdf3..2e9e7f12 100644 --- a/src/clean.c +++ b/src/clean.c @@ -71,7 +71,7 @@ ANN static void clean_exp_binary(Clean *a, Exp_Binary *b) { ANN static void clean_captures(Clean *a, Capture_List b) { for(uint32_t i = 0; i < b->len; i++) { const Capture *cap = mp_vector_at(b, Capture, i); - if(cap->v) value_remref(cap->v, a->gwion); + if(cap->new) value_remref(cap->new, a->gwion); } } diff --git a/src/emit/emit.c b/src/emit/emit.c index 7ce2ef40..b9f499dc 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -783,22 +783,8 @@ ANN static inline Instr specialid_instr(const Emitter emit, return spid->exec ? emit_add_instr(emit, spid->exec) : spid->em(emit, prim); } -static const f_instr upvalue[] = {UpvalueInt, UpvalueFloat, UpvalueOther, - UpvalueAddr}; ANN static m_bool emit_prim_id(const Emitter emit, const Symbol *data) { const Exp_Primary *prim = prim_self(data); - if (prim->value && emit->env->func && emit->env->func->def->captures) { - const Capture_List caps = emit->env->func->def->captures; - for (uint32_t i = 0; i < caps->len; ++i) { - Capture *cap = mp_vector_at(caps, Capture, i); - if (!strcmp(prim->value->name, cap->v->name)) { - const Instr instr = emit_kind(emit, prim->value->type->size, - exp_getvar(exp_self(prim)), upvalue); - instr->m_val = cap->offset; - return GW_OK; - } - } - } struct SpecialId_ *spid = specialid_get(emit->gwion, *data); if (spid) return specialid_instr(emit, spid, prim_self(data)) ? GW_OK : GW_ERROR; @@ -1873,6 +1859,7 @@ ANN static m_bool spork_prepare_code(const Emitter emit, if (emit->env->class_def) stack_alloc(emit); if (emit->env->func && vflag(emit->env->func->value_ref, vflag_member)) stack_alloc(emit); + if(sp->captures) emit->code->frame->curr_offset += captures_sz(sp->captures); return scoped_stmt(emit, sp->code, 0); } @@ -1982,6 +1969,7 @@ ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary *unary) { if(cap->is_ref) exp_setvar(&exp, true); offset += exp_size(&exp); emit_exp(emit, &exp); +// emit_exp_addref(emit, &exp, -exp_size(&exp)); } } if(offset) { @@ -2121,48 +2109,8 @@ ANN static inline m_bool emit_prim_novar(const Emitter emit, return GW_OK; } -ANN static m_bool emit_upvalues(const Emitter emit, const Func func) { - const Capture_List caps = func->def->captures; - for (uint32_t i = 0; i < caps->len; ++i) { - Capture *cap = mp_vector_at(caps, Capture, i); - const Value value = cap->v; - struct Exp_ exp = { - .d = { .prim = { - .d = { .var = cap->xid }, - .value = value, - .prim_type = ae_prim_id - }}, - .type = value->type, - .exp_type = ae_exp_primary, - .pos = cap->pos - }; - if(cap->is_ref) exp_setvar(&exp, true); - CHECK_BB(emit_exp(emit, &exp)); - if (isa(value->type, emit->gwion->type[et_compound]) > 0) { - emit_exp_addref1(emit, &exp, -value->type->size); - map_set(&func->code->closure->m, (vtype)value->type, cap->offset); - } - } - return GW_OK; -} - -ANN static m_bool emit_closure(const Emitter emit, const Func func) { - const Capture *cap = mp_vector_at(func->def->captures, Capture, (func->def->captures->len - 1)); - const m_uint sz = cap->offset + cap->v->type->size; - func->code->closure = new_closure(emit->gwion->mp, sz); - regpushi(emit, (m_uint)func->code->closure->data); - CHECK_BB(emit_upvalues(emit, func)); - regpop(emit, sz); - const Instr cpy = emit_add_instr(emit, Reg2RegOther); - cpy->m_val2 = sz; - regpop(emit, SZ_INT); - return GW_OK; -} - ANN static m_bool emit_lambda(const Emitter emit, const Exp_Lambda *lambda) { CHECK_BB(emit_func_def(emit, lambda->def)); - if (lambda->def->captures) - CHECK_BB(emit_closure(emit, lambda->def->base->func)); if (vflag(lambda->def->base->func->value_ref, vflag_member) && !exp_getvar(exp_self(lambda))) emit_add_instr(emit, RegPushMem); diff --git a/src/lib/deep_equal.c b/src/lib/deep_equal.c index b15510e5..a71cfeaf 100644 --- a/src/lib/deep_equal.c +++ b/src/lib/deep_equal.c @@ -97,8 +97,8 @@ static bool deep_check(const Env env, const Exp_Binary *bin, const Vector l, const Vector r) { const m_uint lsz = vector_size(l), rsz = vector_size(r); - if(lsz && rsz >= lsz) { -// if(rsz >= lsz) { +// if(lsz && rsz >= lsz) { + if(rsz >= lsz) { for(m_uint i = 0; i < lsz; i++) { const Value lval = (Value)vector_at(l, i), rval = (Value)vector_at(r, i); diff --git a/src/lib/lib_func.c b/src/lib/lib_func.c index 6550ea98..c0f6eaab 100644 --- a/src/lib/lib_func.c +++ b/src/lib/lib_func.c @@ -240,7 +240,7 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, const Value v = nspc_lookup_value1(env->curr, cap->xid); if(!v) ERR_B(cap->pos, _("unknown value in capture")); offset += (!cap->is_ref ? SZ_INT : v->type->size); - cap->v = v; + cap->orig = v; cap->offset = offset; } } @@ -651,7 +651,7 @@ ANN Type upvalue_type(const Env env, Capture *cap) { if(!v)exit(3); if(cap->is_ref && not_upvalue(env, v)) ERR_O(cap->pos, _("can't take ref of a scoped value")); - cap->v = v; + cap->orig = v; const Type base_type = !tflag(v->type, tflag_ref) ? v->type : (Type)vector_front(&v->type->info->tuple->contains); return !cap->is_ref ? base_type : ref_type(env->gwion, base_type, cap->pos); } @@ -668,38 +668,38 @@ static OP_CHECK(opck_spork) { for(uint32_t i = 0; i < unary->captures->len; i++) { Capture *const cap = mp_vector_at(unary->captures, Capture, i); DECL_OO(const Type, t, = upvalue_type(env, cap)); - cap->v = new_value(env, t, s_name(cap->xid), cap->pos); - cap->v->from->offset = offset; - offset += cap->v->type->size; + cap->new = new_value(env, t, s_name(cap->xid), cap->pos); + cap->new->from->offset = offset; + offset += cap->new->type->size; } } - ++env->scope->depth; - Upvalues values = { - .values = env->curr->info->value - }; + Upvalues upvalues = { .values = env->curr->info->value }; if(env->func && env->func->def->base->values) - values.parent = env->func->def->base->values; + upvalues.parent = env->func->def->base->values; env->curr->info->value = new_scope(env->gwion->mp); if(unary->captures) { for(uint32_t i = 0; i < unary->captures->len; i++) { Capture *const cap = mp_vector_at(unary->captures, Capture, i); - valid_value(env, cap->xid, cap->v); + valid_value(env, cap->xid, cap->new); } } const Func f = env->func; struct Value_ value = { .type = env->gwion->type[et_lambda]}; if(env->class_def) set_vflag(&value, vflag_member); - struct Func_Base_ fbase = { .xid=insert_symbol("in spork"), .values = &values}; + struct Func_Base_ fbase = { .xid=insert_symbol("in spork"), .values = &upvalues}; set_fbflag(&fbase, fbflag_lambda); struct Func_Def_ fdef = { .base = &fbase}; struct Func_ func = { .name = "in spork", .def = &fdef, .value_ref = &value}; env->func = &func; +// ++env->scope->depth; +//nspc_push_value(env->gwion->mp, env->curr); const m_bool ret = check_stmt(env, unary->code); +// nspc_push_value(env->gwion->mp, env->curr); +// --env->scope->depth; env->func = f; free_scope(env->gwion->mp, env->curr->info->value); - env->curr->info->value = values.values; - --env->scope->depth; + env->curr->info->value = upvalues.values; CHECK_BN(ret); return env->gwion ->type[unary->op == insert_symbol("spork") ? et_shred : et_fork]; diff --git a/src/vm/closure.c b/src/vm/closure.c deleted file mode 100644 index 8d888293..00000000 --- a/src/vm/closure.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "gwion_env.h" -#include "vm.h" -#include "instr.h" -#include "memoize.h" -#include "gwion.h" -#include "object.h" -#include "array.h" -#include "operator.h" -#include "import.h" - -ANN Closure *new_closure(MemPool mp, const m_uint sz) { - Closure *a = mp_malloc2(mp, sizeof(Closure) + sz); - map_init(&a->m); - a->sz = sz; - return a; -} - -ANN void free_closure(Closure *a, const Gwion gwion) { - const Map m = &a->m; - for (m_uint i = 0; i < map_size(m); ++i) { - const Type t = (Type)VKEY(m, i); - const m_bit *data = tflag(t, tflag_ref) ? - (a->data + VVAL(m, i)) : *(m_bit**)(a->data + VVAL(m, i)); - compound_release(gwion->vm->cleaner_shred, t, data); - } - map_release(m); - _mp_free(gwion->mp, sizeof(Closure) + a->sz, a); -} diff --git a/src/vm/vm.c b/src/vm/vm.c index 71e90553..845b7b27 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -478,8 +478,7 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto] &&remref, &&remref2, &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr, &&unioncheck, &&unionint, &&unionfloat, &&unionother, &&unionaddr, &&staticint, &&staticfloat, &&staticother, - &&upvalueint, &&upvaluefloat, &&upvalueother, &&upvalueaddr, &&dotfunc, - &&gacktype, &&gackend, &&gack, &&try_ini, + &&dotfunc, &&gacktype, &&gackend, &&gack, &&try_ini, &&try_end, &&handleeffect, &&performeffect, &&noop, &&debugline, &&debugvalue, &&debugpush, &&debugpop, &&eoc, &&unroll2, &&other, &®pushimm}; @@ -1183,22 +1182,6 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto] memcpy(reg, (m_bit *)VAL, VAL2); reg += VAL2; DISPATCH() - upvalueint: - *(m_uint *)reg = *(m_uint *)(code->closure->data + VAL); - reg += SZ_INT; - DISPATCH() - upvaluefloat: - *(m_float *)reg = *(m_float *)(code->closure->data + VAL); - reg += SZ_FLOAT; - DISPATCH() - upvalueother: - memcpy(reg, code->closure->data + VAL, VAL2); - reg += VAL2; - DISPATCH() - upvalueaddr: - *(m_uint **)reg = (m_uint *)(code->closure->data + VAL); - reg += SZ_INT; - DISPATCH() dotfunc: *(VM_Code *)(reg + (m_uint)VAL2) = ((Func)(*(M_Object *)(reg - SZ_INT))->type_ref->nspc->vtable.ptr[OFFSET + VAL])->code; @@ -1322,8 +1305,7 @@ static void *_dispatch[] = { &&_remref, &&_remref2, &&_except, &&_allocmemberaddr, &&_dotmember, &&_dotfloat, &&_dotother, &&_dotaddr, &&_unioncheck, &&_unionint, &&_unionfloat, &&_unionother, &&_unionaddr, &&_staticint, &&_staticfloat, &&_staticother, - &&_upvalueint, &&_upvaluefloat, &&_upvalueother, &&_upvalueaddr, &&_dotfunc, - &&_gacktype, &&_gackend, &&_gack, &&_try_ini, + &&_dotfunc, &&_gacktype, &&_gackend, &&_gack, &&_try_ini, &&_try_end, &&_handleeffect, &&_performeffect, &&_noop, &&_debugline, &&_debugvalue, &&_debugpush, &&_debugpop, &&_eoc, &&_unroll2, &&_other, &&_regpushimm}; @@ -1556,10 +1538,6 @@ return; PREPARE(staticint); PREPARE(staticfloat); PREPARE(staticother); - PREPARE(upvalueint); - PREPARE(upvaluefloat); - PREPARE(upvalueother); - PREPARE(upvalueaddr); PREPARE(dotfunc); PREPARE(gacktype); PREPARE(gackend); diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index ae8a41ed..4474f898 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -29,12 +29,7 @@ ANN void free_vmcode(VM_Code a, Gwion gwion) { if (!a->builtin) { _mp_free(gwion->mp, vector_size(&a->instr) * BYTECODE_SZ, a->bytecode); if (likely(!a->callback)) { - if (a->closure) { - if (!a->is_memoize) - free_closure(a->closure, gwion); - else - memoize_end(gwion->mp, a->memoize); - } + if(a->memoize) memoize_end(gwion->mp, a->memoize); free_code_instr(&a->instr, gwion); } if (a->handlers.ptr) map_release(&a->handlers); @@ -190,7 +185,6 @@ VM_Code vmcode_callback(MemPool mp, VM_Code base) { instr->opcode = eEOC; const VM_Code code = new_vmcode(mp, &base->instr, &base->live_values, name, base->stack_depth, base->builtin, false); - code->closure = base->closure; code->callback = 1; instr->opcode = eFuncReturn; return code; -- 2.43.0