public virtual NewReference Alloc() { // Create a new PyObject whose type is a generated type that is // implemented by the particular concrete ExtensionType subclass. // The Python instance object is related to an instance of a // particular concrete subclass with a hidden CLR gchandle. BorrowedReference tp = TypeManager.GetTypeReference(GetType()); //int rc = (int)Util.ReadIntPtr(tp, TypeOffset.ob_refcnt); //if (rc > 1050) //{ // DebugUtil.Print("tp is: ", tp); // DebugUtil.DumpType(tp); //} NewReference py = Runtime.PyType_GenericAlloc(tp, 0); #if DEBUG GetGCHandle(py.BorrowOrThrow(), tp, out var existing); System.Diagnostics.Debug.Assert(existing == IntPtr.Zero); #endif SetupGc(py.Borrow(), tp); return(py); }
public new static void tp_dealloc(NewReference ob) { var self = (CLRObject?)GetManagedObject(ob.Borrow()); // don't let the python GC destroy this object Runtime.PyObject_GC_UnTrack(ob.Borrow()); // self may be null after Shutdown begun if (self is not null) { // The python should now have a ref count of 0, but we don't actually want to // deallocate the object until the C# object that references it is destroyed. // So we don't call PyObject_GC_Del here and instead we set the python // reference to a weak reference so that the C# object can be collected. GCHandle oldHandle = GetGCHandle(ob.Borrow()); GCHandle gc = GCHandle.Alloc(self, GCHandleType.Weak); SetGCHandle(ob.Borrow(), gc); oldHandle.Free(); } }
internal static Exception?FetchCurrentOrNull(out ExceptionDispatchInfo?dispatchInfo) { dispatchInfo = null; // prevent potential interop errors in this method // from crashing process with undebuggable StackOverflowException RuntimeHelpers.EnsureSufficientExecutionStack(); using var _ = new Py.GILState(); Runtime.PyErr_Fetch(out var type, out var value, out var traceback); if (type.IsNull()) { Debug.Assert(value.IsNull()); Debug.Assert(traceback.IsNull()); return(null); } try { if (TryDecodePyErr(type.Borrow(), value.BorrowNullable(), traceback.BorrowNullable()) is { } pyErr) { type.Dispose(); value.Dispose(); traceback.Dispose(); return(pyErr); } } catch { type.Dispose(); value.Dispose(); traceback.Dispose(); throw; } var normalizedValue = new NewReference(value.Borrow()); Runtime.PyErr_NormalizeException(type: ref type, val: ref normalizedValue, tb: ref traceback); try { return(FromPyErr(typeRef: type.Borrow(), valRef: value.Borrow(), nValRef: normalizedValue.Borrow(), tbRef: traceback.BorrowNullable(), out dispatchInfo)); } finally { type.Dispose(); value.Dispose(); traceback.Dispose(); } }