| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 16f04e9 commit daccc43
18 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,4 @@ | |||
| 1 | + using System.Runtime.InteropServices; | ||
| 1 | 2 | using System.Text; | |
| 2 | 3 | ||
| 3 | 4 | using NUnit.Framework; | |
@@ -30,7 +31,7 @@ public void CanCreateHeapType() | |||
| 30 | 31 | using var doc = new StrPtr(docStr, Encoding.UTF8); | |
| 31 | 32 | var spec = new TypeSpec( | |
| 32 | 33 | name: name, | |
| 33 | - basicSize: ObjectOffset.Size(Runtime.Runtime.PyTypeType), | ||
| 34 | + basicSize: Marshal.ReadInt32(Runtime.Runtime.PyBaseObjectType, TypeOffset.tp_basicsize), | ||
| 34 | 35 | slots: new TypeSpec.Slot[] { | |
| 35 | 36 | new (TypeSlotID.tp_doc, doc.RawPointer), | |
| 36 | 37 | }, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,9 +1,6 @@ | |||
| 1 | 1 | using System; | |
| 2 | 2 | using System.Collections; | |
| 3 | 3 | using System.Collections.Generic; | |
| 4 | - using System.Diagnostics; | ||
| 5 | - using System.Runtime.InteropServices; | ||
| 6 | - using System.Runtime.Serialization; | ||
| 7 | 4 | ||
| 8 | 5 | namespace Python.Runtime | |
| 9 | 6 | { | |
@@ -355,19 +352,21 @@ public static void tp_dealloc(IntPtr ob) | |||
| 355 | 352 | { | |
| 356 | 353 | ManagedType self = GetManagedObject(ob); | |
| 357 | 354 | tp_clear(ob); | |
| 358 | - Runtime.PyObject_GC_UnTrack(self.pyHandle); | ||
| 359 | - Runtime.PyObject_GC_Del(self.pyHandle); | ||
| 360 | - self.FreeGCHandle(); | ||
| 355 | + Runtime.PyObject_GC_UnTrack(ob); | ||
| 356 | + Runtime.PyObject_GC_Del(ob); | ||
| 357 | + self?.FreeGCHandle(); | ||
| 361 | 358 | } | |
| 362 | 359 | ||
| 363 | 360 | public static int tp_clear(IntPtr ob) | |
| 364 | 361 | { | |
| 365 | 362 | ManagedType self = GetManagedObject(ob); | |
| 366 | - if (!self.IsTypeObject()) | ||
| 363 | + | ||
| 364 | + bool isTypeObject = Runtime.PyObject_TYPE(ob) == Runtime.PyCLRMetaType; | ||
| 365 | + if (!isTypeObject) | ||
| 367 | 366 | { | |
| 368 | 367 | ClearObjectDict(ob); | |
| 369 | 368 | } | |
| 370 | - self.tpHandle = IntPtr.Zero; | ||
| 369 | + if (self is not null) self.tpHandle = IntPtr.Zero; | ||
| 371 | 370 | return 0; | |
| 372 | 371 | } | |
| 373 | 372 | ||
@@ -391,7 +390,7 @@ protected override void OnLoad(InterDomainContext context) | |||
| 391 | 390 | SetObjectDict(pyHandle, dict); | |
| 392 | 391 | } | |
| 393 | 392 | gcHandle = AllocGCHandle(); | |
| 394 | - Marshal.WriteIntPtr(pyHandle, TypeOffset.magic(), (IntPtr)gcHandle); | ||
| 393 | + SetGCHandle(ObjectReference, gcHandle); | ||
| 395 | 394 | } | |
| 396 | 395 | ||
| 397 | 396 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,6 @@ | |||
| 1 | 1 | using System; | |
| 2 | 2 | using System.Collections.Generic; | |
| 3 | + using System.Diagnostics; | ||
| 3 | 4 | using System.Linq; | |
| 4 | 5 | using System.Reflection; | |
| 5 | 6 | using System.Reflection.Emit; | |
@@ -75,8 +76,8 @@ internal ClassDerivedObject(Type tp) : base(tp) | |||
| 75 | 76 | // So we don't call PyObject_GC_Del here and instead we set the python | |
| 76 | 77 | // reference to a weak reference so that the C# object can be collected. | |
| 77 | 78 | GCHandle gc = GCHandle.Alloc(self, GCHandleType.Weak); | |
| 78 | - int gcOffset = ObjectOffset.magic(Runtime.PyObject_TYPE(self.pyHandle)); | ||
| 79 | - Marshal.WriteIntPtr(self.pyHandle, gcOffset, (IntPtr)gc); | ||
| 79 | + Debug.Assert(self.TypeReference == Runtime.PyObject_TYPE(self.ObjectReference)); | ||
| 80 | + SetGCHandle(self.ObjectReference, self.TypeReference, gc); | ||
| 80 | 81 | self.gcHandle.Free(); | |
| 81 | 82 | self.gcHandle = gc; | |
| 82 | 83 | } | |
@@ -106,7 +107,7 @@ internal static IntPtr ToPython(IPythonDerivedType obj) | |||
| 106 | 107 | Runtime._Py_NewReference(self.pyHandle); | |
| 107 | 108 | #endif | |
| 108 | 109 | GCHandle gc = GCHandle.Alloc(self, GCHandleType.Normal); | |
| 109 | - Marshal.WriteIntPtr(self.pyHandle, ObjectOffset.magic(self.tpHandle), (IntPtr)gc); | ||
| 110 | + SetGCHandle(self.ObjectReference, self.TypeReference, gc); | ||
| 110 | 111 | self.gcHandle.Free(); | |
| 111 | 112 | self.gcHandle = gc; | |
| 112 | 113 | ||
@@ -883,11 +884,6 @@ public static void Finalize(IPythonDerivedType obj) | |||
| 883 | 884 | // the C# object is being destroyed which must mean there are no more | |
| 884 | 885 | // references to the Python object as well so now we can dealloc the | |
| 885 | 886 | // python object. | |
| 886 | - IntPtr dict = Marshal.ReadIntPtr(self.pyHandle, ObjectOffset.TypeDictOffset(self.tpHandle)); | ||
| 887 | - if (dict != IntPtr.Zero) | ||
| 888 | - { | ||
| 889 | - Runtime.XDecref(dict); | ||
| 890 | - } | ||
| 891 | 887 | Runtime.PyObject_GC_Del(self.pyHandle); | |
| 892 | 888 | self.gcHandle.Free(); | |
| 893 | 889 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,26 +14,16 @@ internal CLRObject(object ob, IntPtr tp) | |||
| 14 | 14 | System.Diagnostics.Debug.Assert(tp != IntPtr.Zero); | |
| 15 | 15 | IntPtr py = Runtime.PyType_GenericAlloc(tp, 0); | |
| 16 | 16 | ||
| 17 | - var flags = (TypeFlags)Util.ReadCLong(tp, TypeOffset.tp_flags); | ||
| 18 | - if ((flags & TypeFlags.Subclass) != 0) | ||
| 19 | - { | ||
| 20 | - IntPtr dict = Marshal.ReadIntPtr(py, ObjectOffset.TypeDictOffset(tp)); | ||
| 21 | - if (dict == IntPtr.Zero) | ||
| 22 | - { | ||
| 23 | - dict = Runtime.PyDict_New(); | ||
| 24 | - Marshal.WriteIntPtr(py, ObjectOffset.TypeDictOffset(tp), dict); | ||
| 25 | - } | ||
| 26 | - } | ||
| 27 | - | ||
| 28 | - GCHandle gc = AllocGCHandle(TrackTypes.Wrapper); | ||
| 29 | - Marshal.WriteIntPtr(py, ObjectOffset.magic(tp), (IntPtr)gc); | ||
| 30 | 17 | tpHandle = tp; | |
| 31 | 18 | pyHandle = py; | |
| 32 | 19 | inst = ob; | |
| 33 | 20 | ||
| 21 | + GCHandle gc = AllocGCHandle(TrackTypes.Wrapper); | ||
| 22 | + InitGCHandle(ObjectReference, type: TypeReference, gc); | ||
| 23 | + | ||
| 34 | 24 | // Fix the BaseException args (and __cause__ in case of Python 3) | |
| 35 | 25 | // slot if wrapping a CLR exception | |
| 36 | - Exceptions.SetArgsAndCause(py); | ||
| 26 | + if (ob is Exception e) Exceptions.SetArgsAndCause(e, py); | ||
| 37 | 27 | } | |
| 38 | 28 | ||
| 39 | 29 | protected CLRObject() | |
@@ -78,6 +68,9 @@ internal static IntPtr GetInstHandle(object ob) | |||
| 78 | 68 | return co.pyHandle; | |
| 79 | 69 | } | |
| 80 | 70 | ||
| 71 | + internal static NewReference GetReference(object ob) | ||
| 72 | + => NewReference.DangerousFromPointer(GetInstHandle(ob)); | ||
| 73 | + | ||
| 81 | 74 | internal static CLRObject Restore(object ob, IntPtr pyHandle, InterDomainContext context) | |
| 82 | 75 | { | |
| 83 | 76 | CLRObject co = new CLRObject() | |
@@ -101,7 +94,7 @@ protected override void OnLoad(InterDomainContext context) | |||
| 101 | 94 | { | |
| 102 | 95 | base.OnLoad(context); | |
| 103 | 96 | GCHandle gc = AllocGCHandle(TrackTypes.Wrapper); | |
| 104 | - Marshal.WriteIntPtr(pyHandle, ObjectOffset.magic(tpHandle), (IntPtr)gc); | ||
| 97 | + SetGCHandle(ObjectReference, TypeReference, gc); | ||
| 105 | 98 | } | |
| 106 | 99 | } | |
| 107 | 100 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -580,7 +580,7 @@ private static bool ToPrimitive(IntPtr value, Type obType, out object result, bo | |||
| 580 | 580 | { | |
| 581 | 581 | if (Runtime.PyBytes_Size(value) == 1) | |
| 582 | 582 | { | |
| 583 | - op = Runtime.PyBytes_AS_STRING(value); | ||
| 583 | + op = Runtime.PyBytes_AsString(value); | ||
| 584 | 584 | result = (byte)Marshal.ReadByte(op); | |
| 585 | 585 | return true; | |
| 586 | 586 | } | |
@@ -606,7 +606,7 @@ private static bool ToPrimitive(IntPtr value, Type obType, out object result, bo | |||
| 606 | 606 | { | |
| 607 | 607 | if (Runtime.PyBytes_Size(value) == 1) | |
| 608 | 608 | { | |
| 609 | - op = Runtime.PyBytes_AS_STRING(value); | ||
| 609 | + op = Runtime.PyBytes_AsString(value); | ||
| 610 | 610 | result = (byte)Marshal.ReadByte(op); | |
| 611 | 611 | return true; | |
| 612 | 612 | } | |
@@ -632,7 +632,7 @@ private static bool ToPrimitive(IntPtr value, Type obType, out object result, bo | |||
| 632 | 632 | { | |
| 633 | 633 | if (Runtime.PyBytes_Size(value) == 1) | |
| 634 | 634 | { | |
| 635 | - op = Runtime.PyBytes_AS_STRING(value); | ||
| 635 | + op = Runtime.PyBytes_AsString(value); | ||
| 636 | 636 | result = (byte)Marshal.ReadByte(op); | |
| 637 | 637 | return true; | |
| 638 | 638 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -156,15 +156,8 @@ internal static void Shutdown() | |||
| 156 | 156 | /// pointer. | |
| 157 | 157 | /// </summary> | |
| 158 | 158 | /// <param name="ob">The python object wrapping </param> | |
| 159 | - internal static void SetArgsAndCause(IntPtr ob) | ||
| 159 | + internal static void SetArgsAndCause(Exception e, IntPtr ob) | ||
| 160 | 160 | { | |
| 161 | - // e: A CLR Exception | ||
| 162 | - Exception e = ExceptionClassObject.ToException(ob); | ||
| 163 | - if (e == null) | ||
| 164 | - { | ||
| 165 | - return; | ||
| 166 | - } | ||
| 167 | - | ||
| 168 | 161 | IntPtr args; | |
| 169 | 162 | if (!string.IsNullOrEmpty(e.Message)) | |
| 170 | 163 | { | |
@@ -177,13 +170,14 @@ internal static void SetArgsAndCause(IntPtr ob) | |||
| 177 | 170 | args = Runtime.PyTuple_New(0); | |
| 178 | 171 | } | |
| 179 | 172 | ||
| 180 | - Marshal.WriteIntPtr(ob, ExceptionOffset.args, args); | ||
| 173 | + if (Runtime.PyObject_SetAttrString(ob, "args", args) != 0) | ||
| 174 | + throw new PythonException(); | ||
| 181 | 175 | ||
| 182 | 176 | if (e.InnerException != null) | |
| 183 | 177 | { | |
| 184 | 178 | // Note: For an AggregateException, InnerException is only the first of the InnerExceptions. | |
| 185 | - IntPtr cause = CLRObject.GetInstHandle(e.InnerException); | ||
| 186 | - Marshal.WriteIntPtr(ob, ExceptionOffset.cause, cause); | ||
| 179 | + using var cause = CLRObject.GetReference(e.InnerException); | ||
| 180 | + Runtime.PyException_SetCause(ob, cause.DangerousMoveToPointer()); | ||
| 187 | 181 | } | |
| 188 | 182 | } | |
| 189 | 183 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -33,13 +33,17 @@ public ExtensionType() | |||
| 33 | 33 | tpHandle = tp; | |
| 34 | 34 | pyHandle = py; | |
| 35 | 35 | ||
| 36 | + #if DEBUG | ||
| 37 | + GetGCHandle(ObjectReference, TypeReference, out var existing); | ||
| 38 | + System.Diagnostics.Debug.Assert(existing == IntPtr.Zero); | ||
| 39 | + #endif | ||
| 36 | 40 | SetupGc(); | |
| 37 | 41 | } | |
| 38 | 42 | ||
| 39 | 43 | void SetupGc () | |
| 40 | 44 | { | |
| 41 | 45 | GCHandle gc = AllocGCHandle(TrackTypes.Extension); | |
| 42 | - Marshal.WriteIntPtr(pyHandle, ObjectOffset.magic(tpHandle), (IntPtr)gc); | ||
| 46 | + InitGCHandle(ObjectReference, TypeReference, gc); | ||
| 43 | 47 | ||
| 44 | 48 | // We have to support gc because the type machinery makes it very | |
| 45 | 49 | // hard not to - but we really don't have a need for it in most | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,26 +15,6 @@ internal static class ImportHook | |||
| 15 | 15 | private static IntPtr py_clr_module; | |
| 16 | 16 | static BorrowedReference ClrModuleReference => new BorrowedReference(py_clr_module); | |
| 17 | 17 | ||
| 18 | - private static IntPtr module_def = IntPtr.Zero; | ||
| 19 | - | ||
| 20 | - internal static void InitializeModuleDef() | ||
| 21 | - { | ||
| 22 | - if (module_def == IntPtr.Zero) | ||
| 23 | - { | ||
| 24 | - module_def = ModuleDefOffset.AllocModuleDef("clr"); | ||
| 25 | - } | ||
| 26 | - } | ||
| 27 | - | ||
| 28 | - internal static void ReleaseModuleDef() | ||
| 29 | - { | ||
| 30 | - if (module_def == IntPtr.Zero) | ||
| 31 | - { | ||
| 32 | - return; | ||
| 33 | - } | ||
| 34 | - ModuleDefOffset.FreeModuleDef(module_def); | ||
| 35 | - module_def = IntPtr.Zero; | ||
| 36 | - } | ||
| 37 | - | ||
| 38 | 18 | /// <summary> | |
| 39 | 19 | /// Initialize just the __import__ hook itself. | |
| 40 | 20 | /// </summary> | |
@@ -90,8 +70,7 @@ internal static unsafe void Initialize() | |||
| 90 | 70 | root = new CLRModule(); | |
| 91 | 71 | ||
| 92 | 72 | // create a python module with the same methods as the clr module-like object | |
| 93 | - InitializeModuleDef(); | ||
| 94 | - py_clr_module = Runtime.PyModule_Create2(module_def, 3); | ||
| 73 | + py_clr_module = Runtime.PyModule_New("clr").DangerousMoveToPointer(); | ||
| 95 | 74 | ||
| 96 | 75 | // both dicts are borrowed references | |
| 97 | 76 | BorrowedReference mod_dict = Runtime.PyModule_GetDict(ClrModuleReference); | |
@@ -116,13 +95,8 @@ internal static void Shutdown() | |||
| 116 | 95 | ||
| 117 | 96 | RestoreImport(); | |
| 118 | 97 | ||
| 119 | - bool shouldFreeDef = Runtime.Refcount(py_clr_module) == 1; | ||
| 120 | 98 | Runtime.XDecref(py_clr_module); | |
| 121 | 99 | py_clr_module = IntPtr.Zero; | |
| 122 | - if (shouldFreeDef) | ||
| 123 | - { | ||
| 124 | - ReleaseModuleDef(); | ||
| 125 | - } | ||
| 126 | 100 | ||
| 127 | 101 | Runtime.XDecref(root.pyHandle); | |
| 128 | 102 | root = null; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments