8000 * Reset type slots · pythonnet/pythonnet@b07b844 · GitHub
[go: up one dir, main page]

Skip to content

Commit b07b844

Browse files
committed
* Reset type slots
* Fix ref error at PythoneEngine.With
1 parent 91f64b9 commit b07b844

12 files changed

+226
-87
lines changed

src/runtime/classbase.cs

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,6 @@ internal virtual bool CanSubclass()
2929
return !type.IsEnum;
3030
}
3131

32-
/// <summary>
33-
/// Implements __init__ for reflected classes and value types.
34-
/// </summary>
35-
public static int tp_init(IntPtr ob, IntPtr args, IntPtr kw)
36-
{
37-
return 0;
38-
}
3932

4033
/// <summary>
4134
/// Default implementation of [] semantics for reflected types.
@@ -254,13 +247,9 @@ public static IntPtr tp_str(IntPtr ob)
254247
public static void tp_dealloc(IntPtr ob)
255248
{
256249
ManagedType self = GetManagedObject(ob);
257-
if (self.pyHandle != self.tpHandle)
258-
{
259-
ClearObjectDict(ob);
260-
}
250+
tp_clear(ob);
261251
Runtime.PyObject_GC_UnTrack(self.pyHandle);
262252
Runtime.PyObject_GC_Del(self.pyHandle);
263-
Runtime.XDecref(self.tpHandle);
264253
self.FreeGCHandle();
265254
}
266255

@@ -271,9 +260,7 @@ public static int tp_clear(IntPtr ob)
271260
{
272261
ClearObjectDict(ob);
273262
}
274-
Runtime.XDecref(self.tpHandle);
275-
self.tpHandle = IntPtr.Zero;
276-
self.FreeGCHandle();
263+
Runtime.Py_CLEAR(ref self.tpHandle);
277264
return 0;
278265
}
279266

src/runtime/classmanager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ internal static void RemoveClasses()
5454
foreach (var cls in cache.Values)
5555
{
5656
cls.TypeTraverse(OnVisit, visitedPtr);
57-
// XXX: Force release some resouces.
57+
// XXX: Force release instance resources but not dealloc itself.
5858
cls.TypeClear();
5959
}
6060
}

src/runtime/extensiontype.cs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -92,21 +92,5 @@ public static void tp_dealloc(IntPtr ob)
9292
ManagedType self = GetManagedObject(ob);
9393
FinalizeObject(self);
9494
}
95-
96-
public static int tp_clear(IntPtr ob)
97-
{
98-
ManagedType self = GetManagedObject(ob);
99-
Runtime.XDecref(self.tpHandle);
100-
self.FreeGCHandle();
101-
return 0;
102-
}
103-
104-
//public static int tp_traverse(IntPtr ob, IntPtr visit, IntPtr arg)
105-
//{
106-
// ManagedType self = GetManagedObject(ob);
107-
// int res = PyVisit(self.tpHandle, visit, arg);
108-
// if (res != 0) return res;
109-
// return 0;
110-
//}
11195
}
11296
}

src/runtime/finalizer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public IncorrectRefCountException(IntPtr ptr)
5959
IntPtr pyname = Runtime.PyObject_Unicode(PyPtr);
6060
string name = Runtime.GetManagedString(pyname);
6161
Runtime.XDecref(pyname);
62-
_message = $"{name} may has a incorrect ref count";
62+
_message = $"<{name}> may has a incorrect ref count";
6363
}
6464
}
6565

src/runtime/interop.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Reflection;
66
using System.Text;
77
using System.Collections.Generic;
8+
using System.Linq;
89

910
namespace Python.Runtime
1011
{
@@ -262,6 +263,14 @@ public static void FreeModuleDef(IntPtr ptr)
262263
}
263264
#endif // PYTHON3
264265

266+
static class TypeOffsetHelper
267+
{
268+
public static string GetSlotNameByOffset(int offset)
269+
{
270+
return typeof(TypeOffset).GetFields().First(fi => (int)fi.GetValue(null) == offset).Name;
271+
}
272+
}
273+
265274
/// <summary>
266275
/// TypeFlags(): The actual bit values for the Type Flags stored
267276
/// in a class.
@@ -448,11 +457,6 @@ internal static Type GetPrototype(string name)
448457
}
449458

450459
internal static ThunkInfo GetThunk(MethodInfo method, string funcType = null)
451-
{
452-
return GetThunkImpl(method, funcType);
453-
}
454-
455-
private static ThunkInfo GetThunkImpl(MethodInfo method, string funcType)
456460
{
457461
Type dt;
458462
if (funcType != null)
@@ -473,6 +477,7 @@ private static ThunkInfo GetThunkImpl(MethodInfo method, string funcType)
473477
return new ThunkInfo(d, fp);
474478
}
475479

480+
476481
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
477482
public delegate IntPtr UnaryFunc(IntPtr ob);
478483

@@ -552,4 +557,14 @@ struct PyGC_Head
552557
{
553558
public PyGC_Node gc;
554559
}
560+
561+
562+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
563+
struct PyMethodDef
564+
{
565+
public IntPtr ml_name;
566+
public IntPtr ml_meth;
567+
public int ml_flags;
568+
public IntPtr ml_doc;
569+
}
555570
}

src/runtime/metatype.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ public static IntPtr Initialize()
2222
return PyCLRMetaType;
2323
}
2424

25+
public static void Release()
26+
{
27+
if (Runtime.Refcount(PyCLRMetaType) > 1)
28+
{
29+
SlotsHolder.ReleaseTypeSlots(PyCLRMetaType);
30+
}
31+
Runtime.XDecref(PyCLRMetaType);
32+
PyCLRMetaType = IntPtr.Zero;
33+
}
2534

2635
/// <summary>
2736
/// Metatype __new__ implementation. This is called to create a new

src/runtime/methodbinding.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,8 @@ public MethodBinding(MethodObject m, IntPtr target) : this(m, target, IntPtr.Zer
3838

3939
private void ClearMembers()
4040
{
41-
Runtime.XDecref(target);
42-
target = IntPtr.Zero;
43-
Runtime.XDecref(targetType);
44-
targetType = IntPtr.Zero;
41+
Runtime.Py_CLEAR(ref target);
42+
Runtime.Py_CLEAR(ref targetType);
4543
}
4644

4745
/// <summary>
@@ -249,11 +247,11 @@ public static IntPtr tp_repr(IntPtr ob)
249247
FinalizeObject(self);
250248
}
251249

252-
public new static int tp_clear(IntPtr ob)
250+
public static int tp_clear(IntPtr ob)
253251
{
254252
var self = (MethodBinding)GetManagedObject(ob);
255253
self.ClearMembers();
256-
return ExtensionType.tp_clear(ob);
254+
return 0;
257255
}
258256
}
259257
}

src/runtime/methodobject.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,11 @@ public static IntPtr tp_repr(IntPtr ob)
211211
ExtensionType.FinalizeObject(self);
212212
}
213213

214-
public new static int tp_clear(IntPtr ob)
214+
public static int tp_clear(IntPtr ob)
215215
{
216216
var self = (MethodObject)GetManagedObject(ob);
217217
self.ClearMembers();
218-
return ExtensionType.tp_clear(ob);
218+
return 0;
219219
}
220220
}
221221
}

src/runtime/moduleobject.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -304,13 +304,7 @@ public static IntPtr tp_repr(IntPtr ob)
304304
public new static void tp_dealloc(IntPtr ob)
305305
{
306306
var self = (ModuleObject)GetManagedObject(ob);
307-
Runtime.XDecref(self.dict);
308-
self.dict = IntPtr.Zero;
309-
foreach (var attr in self.cache.Values)
310-
{
311-
Runtime.XDecref(attr.pyHandle);
312-
}
313-
self.cache.Clear();
307+
tp_clear(ob);
314308
ExtensionType.tp_dealloc(ob);
315309
}
316310

@@ -327,7 +321,7 @@ public static int tp_traverse(IntPtr ob, IntPtr visit, IntPtr arg)
327321
return 0;
328322
}
329323

330-
public new static int tp_clear(IntPtr ob)
324+
public static int tp_clear(IntPtr ob)
331325
{
332326
var self = (ModuleObject)GetManagedObject(ob);
333327
Runtime.XDecref(self.dict);
@@ -337,7 +331,7 @@ public static int tp_traverse(IntPtr ob, IntPtr visit, IntPtr arg)
337331
Runtime.XDecref(attr.pyHandle);
338332
}
339333
self.cache.Clear();
340-
return ExtensionType.tp_clear(ob);
334+
return 0;
341335
}
342336
}
343337

src/runtime/pythonengine.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,10 @@ public static void Initialize(IEnumerable<string> args, bool setSysArgv = true,
194194
// register the atexit callback (this doesn't use Py_AtExit as the C atexit
195195
// callbacks are called after python is fully finalized but the python ones
196196
// are called while the python engine is still running).
197-
string code =
198-
"import atexit, clr\n" +
199-
"atexit.register(clr._AtExit)\n";
200-
PythonEngine.Exec(code);
197+
//string code =
198+
// "import atexit, clr\n" +
199+
// "atexit.register(clr._AtExit)\n";
200+
//PythonEngine.Exec(code);
201201
}
202202

203203
// Load the clr.py resource into the clr module
@@ -756,6 +756,9 @@ public static void With(PyObject obj, Action<dynamic> Body)
756756
traceBack = ex.PyTB;
757757
}
758758

759+
Runtime.XIncref(type);
760+
Runtime.XIncref(val);
761+
Runtime.XIncref(traceBack);
759762
var exitResult = obj.InvokeMethod("__exit__", new PyObject(type), new PyObject(val), new PyObject(traceBack));
760763

761764
if (ex != null && !exitResult.IsTrue()) throw ex;

src/runtime/runtime.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,7 @@ internal static void Initialize(bool initSigs = false, bool softShutdown = false
311311

312312
// Initialize modules that depend on the runtime class.
313313
AssemblyManager.Initialize();
314-
var metaType = MetaType.Initialize();
315-
XIncref(metaType);
316-
SetPyMember(ref PyCLRMetaType, metaType);
314+
PyCLRMetaType = MetaType.Initialize(); // Steal a reference
317315
Exceptions.Initialize();
318316
ImportHook.Initialize();
319317

@@ -388,11 +386,14 @@ internal static void Shutdown(bool soft)
388386
ClearClrModules();
389387
ClassManager.RemoveClasses();
390388
TypeManager.RemoveTypes();
389+
390+
MetaType.Release();
391+
PyCLRMetaType = IntPtr.Zero;
392+
391393
RemoveClrRootModule();
392394
if (soft)
393395
{
394396
PyGC_Collect();
395-
RemoveClrObjects();
396397
RuntimeState.Restore();
397398
ResetPyMembers();
398399
return;
@@ -471,9 +472,6 @@ private static void PyDictTryDelItem(IntPtr dict, string key)
471472
PyErr_Clear();
472473
}
473474

474-
private static void RemoveClrObjects()
475-
{
476-
}
477475

478476
internal static IntPtr Py_single_input = (IntPtr)256;
479477
internal static IntPtr Py_file_input = (IntPtr)257;
@@ -2036,6 +2034,12 @@ internal static bool _PyObject_GC_IS_TRACKED(IntPtr ob)
20362034
return (long)_PyGC_REFS(ob) != _PyGC_REFS_UNTRACKED;
20372035
}
20382036

2037+
internal static void Py_CLEAR(ref IntPtr ob)
2038+
{
2039+
XDecref(ob);
2040+
ob = IntPtr.Zero;
2041+
}
2042+
20392043
//====================================================================
20402044
// Python Capsules API
20412045
//====================================================================

0 commit comments

Comments
 (0)
0