internal static bool TryFreeGCHandle(BorrowedReference reflectedClrObject, BorrowedReference type) { Debug.Assert(type != null); Debug.Assert(reflectedClrObject != null); Debug.Assert(IsManagedType(type) || IsManagedType(reflectedClrObject)); Debug.Assert(Runtime.PyObject_TypeCheck(reflectedClrObject, type)); int offset = Util.ReadInt32(type, Offsets.tp_clr_inst_offset); Debug.Assert(offset > 0); IntPtr raw = Util.ReadIntPtr(reflectedClrObject, offset); if (raw == IntPtr.Zero) { return(false); } var handle = (GCHandle)raw; handle.Free(); Util.WriteIntPtr(reflectedClrObject, offset, IntPtr.Zero); return(true); }
internal static void GetGCHandle(BorrowedReference reflectedClrObject, BorrowedReference type, out IntPtr handle) { Debug.Assert(reflectedClrObject != null); Debug.Assert(IsManagedType(type) || IsManagedType(reflectedClrObject)); Debug.Assert(Runtime.PyObject_TypeCheck(reflectedClrObject, type)); int gcHandleOffset = Util.ReadInt32(type, Offsets.tp_clr_inst_offset); Debug.Assert(gcHandleOffset > 0); handle = Util.ReadIntPtr(reflectedClrObject, gcHandleOffset); }
internal static void DumpInst(BorrowedReference ob) { BorrowedReference tp = Runtime.PyObject_TYPE(ob); nint sz = Util.ReadIntPtr(tp, TypeOffset.tp_basicsize); for (nint i = 0; i < sz; i += IntPtr.Size) { var pp = new IntPtr(ob.DangerousGetAddress().ToInt64() + i); IntPtr v = Marshal.ReadIntPtr(pp); Console.WriteLine("offset {0}: {1}", i, v); } Console.WriteLine(""); Console.WriteLine(""); }
internal static void DumpType(BorrowedReference type) { IntPtr op = Util.ReadIntPtr(type, TypeOffset.tp_name); string name = Marshal.PtrToStringAnsi(op); Console.WriteLine("Dump type: {0}", name); var objMember = Util.ReadRef(type, TypeOffset.ob_type); Print(" type: ", objMember); objMember = Util.ReadRef(type, TypeOffset.tp_base); Print(" base: ", objMember); objMember = Util.ReadRef(type, TypeOffset.tp_bases); Print(" bases: ", objMember); //op = Util.ReadIntPtr(type, TypeOffset.tp_mro); //DebugUtil.Print(" mro: ", op); var slots = TypeOffset.GetOffsets(); int size = IntPtr.Size; foreach (var entry in slots) { int offset = entry.Value; name = entry.Key; op = Util.ReadIntPtr(type, offset); Console.WriteLine(" {0}: {1}", name, op); } Console.WriteLine(""); Console.WriteLine(""); objMember = Util.ReadRef(type, TypeOffset.tp_dict); if (objMember == null) { Console.WriteLine(" dict: null"); } else { Print(" dict: ", objMember); } }
internal static unsafe void DecrefTypeAndFree(StolenReference ob) { if (ob == null) { throw new ArgumentNullException(nameof(ob)); } var borrowed = new BorrowedReference(ob.DangerousGetAddress()); var type = Runtime.PyObject_TYPE(borrowed); var freePtr = Util.ReadIntPtr(type, TypeOffset.tp_free); Debug.Assert(freePtr != IntPtr.Zero); var free = (delegate * unmanaged[Cdecl] < StolenReference, void >)freePtr; free(ob); Runtime.XDecref(StolenReference.DangerousFromPointer(type.DangerousGetAddress())); }
/// <summary> /// Wrapper for calling tp_clear /// </summary> internal static unsafe int CallTypeClear(BorrowedReference ob, BorrowedReference tp) { if (ob == null) { throw new ArgumentNullException(nameof(ob)); } if (tp == null) { throw new ArgumentNullException(nameof(tp)); } var clearPtr = Util.ReadIntPtr(tp, TypeOffset.tp_clear); if (clearPtr == IntPtr.Zero) { return(0); } var clearFunc = (delegate * unmanaged[Cdecl] < BorrowedReference, int >)clearPtr; return(clearFunc(ob)); }