From: Jérémie Astor Date: Wed, 10 Jun 2020 19:06:40 +0000 (+0200) Subject: :bug: Use emit_mod X-Git-Tag: nightly~1485 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=2bd5c6e210b23850021c1cce449cdb9de711fa01;p=gwion.git :bug: Use emit_mod --- diff --git a/include/emit.h b/include/emit.h index 1782caa1..df560225 100644 --- a/include/emit.h +++ b/include/emit.h @@ -40,7 +40,6 @@ ANN2(1) Instr emit_add_instr(const Emitter, const f_instr) __attribute__((return ANN Code* emit_class_code(const Emitter, const m_str); ANN m_bool emit_array_extend(const Emitter, const Type, const Exp); ANN void emit_class_finish(const Emitter, const Nspc); -ANN void emit_ext_ctor(const Emitter, const VM_Code); ANN void emit_union_offset(Decl_List, const m_uint); ANN2(1,2) m_bool emit_instantiate_object(const Emitter, const Type, const Array_Sub, const m_bool); ANN m_uint emit_code_offset(const Emitter emit); diff --git a/include/modify_instr.h b/include/modify_instr.h new file mode 100644 index 00000000..6a5a8803 --- /dev/null +++ b/include/modify_instr.h @@ -0,0 +1,8 @@ +#ifndef __MODIFY_INSTR +#define __MODIFY_INSTR +typedef void (*instr_modifier)(m_bit *bytecode, m_bit *reg); + +ANN void emit_mod_recurs(const Emitter); +ANN void emit_mod_func(const Emitter, const Func); +ANN void emit_mod_ctor(const Emitter, const Type); +#endif diff --git a/src/emit/emit.c b/src/emit/emit.c index 87e7529e..76b753d8 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -18,6 +18,7 @@ #include "parser.h" #include "specialid.h" #include "vararg.h" +#include "modify_instr.h" #undef insert_symbol #define insert_symbol(a) insert_symbol(emit->gwion->st, (a)) @@ -161,9 +162,11 @@ ANN m_uint emit_local(const Emitter emit, const Type t) { return frame_local(emit->gwion->mp, emit->code->frame, t); } -ANN static inline void maybe_ctor(const Emitter emit, const Type type) { - if(type->nspc && type->nspc->pre_ctor && !GET_FLAG(type, nonnull)) - emit_ext_ctor(emit, type->nspc->pre_ctor); +ANN void emit_ext_ctor(const Emitter emit, const Type t); + +ANN static inline void maybe_ctor(const Emitter emit, const Type t) { + if(!GET_FLAG(t, nonnull) && GET_FLAG(t, ctor)) + emit_ext_ctor(emit, t); } ANN static void emit_pre_ctor(const Emitter emit, const Type type) { @@ -243,11 +246,14 @@ ANN2(1,2) static ArrayInfo* emit_array_extend_inner(const Emitter emit, const Ty return info; } -ANN void emit_ext_ctor(const Emitter emit, const VM_Code code) { +ANN void emit_ext_ctor(const Emitter emit, const Type t) { const Instr cpy = emit_add_instr(emit, Reg2Reg); cpy->m_val2 = -SZ_INT; - const Instr set_code = regseti(emit, (m_uint)code); - set_code->m_val2 = SZ_INT; + if(t->nspc->pre_ctor) { + const Instr set_code = regseti(emit, (m_uint)t->nspc->pre_ctor); + set_code->m_val2 = SZ_INT; + } else + emit_mod_ctor(emit, t); const m_uint offset = emit_code_offset(emit); const Instr regset = regseti(emit, offset); regset->m_val2 = SZ_INT *2; @@ -600,7 +606,7 @@ ANN static void decl_expand(const Emitter emit, const Type t) { ANN static void emit_struct_decl_finish(const Emitter emit, const Type t, const uint emit_addr) { emit->code->frame->curr_offset += t->size + SZ_INT; - emit_ext_ctor(emit, t->nspc->pre_ctor); + emit_ext_ctor(emit, t); if(!emit_addr) decl_expand(emit, t); emit->code->frame->curr_offset -= t->size + SZ_INT; @@ -1040,7 +1046,7 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) { if(GET_FLAG(f, template) && !is_fptr(emit->gwion, f->value_ref->type)) { if(emit->env->func != f) CHECK_BO(emit_template_code(emit, f)) - else { + else { // recursive function. (maybe should be used only for global funcs) const Instr back = (Instr) vector_size(&emit->code->instr) ? (Instr)vector_back(&emit->code->instr) : emit_add_instr(emit, RegPushImm); back->opcode = ePushStaticCode; @@ -1078,17 +1084,15 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) { const Instr instr = emit_add_instr(emit, (f_instr)(m_uint)exec); instr->m_val = val; instr->m_val2 = val2; - } else if(f != emit->env->func && !f->code&& ! is_fptr(emit->gwion, f->value_ref->type)){ + } else if(f != emit->env->func && !f->code && !is_fptr(emit->gwion, f->value_ref->type)){ /* not yet emitted static func */ if(f->value_ref->from->owner_class) { const Instr instr = vector_size(&emit->code->instr) ? (Instr)vector_back(&emit->code->instr) : emit_add_instr(emit, PushStaticCode); assert(instr->opcode == ePushStaticCode); instr->opcode = eRegPushImm; - } else { - const Instr pushcode = emit_add_instr(emit, PushStaticCode); - pushcode->m_val = (m_uint)f; - } + } else + emit_mod_func(emit, f); } const m_uint offset = emit_code_offset(emit); regseti(emit, offset); @@ -2042,9 +2046,9 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) { const Type t = cdef->base.type; if(GET_FLAG(t, emit)) return GW_OK; + SET_FLAG(t, emit); if(cdef->base.ext && t->e->parent->e->def && !GET_FLAG(t->e->parent, emit)) CHECK_BB(cdef_parent(emit, cdef)) - SET_FLAG(t, emit); nspc_allocdata(emit->gwion->mp, t->nspc); if(cdef->body) { emit_class_code(emit, t->name); diff --git a/src/emit/modify_instr.c b/src/emit/modify_instr.c new file mode 100644 index 00000000..488f5658 --- /dev/null +++ b/src/emit/modify_instr.c @@ -0,0 +1,52 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "gwion_env.h" +#include "vm.h" +#include "gwion.h" +#include "instr.h" +#include "emit.h" + +// should be in vm.h +#define VAL (*(m_uint*)(byte + SZ_INT)) +#define FVAL (*(m_float*)(byte + SZ_INT)) +#define VAL2 (*(m_uint*)(byte + SZ_INT*2)) +/* +ANN static void set_recurs(m_bit *byte, m_bit **reg) { + *(m_bit*)byte = eRegPushImm; + VAL = (*(m_uint*)(*reg-SZ_INT) = ); + VAL2 = -SZ_INT; +// copy from vm_code +} +*/ + +ANN static void set_func(m_bit *byte, m_bit **reg) { + *(m_bit*)byte = eRegSetImm; + VAL = (*(m_uint*)(*reg-SZ_INT) = (m_uint)((Func)VAL)->code); + VAL2 = -SZ_INT; +// copy from vm_code +} + +ANN static void set_ctor(m_bit *byte, m_bit *reg) { + *(m_bit*)byte = eRegSetImm; + VAL = (*(m_uint*)(reg+SZ_INT) = (m_uint)((Type)VAL)->nspc->pre_ctor); + VAL2 = SZ_INT; +} + +ANN void emit_mod_recurs(const Emitter emit) { + const Instr instr = vector_size(&emit->code->instr) ? + (Instr)vector_back(&emit->code->instr) : emit_add_instr(emit, RegPushImm); + instr->opcode = ePushStaticCode; + instr->m_val = 0; +} + +ANN void emit_mod_func(const Emitter emit, const Func f) { + const Instr instr = emit_add_instr(emit, PushStaticCode); + instr->m_val = (m_uint)f; + instr->m_val2 = (m_uint)set_func; +} + +ANN void emit_mod_ctor(const Emitter emit, const Type t) { + const Instr instr = emit_add_instr(emit, PushStaticCode); + instr->m_val = (m_uint)t; + instr->m_val2 = (m_uint)set_ctor; +} diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 1ae6d759..7f9e3188 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -264,9 +264,12 @@ OP_EMIT(opem_object_dot) { CHECK_BO(emit_exp(emit, member->base)) emit_struct_data(emit, value, exp_getvar(exp_self(member))); } - } - else if(GET_FLAG(value, static)) + } else if(GET_FLAG(value, static)) emit_dot_static_import_data(emit, value, exp_getvar(exp_self(member))); + else { // member type + const Instr instr = emit_add_instr(emit, RegPushImm); + instr->m_val = (m_uint)value->type; + } return (Instr)GW_OK; } diff --git a/src/parse/check.c b/src/parse/check.c index 74f902b5..e3f1adca 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -1406,8 +1406,10 @@ ANN m_bool check_class_def(const Env env, const Class_Def cdef) { CHECK_BB(cdef_parent(env, cdef)) if(!GET_FLAG(cdef, struct)) inherit(t); - if(cdef->body) + if(cdef->body) { CHECK_BB(env_body(env, cdef, check_section)) + SET_FLAG(t, ctor); + } SET_FLAG(t, valid); return GW_OK; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 1c700c47..6ae61648 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -28,20 +28,10 @@ ANN static inline m_bool ensure_scan1(const Env env, const Type t) { return envset_run(&es, t); } -ANN static m_bool type_recursive(const Env env, const Type_Decl *td, const Type t) { - const Type base = get_type(t); - if(!GET_FLAG(td, ref) && env->class_def && !env->scope->depth && - base == env->class_def) { - ERR_B(td_pos(td), _("%s declared inside %s\n. (make it a ref ?)"), - t->name, t == env->class_def ? "itself" : env->class_def->name); - } - return GW_OK; -} - ANN static Type scan1_type(const Env env, Type_Decl* td) { DECL_OO(const Type, type, = known_type(env, td)) const Type t = get_type(type); - if(!env->func && env->class_def) + if(!env->func && env->class_def && !GET_FLAG(td, ref)) CHECK_BO(type_cyclic(env, t, td)) if(!GET_FLAG(t, scan1) && t->e->def) CHECK_BO(ensure_scan1(env, t)) @@ -50,8 +40,6 @@ ANN static Type scan1_type(const Env env, Type_Decl* td) { ANN static Type void_type(const Env env, Type_Decl* td) { DECL_OO(const Type, type, = scan1_type(env, td)) - if(isa(type, env->gwion->type[et_compound]) > 0) - CHECK_BO(type_recursive(env, td, type)) if(type->size) return type; ERR_O(td_pos(td), _("cannot declare variables of size '0' (i.e. 'void')...")) diff --git a/src/vm/vm.c b/src/vm/vm.c index 349f959c..06751199 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -14,7 +14,7 @@ #include "map_private.h" #include "gack.h" #include "array.h" - +#include "modify_instr.h" static inline uint64_t splitmix64_stateless(uint64_t index) { uint64_t z = (index + UINT64_C(0x9E3779B97F4A7C15)); @@ -837,10 +837,8 @@ PRAGMA_PUSH() *(VM_Code*)(reg-SZ_INT) = ((Func)vector_at(a.obj->vtable, VAL))->code; PRAGMA_POP() DISPATCH() -pushstaticcode: - *(m_bit*)byte = eRegSetImm; - VAL = (*(m_uint*)(reg-SZ_INT) = (m_uint)((Func)VAL)->code); - VAL2 = -SZ_INT; +pushstaticcode: // TODO: use external instr + ((instr_modifier)VAL2)(byte, reg); DISPATCH() gcini: vector_add(&shred->gc, 0);