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); }
/// <summary> /// For the operator methods of a CLR type, set the special slots of the /// corresponding Python type's operator methods. /// </summary> public static void FixupSlots(BorrowedReference pyType, Type clrType) { Debug.Assert(_opType != null); var operatorCandidates = GetOperatorCandidates(clrType); foreach (var method in operatorCandidates) { // We only want to override slots for operators excluding // comparison operators, which are handled by ClassBase.tp_richcompare. if (!OpMethodMap.ContainsKey(method.Name)) { continue; } int offset = OpMethodMap[method.Name].TypeOffset; // Copy the default implementation of e.g. the nb_add slot, // which simply calls __add__ on the type. IntPtr func = Util.ReadIntPtr(_opType !, offset); // Write the slot definition of the target Python type, so // that we can later modify __add___ and it will be called // when used with a Python operator. // https://tenthousandmeters.com/blog/python-behind-the-scenes-6-how-python-object-system-works/ Util.WriteIntPtr(pyType, offset, func); } }
internal static void SetGCHandle(BorrowedReference reflectedClrObject, BorrowedReference type, GCHandle newHandle) { 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); Util.WriteIntPtr(reflectedClrObject, offset, (IntPtr)newHandle); }