From: Jérémie Astor Date: Tue, 5 Jan 2021 13:18:09 +0000 (+0100) Subject: :art: Introduce struct_addref functions X-Git-Tag: nightly~1059 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=4e48c9573e3cedf06f87ee248138987b24b369e7;p=gwion.git :art: Introduce struct_addref functions --- diff --git a/include/emit.h b/include/emit.h index 34c700dd..a144705d 100644 --- a/include/emit.h +++ b/include/emit.h @@ -47,4 +47,12 @@ ANN static inline void emit_gc(const Emitter emit, const m_int offset) { const Instr gc = emit_add_instr(emit, GcAdd); gc->m_val = offset; } + + +ANN Instr emit_object_addref(const Emitter emit, const m_int size, const m_bool emit_var); +ANN Instr emit_struct_addref(const Emitter emit, const Type t, const m_int size, const m_bool emit_var); +ANN static inline Instr emit_compound_addref(const Emitter emit, const Type t, const m_int size, const m_bool emit_var) { + return !tflag(t, tflag_struct) ? emit_object_addref(emit, size, emit_var) : + emit_struct_addref(emit, t, size, emit_var); +} #endif diff --git a/include/object.h b/include/object.h index 9ea5ee1a..2ed67898 100644 --- a/include/object.h +++ b/include/object.h @@ -41,6 +41,19 @@ typedef void (f_release)(const VM_Shred shred, const Type t NUSED, const m_bit* #define RELEASE_FUNC(a) void (a)(const VM_Shred shred, const Type t NUSED, const m_bit* ptr) static inline RELEASE_FUNC(object_release) { release(*(M_Object*)ptr, shred); } RELEASE_FUNC(struct_release); + +static inline void struct_addref(const Gwion gwion, const Type type, const m_bit* ptr) { + 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, gwion->type[et_object]) > 0) { + const M_Object o = *(M_Object*)(ptr + vector_at(&type->info->tuple->offset, i)); + ++o->ref; + } else if(tflag(t, tflag_struct)) { + struct_addref(gwion, t, *(m_bit**)(ptr + vector_at(&type->info->tuple->offset, i))); + } + } +} + static inline void compound_release(const VM_Shred shred, const Type t, const m_bit* ptr) { if(!tflag(t, tflag_struct)) object_release(shred, t, ptr); diff --git a/include/opcode.h b/include/opcode.h index 60813e0d..d534088e 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -153,6 +153,8 @@ enum { eObjectInstantiate, eRegAddRef, eRegAddRefAddr, + eStructRegAddRef, + eStructRegAddRefAddr, eObjectAssign, eAssign, eObjectRelease, @@ -188,189 +190,191 @@ enum { eDotTmplVal, }; -#define RegSetImm (f_instr)eRegSetImm -#define RegPushImm (f_instr)eRegPushImm -#define RegPushImm2 (f_instr)eRegPushImm2 -#define RegPushImm3 (f_instr)eRegPushImm3 -#define RegPushImm4 (f_instr)eRegPushImm4 -#define RegPushMem (f_instr)eRegPushMem -#define RegPushMem2 (f_instr)eRegPushMem2 -#define RegPushMem3 (f_instr)eRegPushMem3 -#define RegPushMem4 (f_instr)eRegPushMem4 -#define RegPushMemDeref (f_instr)eRegPushMemDeref -#define RegPushNow (f_instr)eRegPushNow -#define RegPushBase (f_instr)eRegPushBase -#define RegPushBase2 (f_instr)eRegPushBase2 -#define RegPushBase3 (f_instr)eRegPushBase3 -#define RegPushBase4 (f_instr)eRegPushBase4 -#define Reg2Reg (f_instr)eReg2Reg -#define Reg2RegOther (f_instr)eReg2RegOther -#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 -#define RegPushMaybe (f_instr)eRegPushMaybe -#define FuncReturn (f_instr)eFuncReturn -#define Goto (f_instr)eGoto -#define AllocWord (f_instr)eAllocWord -#define AllocWord2 (f_instr)eAllocWord2 -#define AllocWord3 (f_instr)eAllocWord3 -#define int_plus (f_instr)eint_plus -#define int_minus (f_instr)eint_minus -#define int_mul (f_instr)eint_mul -#define int_div (f_instr)eint_div -#define int_modulo (f_instr)eint_modulo -#define int_eq (f_instr)eint_eq -#define int_neq (f_instr)eint_neq -#define int_and (f_instr)eint_and -#define int_or (f_instr)eint_or -#define int_gt (f_instr)eint_gt -#define int_ge (f_instr)eint_ge -#define int_lt (f_instr)eint_lt -#define int_le (f_instr)eint_le -#define int_sl (f_instr)eint_sl -#define int_sr (f_instr)eint_sr -#define int_sand (f_instr)eint_sand -#define int_sor (f_instr)eint_sor -#define int_xor (f_instr)eint_xor -#define int_negate (f_instr)eint_negate -#define IntNot (f_instr)eIntNot -#define int_cmp (f_instr)eint_cmp -#define int_r_assign (f_instr)eint_r_assign -#define int_r_plus (f_instr)eint_r_plus -#define int_r_minus (f_instr)eint_r_minus -#define int_r_mul (f_instr)eint_r_mul -#define int_r_div (f_instr)eint_r_div -#define int_r_modulo (f_instr)eint_r_modulo -#define int_r_sl (f_instr)eint_r_sl -#define int_r_sr (f_instr)eint_r_sr -#define int_r_sand (f_instr)eint_r_sand -#define int_r_sor (f_instr)eint_r_sor -#define int_r_sxor (f_instr)eint_r_sxor -#define int_pre_inc (f_instr)eint_pre_inc -#define int_pre_dec (f_instr)eint_pre_dec -#define int_post_inc (f_instr)eint_post_inc -#define int_post_dec (f_instr)eint_post_dec -#define FloatPlus (f_instr)eFloatPlus -#define FloatMinus (f_instr)eFloatMinus -#define FloatTimes (f_instr)eFloatTimes -#define FloatDivide (f_instr)eFloatDivide -#define float_and (f_instr)efloat_and -#define float_or (f_instr)efloat_or -#define float_eq (f_instr)efloat_eq -#define float_neq (f_instr)efloat_neq -#define float_gt (f_instr)efloat_gt -#define float_ge (f_instr)efloat_ge -#define float_lt (f_instr)efloat_lt -#define float_le (f_instr)efloat_le -#define float_negate (f_instr)efloat_negate -#define float_not (f_instr)efloat_not -#define float_r_assign (f_instr)efloat_r_assign -#define float_r_plus (f_instr)efloat_r_plus -#define float_r_minus (f_instr)efloat_r_minus -#define float_r_mul (f_instr)efloat_r_mul -#define float_r_div (f_instr)efloat_r_div -#define int_float_plus (f_instr)eint_float_plus -#define int_float_minus (f_instr)eint_float_minus -#define int_float_mul (f_instr)eint_float_mul -#define int_float_div (f_instr)eint_float_div -#define int_float_and (f_instr)eint_float_and -#define int_float_or (f_instr)eint_float_or -#define int_float_eq (f_instr)eint_float_eq -#define int_float_neq (f_instr)eint_float_neq -#define int_float_gt (f_instr)eint_float_gt -#define int_float_ge (f_instr)eint_float_ge -#define int_float_lt (f_instr)eint_float_lt -#define int_float_le (f_instr)eint_float_le -#define int_float_r_assign (f_instr)eint_float_r_assign -#define int_float_r_plus (f_instr)eint_float_r_plus -#define int_float_r_minus (f_instr)eint_float_r_minus -#define int_float_r_mul (f_instr)eint_float_r_mul -#define int_float_r_div (f_instr)eint_float_r_div -#define float_int_plus (f_instr)efloat_int_plus -#define float_int_minus (f_instr)efloat_int_minus -#define float_int_mul (f_instr)efloat_int_mul -#define float_int_div (f_instr)efloat_int_div -#define float_int_and (f_instr)efloat_int_and -#define float_int_or (f_instr)efloat_int_or -#define float_int_eq (f_instr)efloat_int_eq -#define float_int_neq (f_instr)efloat_int_neq -#define float_int_gt (f_instr)efloat_int_gt -#define float_int_ge (f_instr)efloat_int_ge -#define float_int_lt (f_instr)efloat_int_lt -#define float_int_le (f_instr)efloat_int_le -#define float_int_r_assign (f_instr)efloat_int_r_assign -#define float_int_r_plus (f_instr)efloat_int_r_plus -#define float_int_r_minus (f_instr)efloat_int_r_minus -#define float_int_r_mul (f_instr)efloat_int_r_mul -#define float_int_r_div (f_instr)efloat_int_r_div -#define CastI2F (f_instr)eCastI2F -#define CastF2I (f_instr)eCastF2I -#define Time_Advance (f_instr)eTime_Advance -#define SetCode (f_instr)eSetCode -#define RegMove (f_instr)eRegMove -#define Reg2Mem (f_instr)eReg2Mem -#define Reg2Mem4 (f_instr)eReg2Mem4 -#define Overflow (f_instr)eOverflow -#define FuncUsrEnd (f_instr)eFuncUsrEnd -#define FuncMemberEnd (f_instr)eFuncMemberEnd -#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 SporkEnd (f_instr)eSporkEnd -#define BranchEqInt (f_instr)eBranchEqInt -#define BranchNeqInt (f_instr)eBranchNeqInt -#define BranchEqFloat (f_instr)eBranchEqFloat -#define BranchNeqFloat (f_instr)eBranchNeqFloat -#define ArrayAppend (f_instr)eArrayAppend -#define AutoLoop (f_instr)eAutoLoop -#define AutoLoopPtr (f_instr)eAutoLoopPtr -#define AutoLoopCount (f_instr)eAutoLoopCount -#define ArrayTop (f_instr)eArrayTop -#define ArrayAccess (f_instr)eArrayAccess -#define ArrayGet (f_instr)eArrayGet -#define ArrayAddr (f_instr)eArrayAddr -#define ArrayValid (f_instr)eArrayValid -#define ObjectInstantiate (f_instr)eObjectInstantiate -#define RegAddRef (f_instr)eRegAddRef -#define RegAddRefAddr (f_instr)eRegAddRefAddr -#define ObjectAssign (f_instr)eObjectAssign -#define Assign (f_instr)eAssign -#define ObjectRelease (f_instr)eObjectRelease -#define GWOP_EXCEPT (f_instr)eGWOP_EXCEPT -#define AllocMember4 (f_instr)eAllocMember4 -#define DotMember (f_instr)eDotMember -#define DotMember2 (f_instr)eDotMember2 -#define DotMember3 (f_instr)eDotMember3 -#define DotMember4 (f_instr)eDotMember4 -#define UnionCheck (f_instr)eUnionCheck -#define UnionMember (f_instr)eUnionMember -#define UnionMember2 (f_instr)eUnionMember2 -#define UnionMember3 (f_instr)eUnionMember3 -#define UnionMember4 (f_instr)eUnionMember4 -#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 DotStaticFunc (f_instr)eDotStaticFunc -#define GcIni (f_instr)eGcIni -#define GcAdd (f_instr)eGcAdd -#define GcEnd (f_instr)eGcEnd -#define GackType (f_instr)eGackType -#define GackEnd (f_instr)eGackEnd -#define Gack (f_instr)eGack -#define NoOp (f_instr)eNoOp -#define EOC (f_instr)eEOC -#define OP_MAX (f_instr)eOP_MAX -#define DotTmplVal (f_instr)eDotTmplVal +#define RegSetImm (f_instr)eRegSetImm +#define RegPushImm (f_instr)eRegPushImm +#define RegPushImm2 (f_instr)eRegPushImm2 +#define RegPushImm3 (f_instr)eRegPushImm3 +#define RegPushImm4 (f_instr)eRegPushImm4 +#define RegPushMem (f_instr)eRegPushMem +#define RegPushMem2 (f_instr)eRegPushMem2 +#define RegPushMem3 (f_instr)eRegPushMem3 +#define RegPushMem4 (f_instr)eRegPushMem4 +#define RegPushMemDeref (f_instr)eRegPushMemDeref +#define RegPushNow (f_instr)eRegPushNow +#define RegPushBase (f_instr)eRegPushBase +#define RegPushBase2 (f_instr)eRegPushBase2 +#define RegPushBase3 (f_instr)eRegPushBase3 +#define RegPushBase4 (f_instr)eRegPushBase4 +#define Reg2Reg (f_instr)eReg2Reg +#define Reg2RegOther (f_instr)eReg2RegOther +#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 +#define RegPushMaybe (f_instr)eRegPushMaybe +#define FuncReturn (f_instr)eFuncReturn +#define Goto (f_instr)eGoto +#define AllocWord (f_instr)eAllocWord +#define AllocWord2 (f_instr)eAllocWord2 +#define AllocWord3 (f_instr)eAllocWord3 +#define int_plus (f_instr)eint_plus +#define int_minus (f_instr)eint_minus +#define int_mul (f_instr)eint_mul +#define int_div (f_instr)eint_div +#define int_modulo (f_instr)eint_modulo +#define int_eq (f_instr)eint_eq +#define int_neq (f_instr)eint_neq +#define int_and (f_instr)eint_and +#define int_or (f_instr)eint_or +#define int_gt (f_instr)eint_gt +#define int_ge (f_instr)eint_ge +#define int_lt (f_instr)eint_lt +#define int_le (f_instr)eint_le +#define int_sl (f_instr)eint_sl +#define int_sr (f_instr)eint_sr +#define int_sand (f_instr)eint_sand +#define int_sor (f_instr)eint_sor +#define int_xor (f_instr)eint_xor +#define int_negate (f_instr)eint_negate +#define IntNot (f_instr)eIntNot +#define int_cmp (f_instr)eint_cmp +#define int_r_assign (f_instr)eint_r_assign +#define int_r_plus (f_instr)eint_r_plus +#define int_r_minus (f_instr)eint_r_minus +#define int_r_mul (f_instr)eint_r_mul +#define int_r_div (f_instr)eint_r_div +#define int_r_modulo (f_instr)eint_r_modulo +#define int_r_sl (f_instr)eint_r_sl +#define int_r_sr (f_instr)eint_r_sr +#define int_r_sand (f_instr)eint_r_sand +#define int_r_sor (f_instr)eint_r_sor +#define int_r_sxor (f_instr)eint_r_sxor +#define int_pre_inc (f_instr)eint_pre_inc +#define int_pre_dec (f_instr)eint_pre_dec +#define int_post_inc (f_instr)eint_post_inc +#define int_post_dec (f_instr)eint_post_dec +#define FloatPlus (f_instr)eFloatPlus +#define FloatMinus (f_instr)eFloatMinus +#define FloatTimes (f_instr)eFloatTimes +#define FloatDivide (f_instr)eFloatDivide +#define float_and (f_instr)efloat_and +#define float_or (f_instr)efloat_or +#define float_eq (f_instr)efloat_eq +#define float_neq (f_instr)efloat_neq +#define float_gt (f_instr)efloat_gt +#define float_ge (f_instr)efloat_ge +#define float_lt (f_instr)efloat_lt +#define float_le (f_instr)efloat_le +#define float_negate (f_instr)efloat_negate +#define float_not (f_instr)efloat_not +#define float_r_assign (f_instr)efloat_r_assign +#define float_r_plus (f_instr)efloat_r_plus +#define float_r_minus (f_instr)efloat_r_minus +#define float_r_mul (f_instr)efloat_r_mul +#define float_r_div (f_instr)efloat_r_div +#define int_float_plus (f_instr)eint_float_plus +#define int_float_minus (f_instr)eint_float_minus +#define int_float_mul (f_instr)eint_float_mul +#define int_float_div (f_instr)eint_float_div +#define int_float_and (f_instr)eint_float_and +#define int_float_or (f_instr)eint_float_or +#define int_float_eq (f_instr)eint_float_eq +#define int_float_neq (f_instr)eint_float_neq +#define int_float_gt (f_instr)eint_float_gt +#define int_float_ge (f_instr)eint_float_ge +#define int_float_lt (f_instr)eint_float_lt +#define int_float_le (f_instr)eint_float_le +#define int_float_r_assign (f_instr)eint_float_r_assign +#define int_float_r_plus (f_instr)eint_float_r_plus +#define int_float_r_minus (f_instr)eint_float_r_minus +#define int_float_r_mul (f_instr)eint_float_r_mul +#define int_float_r_div (f_instr)eint_float_r_div +#define float_int_plus (f_instr)efloat_int_plus +#define float_int_minus (f_instr)efloat_int_minus +#define float_int_mul (f_instr)efloat_int_mul +#define float_int_div (f_instr)efloat_int_div +#define float_int_and (f_instr)efloat_int_and +#define float_int_or (f_instr)efloat_int_or +#define float_int_eq (f_instr)efloat_int_eq +#define float_int_neq (f_instr)efloat_int_neq +#define float_int_gt (f_instr)efloat_int_gt +#define float_int_ge (f_instr)efloat_int_ge +#define float_int_lt (f_instr)efloat_int_lt +#define float_int_le (f_instr)efloat_int_le +#define float_int_r_assign (f_instr)efloat_int_r_assign +#define float_int_r_plus (f_instr)efloat_int_r_plus +#define float_int_r_minus (f_instr)efloat_int_r_minus +#define float_int_r_mul (f_instr)efloat_int_r_mul +#define float_int_r_div (f_instr)efloat_int_r_div +#define CastI2F (f_instr)eCastI2F +#define CastF2I (f_instr)eCastF2I +#define Time_Advance (f_instr)eTime_Advance +#define SetCode (f_instr)eSetCode +#define RegMove (f_instr)eRegMove +#define Reg2Mem (f_instr)eReg2Mem +#define Reg2Mem4 (f_instr)eReg2Mem4 +#define Overflow (f_instr)eOverflow +#define FuncUsrEnd (f_instr)eFuncUsrEnd +#define FuncMemberEnd (f_instr)eFuncMemberEnd +#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 SporkEnd (f_instr)eSporkEnd +#define BranchEqInt (f_instr)eBranchEqInt +#define BranchNeqInt (f_instr)eBranchNeqInt +#define BranchEqFloat (f_instr)eBranchEqFloat +#define BranchNeqFloat (f_instr)eBranchNeqFloat +#define ArrayAppend (f_instr)eArrayAppend +#define AutoLoop (f_instr)eAutoLoop +#define AutoLoopPtr (f_instr)eAutoLoopPtr +#define AutoLoopCount (f_instr)eAutoLoopCount +#define ArrayTop (f_instr)eArrayTop +#define ArrayAccess (f_instr)eArrayAccess +#define ArrayGet (f_instr)eArrayGet +#define ArrayAddr (f_instr)eArrayAddr +#define ArrayValid (f_instr)eArrayValid +#define ObjectInstantiate (f_instr)eObjectInstantiate +#define RegAddRef (f_instr)eRegAddRef +#define RegAddRefAddr (f_instr)eRegAddRefAddr +#define StructRegAddRef (f_instr)eStructRegAddRef +#define StructRegAddRefAddr (f_instr)eStructRegAddRefAddr +#define ObjectAssign (f_instr)eObjectAssign +#define Assign (f_instr)eAssign +#define ObjectRelease (f_instr)eObjectRelease +#define GWOP_EXCEPT (f_instr)eGWOP_EXCEPT +#define AllocMember4 (f_instr)eAllocMember4 +#define DotMember (f_instr)eDotMember +#define DotMember2 (f_instr)eDotMember2 +#define DotMember3 (f_instr)eDotMember3 +#define DotMember4 (f_instr)eDotMember4 +#define UnionCheck (f_instr)eUnionCheck +#define UnionMember (f_instr)eUnionMember +#define UnionMember2 (f_instr)eUnionMember2 +#define UnionMember3 (f_instr)eUnionMember3 +#define UnionMember4 (f_instr)eUnionMember4 +#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 DotStaticFunc (f_instr)eDotStaticFunc +#define GcIni (f_instr)eGcIni +#define GcAdd (f_instr)eGcAdd +#define GcEnd (f_instr)eGcEnd +#define GackType (f_instr)eGackType +#define GackEnd (f_instr)eGackEnd +#define Gack (f_instr)eGack +#define NoOp (f_instr)eNoOp +#define EOC (f_instr)eEOC +#define OP_MAX (f_instr)eOP_MAX +#define DotTmplVal (f_instr)eDotTmplVal #endif diff --git a/src/emit/emit.c b/src/emit/emit.c index acfcbf6f..44ddd2f3 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -466,39 +466,26 @@ ANN static inline m_uint exp_totalsize(Exp e) { return size; } -ANN static Instr emit_addref(const Emitter emit, const m_bool emit_var) { +ANN Instr emit_object_addref(const Emitter emit, const m_int size, const m_bool emit_var) { const f_instr exec = !emit_var ? RegAddRef : RegAddRefAddr; const Instr instr = emit_add_instr(emit, exec); - instr->m_val = -SZ_INT; + instr->m_val = size; return instr; } -ANN static void struct_addref(const Emitter emit, const Type type, - const m_int size, const m_bool offset, const m_bool emit_var) { - if(!type->info->tuple) - return; - 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_addref(emit, emit_var); - instr->m_val = size; - instr->m_val2 = vector_at(&type->info->tuple->offset, i); - } else if(tflag(t, tflag_struct)) - struct_addref(emit, t, size, offset + vector_at(&type->info->tuple->offset, i), emit_var); - } +ANN Instr emit_struct_addref(const Emitter emit, const Type t, const m_int size, const m_bool emit_var) { + const Instr instr = emit_add_instr(emit, !emit_var ? StructRegAddRef : StructRegAddRefAddr); + instr->m_val = (m_uint)t; + instr->m_val2 = size; + return instr; } -ANN2(1) static void emit_exp_addref1(const Emitter emit, /* const */Exp exp, m_int size) { - if(isa(exp->type, emit->gwion->type[et_object]) > 0 && - (exp->cast_to ? isa(exp->cast_to, emit->gwion->type[et_object]) > 0 : 1)) { - if(exp->exp_type == ae_exp_decl && GET_FLAG(exp->d.exp_decl.td, late) && !exp_getvar(exp)) { - const Instr instr = emit_add_instr(emit, GWOP_EXCEPT); - instr->m_val = size; - } - const Instr instr = emit_addref(emit, exp_getvar(exp)); - instr->m_val = size; - } else if(tflag(exp->type, tflag_struct)) // check cast_to ? - struct_addref(emit, exp->type, size, 0, exp_getvar(exp)); +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)); } ANN2(1) static void emit_exp_addref(const Emitter emit, /* const */Exp exp, m_int size) { @@ -635,7 +622,7 @@ ANN static m_bool emit_prim_str(const Emitter emit, const m_str *str) { if(!v->d.ptr) v->d.ptr = (m_uint*)new_string2(emit->gwion, NULL, s_name(sym)); regpushi(emit, (m_uint)v->d.ptr); - emit_addref(emit, 0); + emit_object_addref(emit, -SZ_INT, 0); return GW_OK; } @@ -728,7 +715,7 @@ ANN static m_bool decl_static(const Emitter emit, const Exp_Decl *decl, const Va CHECK_BB(emit_instantiate_decl(emit, v->type, decl->td, var_decl->array, is_ref)) CHECK_BB(emit_dot_static_data(emit, v, 1)) emit_add_instr(emit, Assign); -// (void)emit_addref(emit, 0); +// (void)emit_object_addref(emit, -SZ_INT, 0); regpop(emit, SZ_INT); emit->code = code; return GW_OK; @@ -837,7 +824,7 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl, push->m_val = -(missing_depth) * SZ_INT; } */ - (void)emit_addref(emit, emit_var); + (void)emit_object_addref(emit, -SZ_INT, emit_var); } else if(struct_ctor(v)) emit_struct_decl_finish(emit, v->type, emit_addr); return GW_OK; diff --git a/src/env/nspc.c b/src/env/nspc.c index e219b1d2..a528cf64 100644 --- a/src/env/nspc.c +++ b/src/env/nspc.c @@ -2,8 +2,8 @@ #include "gwion_ast.h" #include "gwion_env.h" #include "vm.h" -#include "object.h" #include "gwion.h" +#include "object.h" #include "operator.h" ANN void nspc_commit(const Nspc nspc) { diff --git a/src/env/tupleform.c b/src/env/tupleform.c index b8a3fbf9..5e215440 100644 --- a/src/env/tupleform.c +++ b/src/env/tupleform.c @@ -3,10 +3,10 @@ #include "gwion_env.h" #include "vm.h" #include "instr.h" +#include "gwion.h" #include "object.h" #include "emit.h" #include "vm.h" -#include "gwion.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/import/cleaner.c b/src/import/cleaner.c index aeada70d..c2b860ef 100644 --- a/src/import/cleaner.c +++ b/src/import/cleaner.c @@ -7,9 +7,9 @@ #include "vm.h" #include "traverse.h" #include "instr.h" -#include "object.h" #include "emit.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/import/import_cdef.c b/src/import/import_cdef.c index 8f84f962..889eb1b2 100644 --- a/src/import/import_cdef.c +++ b/src/import/import_cdef.c @@ -7,9 +7,9 @@ #include "vm.h" #include "traverse.h" #include "instr.h" -#include "object.h" #include "emit.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/import/import_checker.c b/src/import/import_checker.c index 4c194d2b..1fbfc6b8 100644 --- a/src/import/import_checker.c +++ b/src/import/import_checker.c @@ -8,9 +8,9 @@ #include "vm.h" #include "traverse.h" #include "instr.h" -#include "object.h" #include "emit.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/import/import_enum.c b/src/import/import_enum.c index 4870b310..866c1d92 100644 --- a/src/import/import_enum.c +++ b/src/import/import_enum.c @@ -7,9 +7,9 @@ #include "vm.h" #include "traverse.h" #include "instr.h" -#include "object.h" #include "emit.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/import/import_fdef.c b/src/import/import_fdef.c index 10747f2c..f8b39276 100644 --- a/src/import/import_fdef.c +++ b/src/import/import_fdef.c @@ -6,10 +6,10 @@ #include "gwion_env.h" #include "vm.h" #include "traverse.h" -#include "object.h" #include "instr.h" #include "emit.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/import/import_internals.c b/src/import/import_internals.c index 2c997ff2..9de5c531 100644 --- a/src/import/import_internals.c +++ b/src/import/import_internals.c @@ -4,8 +4,8 @@ #include "vm.h" #include "traverse.h" #include "instr.h" -#include "object.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/import/import_item.c b/src/import/import_item.c index 34bb6ab0..dd8311c4 100644 --- a/src/import/import_item.c +++ b/src/import/import_item.c @@ -4,8 +4,8 @@ #include "vm.h" #include "traverse.h" #include "instr.h" -#include "object.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/import/import_oper.c b/src/import/import_oper.c index b9b03dd5..6ed6dada 100644 --- a/src/import/import_oper.c +++ b/src/import/import_oper.c @@ -7,9 +7,9 @@ #include "vm.h" #include "traverse.h" #include "instr.h" -#include "object.h" #include "emit.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/import/import_special.c b/src/import/import_special.c index c81690a4..f81684d8 100644 --- a/src/import/import_special.c +++ b/src/import/import_special.c @@ -7,9 +7,9 @@ #include "vm.h" #include "traverse.h" #include "instr.h" -#include "object.h" #include "emit.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/import/import_tdef.c b/src/import/import_tdef.c index 77e4764e..f0712a16 100644 --- a/src/import/import_tdef.c +++ b/src/import/import_tdef.c @@ -7,9 +7,9 @@ #include "vm.h" #include "traverse.h" #include "instr.h" -#include "object.h" #include "emit.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/import/import_type.c b/src/import/import_type.c index 75ee489b..f1ed62e7 100644 --- a/src/import/import_type.c +++ b/src/import/import_type.c @@ -7,9 +7,9 @@ #include "vm.h" #include "traverse.h" #include "instr.h" -#include "object.h" #include "emit.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/import/import_udef.c b/src/import/import_udef.c index 2e9dfc21..4efd3884 100644 --- a/src/import/import_udef.c +++ b/src/import/import_udef.c @@ -7,9 +7,9 @@ #include "vm.h" #include "traverse.h" #include "instr.h" -#include "object.h" #include "emit.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/lib/array.c b/src/lib/array.c index d3b62012..56b162bc 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -413,7 +413,7 @@ GWION_IMPORT(array) { GWI_BB(gwi_class_end(gwi)) GWI_BB(gwi_oper_ini(gwi, "@Array", "@Array", NULL)) GWI_BB(gwi_oper_add(gwi, opck_array_at)) - GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign)) + GWI_BB(gwi_oper_end(gwi, "@=>", NULL)) GWI_BB(gwi_oper_ini(gwi, "@Array", (m_str)OP_ANY_TYPE, NULL)) GWI_BB(gwi_oper_add(gwi, opck_array_sl)) GWI_BB(gwi_oper_emi(gwi, opem_array_sl)) diff --git a/src/lib/engine.c b/src/lib/engine.c index a073b049..ec85614c 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -3,9 +3,9 @@ #include "gwion_env.h" #include "vm.h" #include "instr.h" -#include "object.h" #include "emit.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/lib/instr.c b/src/lib/instr.c index ba55288f..f022ddb1 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -5,10 +5,10 @@ #include "gwion_env.h" #include "vm.h" #include "instr.h" -#include "object.h" -#include "array.h" #include "shreduler_private.h" #include "gwion.h" +#include "object.h" +#include "array.h" #include "operator.h" #include "import.h" #include "emit.h" diff --git a/src/lib/object_op.c b/src/lib/object_op.c index f851ae69..2fdee4b2 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -27,7 +27,7 @@ static INSTR(name##Object) { \ describe_logical(Eq, ==) describe_logical(Neq, !=) -static OP_CHECK(at_object) { +static OP_CHECK(opck_object_at) { const Exp_Binary* bin = (Exp_Binary*)data; if(opck_rassign(env, data) == env->gwion->type[et_error]) return env->gwion->type[et_error]; @@ -38,6 +38,13 @@ static OP_CHECK(at_object) { return bin->rhs->type; } +static OP_EMIT(opem_object_at) { + const Instr addref = emit_add_instr(emit, RegAddRef); + addref->m_val = -SZ_INT*2; + (void)emit_add_instr(emit, ObjectAssign); + return GW_OK; +} + static OP_CHECK(opck_object_cast) { const Exp_Cast* cast = (Exp_Cast*)data; const Type to = known_type(env, cast->td); @@ -310,8 +317,9 @@ GWION_IMPORT(object_op) { gwi->gwion->type[et_error] = t_error; GWI_BB(gwi_set_global_type(gwi, t_error, et_error)) GWI_BB(gwi_oper_ini(gwi, "Object", "Object", NULL)) - GWI_BB(gwi_oper_add(gwi, at_object)) - GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign)) + GWI_BB(gwi_oper_add(gwi, opck_object_at)) + GWI_BB(gwi_oper_emi(gwi, opem_object_at)) + GWI_BB(gwi_oper_end(gwi, "@=>", NULL)) GWI_BB(gwi_oper_ini(gwi, "Object", "Object", "bool")) GWI_BB(gwi_oper_end(gwi, "==", EqObject)) GWI_BB(gwi_oper_end(gwi, "!=", NeqObject)) diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 7402d1fd..1e08e911 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -3,6 +3,7 @@ #include "gwion_env.h" #include "vm.h" #include "instr.h" +#include "gwion.h" #include "object.h" #include "emit.h" #include "traverse.h" diff --git a/src/lib/ptr.c b/src/lib/ptr.c index 069662bc..501fb696 100644 --- a/src/lib/ptr.c +++ b/src/lib/ptr.c @@ -44,28 +44,12 @@ static OP_CHECK(opck_ptr_assign) { return env->gwion->type[et_error]; } -static INSTR(instr_ptr_assign) { - m_bit **o = *(m_bit***)REG(0); - *o = *(m_bit**)REG(-SZ_INT); -} - -static INSTR(instr_ptr_assign_obj) { - m_bit **o = *(m_bit***)REG(0); - //release(*(M_Object*)o, shred); - // addref to object? - *o = *(m_bit**)REG(-SZ_INT); -} - static OP_EMIT(opem_ptr_assign) { - const Instr pop = emit_add_instr(emit, RegMove); - pop->m_val = -SZ_INT; const Exp_Binary* bin = (Exp_Binary*)data; - if(isa(bin->lhs->type, emit->gwion->type[et_object]) > 0) { - const Instr instr = emit_add_instr(emit, RegAddRefAddr); - instr->m_val = -SZ_INT; - emit_add_instr(emit, instr_ptr_assign_obj); - } else - emit_add_instr(emit, instr_ptr_assign); + const Type t = bin->lhs->cast_to ?: bin->lhs->type; + if(isa(t, emit->gwion->type[et_compound]) > 0) + (void)emit_compound_addref(emit, t, -(SZ_INT + t->size), 0); + emit_add_instr(emit, int_r_assign); return GW_OK; } diff --git a/src/lib/shred.c b/src/lib/shred.c index 60a20095..eb0a751d 100644 --- a/src/lib/shred.c +++ b/src/lib/shred.c @@ -4,9 +4,9 @@ #include "gwion_thread.h" #include "vm.h" #include "instr.h" -#include "object.h" #include "shreduler_private.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "emit.h" diff --git a/src/lib/string.c b/src/lib/string.c index 90b4c243..d40cce24 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -6,8 +6,8 @@ #include "gwion_env.h" #include "vm.h" #include "instr.h" -#include "object.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "emit.h" diff --git a/src/lib/union.c b/src/lib/union.c index bf368cdc..cb06211c 100644 --- a/src/lib/union.c +++ b/src/lib/union.c @@ -3,9 +3,9 @@ #include "gwion_env.h" #include "vm.h" #include "instr.h" -#include "object.h" #include "emit.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/lib/vararg.c b/src/lib/vararg.c index e24ac5e9..e723df45 100644 --- a/src/lib/vararg.c +++ b/src/lib/vararg.c @@ -4,9 +4,9 @@ #include "vm.h" #include "instr.h" #include "emit.h" -#include "object.h" #include "vararg.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gwi.h" diff --git a/src/parse/check.c b/src/parse/check.c index 840fe249..4fcb436f 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -3,10 +3,10 @@ #include "gwion_env.h" #include "vm.h" #include "instr.h" -#include "object.h" #include "traverse.h" #include "template.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "parse.h" diff --git a/src/parse/func_operator.c b/src/parse/func_operator.c index 2d794a8d..131fd2cc 100644 --- a/src/parse/func_operator.c +++ b/src/parse/func_operator.c @@ -3,8 +3,8 @@ #include "gwion_env.h" #include "vm.h" #include "instr.h" -#include "object.h" #include "gwion.h" +#include "object.h" #include "operator.h" ANN void func_operator(const Func_Def fdef, struct Op_Import *opi) { diff --git a/src/parse/func_resolve_tmpl.c b/src/parse/func_resolve_tmpl.c index ed5801b0..e46fd87a 100644 --- a/src/parse/func_resolve_tmpl.c +++ b/src/parse/func_resolve_tmpl.c @@ -3,10 +3,10 @@ #include "gwion_env.h" #include "vm.h" #include "instr.h" -#include "object.h" #include "traverse.h" #include "template.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "parse.h" diff --git a/src/parse/scan0.c b/src/parse/scan0.c index c333eb71..1b96133e 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -6,6 +6,7 @@ #include "traverse.h" #include "template.h" #include "parse.h" +#include "gwion.h" #include "object.h" #include "instr.h" #include "operator.h" diff --git a/src/parse/scan2.c b/src/parse/scan2.c index ced4e7b0..f5286ac4 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -6,6 +6,7 @@ #include "traverse.h" #include "parse.h" #include "operator.h" +#include "gwion.h" #include "object.h" #include "instr.h" #include "import.h" diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index d3fce42a..a00a7fbe 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -34,7 +34,5 @@ ANN static inline void* type_unknown(const Env env, const Type_Decl* td) { } ANN Type known_type(const Env env, Type_Decl* td) { - if(!td->xid) - return env->gwion->type[et_undefined]; return resolve(env, td) ?:type_unknown(env, td); } diff --git a/src/vm/closure.c b/src/vm/closure.c index b31b5871..df3a0539 100644 --- a/src/vm/closure.c +++ b/src/vm/closure.c @@ -3,10 +3,10 @@ #include "gwion_env.h" #include "vm.h" #include "instr.h" -#include "object.h" -#include "array.h" #include "memoize.h" #include "gwion.h" +#include "object.h" +#include "array.h" #include "operator.h" #include "import.h" diff --git a/src/vm/gack.c b/src/vm/gack.c index a4338d3f..3cbe9fe6 100644 --- a/src/vm/gack.c +++ b/src/vm/gack.c @@ -5,9 +5,9 @@ #include "gwion_ast.h" #include "gwion_env.h" #include "vm.h" -#include "object.h" #include "instr.h" #include "gwion.h" +#include "object.h" #include "operator.h" #include "import.h" #include "gack.h" diff --git a/src/vm/shreduler.c b/src/vm/shreduler.c index 0822589e..11c408a9 100644 --- a/src/vm/shreduler.c +++ b/src/vm/shreduler.c @@ -3,6 +3,7 @@ #include "gwion_ast.h" #include "gwion_env.h" #include "vm.h" +#include "gwion.h" #include "object.h" #include "driver.h" #include "shreduler_private.h" diff --git a/src/vm/vm.c b/src/vm/vm.c index fe7bc61b..6c076bf0 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -4,11 +4,11 @@ #include "gwion_env.h" #include "vm.h" #include "instr.h" -#include "object.h" -#include "ugen.h" #include "shreduler_private.h" #include "emit.h" #include "gwion.h" +#include "object.h" +#include "ugen.h" #include "operator.h" #include "import.h" #include "gack.h" @@ -322,7 +322,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] &&sporkini, &&forkini, &&sporkfunc, &&sporkmemberfptr, &&sporkexp, &&sporkend, &&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat, &&arrayappend, &&autoloop, &&autoloopptr, &&autoloopcount, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&arrayvalid, - &&newobj, &&addref, &&addrefaddr, &&objassign, &&assign, &&remref, + &&newobj, &&addref, &&addrefaddr, &&structaddref, &&structaddrefaddr, &&objassign, &&assign, &&remref, &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr, &&unioncheck, &&unionint, &&unionfloat, &&unionother, &&unionaddr, &&staticint, &&staticfloat, &&staticother, @@ -760,25 +760,28 @@ newobj: DISPATCH() addref: { - const M_Object o = *((M_Object*)(reg+(m_int)VAL) + (m_int)VAL2); + const M_Object o = *(M_Object*)(reg+(m_int)VAL); // if(o) ++o->ref; } DISPATCH() addrefaddr: { - const M_Object o = *(*(M_Object**)(reg+(m_int)VAL) + (m_int)VAL2); + const M_Object o = **(M_Object**)(reg+(m_int)VAL); if(o) ++o->ref; } DISPATCH() +structaddref: + struct_addref(vm->gwion, (Type)VAL2, *(m_bit**)(reg + (m_int)VAL)); + DISPATCH() +structaddrefaddr: + struct_addref(vm->gwion, (Type)VAL2, **(m_bit***)(reg + (m_int)VAL)); + DISPATCH() objassign: { const M_Object o = **(M_Object**)(reg -SZ_INT); - if(o) { - _release(o, shred); - } - ++(*(M_Object*)(reg -SZ_INT*2))->ref; + release(o, shred); } assign: reg -= SZ_INT; diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index 21b3acc3..dbd573ca 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -3,10 +3,10 @@ #include "gwion_env.h" #include "vm.h" #include "instr.h" -#include "object.h" -#include "array.h" #include "memoize.h" #include "gwion.h" +#include "object.h" +#include "array.h" #include "operator.h" #include "import.h" diff --git a/src/vm/vm_shred.c b/src/vm/vm_shred.c index 52795e6c..0864d7dd 100644 --- a/src/vm/vm_shred.c +++ b/src/vm/vm_shred.c @@ -2,8 +2,8 @@ #include "gwion_ast.h" #include "gwion_env.h" #include "vm.h" -#include "object.h" #include "gwion.h" +#include "object.h" struct Stack_ { VM_Shred shred;