X Tutup
using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; namespace Python.Runtime { [Serializable] [DebuggerDisplay("clrO: {inst}")] internal sealed class CLRObject : ManagedType { internal readonly object inst; internal static bool creationBlocked = false; // "borrowed" references internal static readonly HashSet reflectedObjects = new(); static NewReference Create(object ob, BorrowedReference tp) { if (creationBlocked) throw new InvalidOperationException("Reflected objects should not be created anymore."); Debug.Assert(tp != null); var py = Runtime.PyType_GenericAlloc(tp, 0); var self = new CLRObject(ob); GCHandle gc = GCHandle.Alloc(self); InitGCHandle(py.Borrow(), type: tp, gc); bool isNew = reflectedObjects.Add(py.DangerousGetAddress()); Debug.Assert(isNew); // Fix the BaseException args (and __cause__ in case of Python 3) // slot if wrapping a CLR exception if (ob is Exception e) Exceptions.SetArgsAndCause(py.Borrow(), e); return py; } CLRObject(object inst) { this.inst = inst; } internal static NewReference GetReference(object ob, BorrowedReference pyType) => Create(ob, pyType); internal static NewReference GetReference(object ob, Type type) { BorrowedReference cc = ClassManager.GetClass(type); return Create(ob, cc); } internal static NewReference GetReference(object ob) { BorrowedReference cc = ClassManager.GetClass(ob.GetType()); return Create(ob, cc); } internal static void Restore(object ob, BorrowedReference pyHandle, Dictionary context) { var co = new CLRObject(ob); co.OnLoad(pyHandle, context); } protected override void OnLoad(BorrowedReference ob, Dictionary? context) { if (creationBlocked) throw new InvalidOperationException("Reflected objects should not be loaded anymore."); base.OnLoad(ob, context); GCHandle gc = GCHandle.Alloc(this); SetGCHandle(ob, gc); bool isNew = reflectedObjects.Add(ob.DangerousGetAddress()); Debug.Assert(isNew); } } }
X Tutup