| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -75,7 +75,8 @@ internal ClassDerivedObject(Type tp) : base(tp) | |||
| 75 | 75 | // So we don't call PyObject_GC_Del here and instead we set the python | |
| 76 | 76 | // reference to a weak reference so that the C# object can be collected. | |
| 77 | 77 | GCHandle gc = GCHandle.Alloc(self, GCHandleType.Weak); | |
| 78 | - Marshal.WriteIntPtr(self.pyHandle, ObjectOffset.magic(self.tpHandle), (IntPtr)gc); | ||
| 78 | + int gcOffset = ObjectOffset.magic(Runtime.PyObject_TYPE(self.pyHandle)); | ||
| 79 | + Marshal.WriteIntPtr(self.pyHandle, gcOffset, (IntPtr)gc); | ||
| 79 | 80 | self.gcHandle.Free(); | |
| 80 | 81 | self.gcHandle = gc; | |
| 81 | 82 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,5 @@ | |||
| 1 | 1 | using System; | |
| 2 | + using System.Diagnostics; | ||
| 2 | 3 | using System.Runtime.InteropServices; | |
| 3 | 4 | ||
| 4 | 5 | namespace Python.Runtime | |
@@ -85,6 +86,7 @@ internal static CLRObject Restore(object ob, IntPtr pyHandle, InterDomainContext | |||
| 85 | 86 | pyHandle = pyHandle, | |
| 86 | 87 | tpHandle = Runtime.PyObject_TYPE(pyHandle) | |
| 87 | 88 | }; | |
| 89 | + Debug.Assert(co.tpHandle != IntPtr.Zero); | ||
| 88 | 90 | co.Load(context); | |
| 89 | 91 | return co; | |
| 90 | 92 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -313,7 +313,9 @@ internal static bool ToManaged(IntPtr value, Type type, | |||
| 313 | 313 | return Converter.ToManagedValue(value, type, out result, setError); | |
| 314 | 314 | } | |
| 315 | 315 | ||
| 316 | - | ||
| 316 | + internal static bool ToManagedValue(BorrowedReference value, Type obType, | ||
| 317 | + out object result, bool setError) | ||
| 318 | + => ToManagedValue(value.DangerousGetAddress(), obType, out result, setError); | ||
| 317 | 319 | internal static bool ToManagedValue(IntPtr value, Type obType, | |
| 318 | 320 | out object result, bool setError) | |
| 319 | 321 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -85,9 +85,11 @@ internal static void Use(ITypeOffsets offsets) | |||
| 85 | 85 | internal static Dictionary<string, int> GetOffsets() | |
| 86 | 86 | { | |
| 87 | 87 | var properties = typeof(TypeOffset).GetProperties(FieldFlags); | |
| 88 | - return properties.ToDictionary( | ||
| 89 | - keySelector: p => p.Name, | ||
| 90 | - elementSelector: p => (int)p.GetValue(obj: null, index: null)); | ||
| 88 | + var result = properties.ToDictionary( | ||
| 89 | + keySelector: p => p.Name, | ||
| 90 | + elementSelector: p => (int)p.GetValue(obj: null, index: null)); | ||
| 91 | + Debug.Assert(result.Values.Any(v => v != 0)); | ||
| 92 | + return result; | ||
| 91 | 93 | } | |
| 92 | 94 | ||
| 93 | 95 | internal static int GetOffsetUncached(string name) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1641,6 +1641,8 @@ internal static bool PyDict_Check(IntPtr ob) | |||
| 1641 | 1641 | /// </summary> | |
| 1642 | 1642 | [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] | |
| 1643 | 1643 | internal static extern IntPtr PyDict_GetItem(IntPtr pointer, IntPtr key); | |
| 1644 | + [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] | ||
| 1645 | + internal static extern BorrowedReference PyDict_GetItemWithError(BorrowedReference pointer, BorrowedReference key); | ||
| 1644 | 1646 | ||
| 1645 | 1647 | /// <summary> | |
| 1646 | 1648 | /// Return value: Borrowed reference. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,6 +6,7 @@ | |||
| 6 | 6 | using System.Runtime.InteropServices; | |
| 7 | 7 | using System.Diagnostics; | |
| 8 | 8 | using Python.Runtime.Slots; | |
| 9 | + using static Python.Runtime.PythonException; | ||
| 9 | 10 | ||
| 10 | 11 | namespace Python.Runtime | |
| 11 | 12 | { | |
@@ -142,7 +143,7 @@ internal static IntPtr GetTypeHandle(ManagedType obj, Type type) | |||
| 142 | 143 | /// </summary> | |
| 143 | 144 | internal static IntPtr CreateType(Type impl) | |
| 144 | 145 | { | |
| 145 | - IntPtr type = AllocateTypeObject(impl.Name); | ||
| 146 | + IntPtr type = AllocateTypeObject(impl.Name, metatype: Runtime.PyTypeType); | ||
| 146 | 147 | int ob_size = ObjectOffset.Size(type); | |
| 147 | 148 | ||
| 148 | 149 | // Set tp_basicsize to the size of our managed instance objects. | |
@@ -211,7 +212,7 @@ internal static IntPtr CreateType(ManagedType impl, Type clrType) | |||
| 211 | 212 | base_ = bc.pyHandle; | |
| 212 | 213 | } | |
| 213 | 214 | ||
| 214 | - IntPtr type = AllocateTypeObject(name); | ||
| 215 | + IntPtr type = AllocateTypeObject(name, Runtime.PyCLRMetaType); | ||
| 215 | 216 | ||
| 216 | 217 | Marshal.WriteIntPtr(type, TypeOffset.ob_type, Runtime.PyCLRMetaType); | |
| 217 | 218 | Runtime.XIncref(Runtime.PyCLRMetaType); | |
@@ -302,6 +303,7 @@ internal static IntPtr CreateType(ManagedType impl, Type clrType) | |||
| 302 | 303 | ||
| 303 | 304 | internal static IntPtr CreateSubType(IntPtr py_name, IntPtr py_base_type, IntPtr py_dict) | |
| 304 | 305 | { | |
| 306 | + var dictRef = new BorrowedReference(py_dict); | ||
| 305 | 307 | // Utility to create a subtype of a managed type with the ability for the | |
| 306 | 308 | // a python subtype able to override the managed implementation | |
| 307 | 309 | string name = Runtime.GetManagedString(py_name); | |
@@ -311,40 +313,29 @@ internal static IntPtr CreateSubType(IntPtr py_name, IntPtr py_base_type, IntPtr | |||
| 311 | 313 | object assembly = null; | |
| 312 | 314 | object namespaceStr = null; | |
| 313 | 315 | ||
| 314 | - var disposeList = new List<PyObject>(); | ||
| 315 | - try | ||
| 316 | + using (var assemblyKey = new PyString("__assembly__")) | ||
| 316 | 317 | { | |
| 317 | - var assemblyKey = new PyObject(Converter.ToPython("__assembly__", typeof(string))); | ||
| 318 | - disposeList.Add(assemblyKey); | ||
| 319 | - if (0 != Runtime.PyMapping_HasKey(py_dict, assemblyKey.Handle)) | ||
| 318 | + var assemblyPtr = Runtime.PyDict_GetItemWithError(dictRef, assemblyKey.Reference); | ||
| 319 | + if (assemblyPtr.IsNull) | ||
| 320 | 320 | { | |
| 321 | - var pyAssembly = new PyObject(Runtime.PyDict_GetItem(py_dict, assemblyKey.Handle)); | ||
| 322 | - Runtime.XIncref(pyAssembly.Handle); | ||
| 323 | - disposeList.Add(pyAssembly); | ||
| 324 | - if (!Converter.ToManagedValue(pyAssembly.Handle, typeof(string), out assembly, false)) | ||
| 325 | - { | ||
| 326 | - throw new InvalidCastException("Couldn't convert __assembly__ value to string"); | ||
| 327 | - } | ||
| 321 | + if (Exceptions.ErrorOccurred()) return IntPtr.Zero; | ||
| 322 | + } | ||
| 323 | + else if (!Converter.ToManagedValue(assemblyPtr, typeof(string), out assembly, false)) | ||
| 324 | + { | ||
| 325 | + return Exceptions.RaiseTypeError("Couldn't convert __assembly__ value to string"); | ||
| 328 | 326 | } | |
| 329 | 327 | ||
| 330 | - var namespaceKey = new PyObject(Converter.ToPythonImplicit("__namespace__")); | ||
| 331 | - disposeList.Add(namespaceKey); | ||
| 332 | - if (0 != Runtime.PyMapping_HasKey(py_dict, namespaceKey.Handle)) | ||
| 328 | + using (var namespaceKey = new PyString("__namespace__")) | ||
| 333 | 329 | { | |
| 334 | - var pyNamespace = new PyObject(Runtime.PyDict_GetItem(py_dict, namespaceKey.Handle)); | ||
| 335 | - Runtime.XIncref(pyNamespace.Handle); | ||
| 336 | - disposeList.Add(pyNamespace); | ||
| 337 | - if (!Converter.ToManagedValue(pyNamespace.Handle, typeof(string), out namespaceStr, false)) | ||
| 330 | + var pyNamespace = Runtime.PyDict_GetItemWithError(dictRef, namespaceKey.Reference); | ||
| 331 | + if (pyNamespace.IsNull) | ||
| 338 | 332 | { | |
| 339 | - throw new InvalidCastException("Couldn't convert __namespace__ value to string"); | ||
| 333 | + if (Exceptions.ErrorOccurred()) return IntPtr.Zero; | ||
| 334 | + } | ||
| 335 | + else if (!Converter.ToManagedValue(pyNamespace, typeof(string), out namespaceStr, false)) | ||
| 336 | + { | ||
| 337 | + return Exceptions.RaiseTypeError("Couldn't convert __namespace__ value to string"); | ||
| 340 | 338 | } | |
| 341 | - } | ||
| 342 | - } | ||
| 343 | - finally | ||
| 344 | - { | ||
| 345 | - foreach (PyObject o in disposeList) | ||
| 346 | - { | ||
| 347 | - o.Dispose(); | ||
| 348 | 339 | } | |
| 349 | 340 | } | |
| 350 | 341 | ||
@@ -370,14 +361,14 @@ internal static IntPtr CreateSubType(IntPtr py_name, IntPtr py_base_type, IntPtr | |||
| 370 | 361 | // by default the class dict will have all the C# methods in it, but as this is a | |
| 371 | 362 | // derived class we want the python overrides in there instead if they exist. | |
| 372 | 363 | IntPtr cls_dict = Marshal.ReadIntPtr(py_type, TypeOffset.tp_dict); | |
| 373 | - Runtime.PyDict_Update(cls_dict, py_dict); | ||
| 364 | + ThrowIfIsNotZero(Runtime.PyDict_Update(cls_dict, py_dict)); | ||
| 374 | 365 | Runtime.XIncref(py_type); | |
| 375 | 366 | // Update the __classcell__ if it exists | |
| 376 | 367 | var cell = new BorrowedReference(Runtime.PyDict_GetItemString(cls_dict, "__classcell__")); | |
| 377 | 368 | if (!cell.IsNull) | |
| 378 | 369 | { | |
| 379 | - Runtime.PyCell_Set(cell, py_type); | ||
| 380 | - Runtime.PyDict_DelItemString(cls_dict, "__classcell__"); | ||
| 370 | + ThrowIfIsNotZero(Runtime.PyCell_Set(cell, py_type)); | ||
| 371 | + ThrowIfIsNotZero(Runtime.PyDict_DelItemString(cls_dict, "__classcell__")); | ||
| 381 | 372 | } | |
| 382 | 373 | ||
| 383 | 374 | return py_type; | |
@@ -436,12 +427,15 @@ internal static IntPtr CreateMetaType(Type impl, out SlotsHolder slotsHolder) | |||
| 436 | 427 | // the standard type slots, and has to subclass PyType_Type for | |
| 437 | 428 | // certain functions in the C runtime to work correctly with it. | |
| 438 | 429 | ||
| 439 | - IntPtr type = AllocateTypeObject("CLR Metatype"); | ||
| 440 | - IntPtr py_type = Runtime.PyTypeType; | ||
| 430 | + IntPtr type = AllocateTypeObject("CLR Metatype", metatype: Runtime.PyTypeType); | ||
| 441 | 431 | ||
| 432 | + IntPtr py_type = Runtime.PyTypeType; | ||
| 442 | 433 | Marshal.WriteIntPtr(type, TypeOffset.tp_base, py_type); | |
| 443 | 434 | Runtime.XIncref(py_type); | |
| 444 | 435 | ||
| 436 | + int size = TypeOffset.magic() + IntPtr.Size; | ||
| 437 | + Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, new IntPtr(size)); | ||
| 438 | + | ||
| 445 | 439 | const int flags = TypeFlags.Default | |
| 446 | 440 | | TypeFlags.Managed | |
| 447 | 441 | | TypeFlags.HeapType | |
@@ -531,7 +525,7 @@ internal static IntPtr BasicSubType(string name, IntPtr base_, Type impl) | |||
| 531 | 525 | // Utility to create a subtype of a std Python type, but with | |
| 532 | 526 | // a managed type able to override implementation | |
| 533 | 527 | ||
| 534 | - IntPtr type = AllocateTypeObject(name); | ||
| 528 | + IntPtr type = AllocateTypeObject(name, metatype: Runtime.PyTypeType); | ||
| 535 | 529 | //Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)obSize); | |
| 536 | 530 | //Marshal.WriteIntPtr(type, TypeOffset.tp_itemsize, IntPtr.Zero); | |
| 537 | 531 | ||
@@ -573,9 +567,9 @@ internal static IntPtr BasicSubType(string name, IntPtr base_, Type impl) | |||
| 573 | 567 | /// <summary> | |
| 574 | 568 | /// Utility method to allocate a type object & do basic initialization. | |
| 575 | 569 | /// </summary> | |
| 576 | - internal static IntPtr AllocateTypeObject(string name) | ||
| 570 | + internal static IntPtr AllocateTypeObject(string name, IntPtr metatype) | ||
| 577 | 571 | { | |
| 578 | - IntPtr type = Runtime.PyType_GenericAlloc(Runtime.PyTypeType, 0); | ||
| 572 | + IntPtr type = Runtime.PyType_GenericAlloc(metatype, 0); | ||
| 579 | 573 | // Clr type would not use __slots__, | |
| 580 | 574 | // and the PyMemberDef after PyHeapTypeObject will have other uses(e.g. type handle), | |
| 581 | 575 | // thus set the ob_size to 0 for avoiding slots iterations. | |
| Back | FazBrowse Home | New Git URL |
0 commit comments