Skip to content

Commit bdc0f72

Browse files
committed
* Use subtype slots instead JIT code
* Correct signature of PyRun_String
1 parent fba616a commit bdc0f72

9 files changed

Lines changed: 112 additions & 61 deletions

File tree

src/runtime/classbase.cs

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -299,29 +299,9 @@ public static int tp_clear(IntPtr ob)
299299
{
300300
ClearObjectDict(ob);
301301
}
302+
self.tpHandle = IntPtr.Zero;
302303
Runtime.Py_CLEAR(ref self.tpHandle);
303304
return 0;
304305
}
305-
306-
private static IntPtr GetObjectDict(IntPtr ob)
307-
{
308-
return Marshal.ReadIntPtr(ob, ObjectOffset.DictOffset(ob));
309-
}
310-
311-
private static void SetObjectDict(IntPtr ob, IntPtr value)
312-
{
313-
Marshal.WriteIntPtr(ob, ObjectOffset.DictOffset(ob), value);
314-
}
315-
316-
private static void ClearObjectDict(IntPtr ob)
317-
{
318-
IntPtr dict = GetObjectDict(ob);
319-
if (dict == IntPtr.Zero)
320-
{
321-
return;
322-
}
323-
SetObjectDict(ob, IntPtr.Zero);
324-
Runtime.XDecref(dict);
325-
}
326306
}
327307
}

src/runtime/classmanager.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ internal static void RemoveClasses()
5353
{
5454
foreach (var cls in cache.Values)
5555
{
56-
cls.TypeTraverse(OnVisit, visitedPtr);
56+
cls.CallTypeTraverse(OnVisit, visitedPtr);
5757
// XXX: Force release instance resources but not dealloc itself.
58-
cls.TypeClear();
58+
cls.CallTypeClear();
5959
}
6060
}
6161
finally
@@ -75,8 +75,8 @@ private static int OnVisit(IntPtr ob, IntPtr arg)
7575
var clrObj = ManagedType.GetManagedObject(ob);
7676
if (clrObj != null)
7777
{
78-
clrObj.TypeTraverse(OnVisit, arg);
79-
clrObj.TypeClear();
78+
clrObj.CallTypeTraverse(OnVisit, arg);
79+
clrObj.CallTypeClear();
8080
}
8181
return 0;
8282
}

src/runtime/extensiontype.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public ExtensionType()
4949
/// </summary>
5050
public static void FinalizeObject(ManagedType self)
5151
{
52+
ClearObjectDict(self.pyHandle);
5253
Runtime.PyObject_GC_Del(self.pyHandle);
5354
// Not necessary for decref of `tpHandle`.
5455
self.FreeGCHandle();

src/runtime/managedtype.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ internal static int PyVisit(IntPtr ob, IntPtr visit, IntPtr arg)
149149
/// <summary>
150150
/// Wrapper for calling tp_clear
151151
/// </summary>
152-
internal void TypeClear()
152+
internal void CallTypeClear()
153153
{
154154
if (tpHandle == IntPtr.Zero || pyHandle == IntPtr.Zero)
155155
{
@@ -168,7 +168,7 @@ internal void TypeClear()
168168
/// <summary>
169169
/// Wrapper for calling tp_traverse
170170
/// </summary>
171-
internal void TypeTraverse(Interop.ObjObjFunc visitproc, IntPtr arg)
171+
internal void CallTypeTraverse(Interop.ObjObjFunc visitproc, IntPtr arg)
172172
{
173173
if (tpHandle == IntPtr.Zero || pyHandle == IntPtr.Zero)
174174
{
@@ -184,5 +184,31 @@ internal void TypeTraverse(Interop.ObjObjFunc visitproc, IntPtr arg)
184184
// TODO: Handle errors base on return value
185185
traverseFunc(pyHandle, visiPtr, arg);
186186
}
187+
188+
protected void TypeClear()
189+
{
190+
ClearObjectDict(pyHandle);
191+
}
192+
193+
protected static void ClearObjectDict(IntPtr ob)
194+
{
195+
IntPtr dict = GetObjectDict(ob);
196+
if (dict == IntPtr.Zero)
197+
{
198+
return;
199+
}
200+
SetObjectDict(ob, IntPtr.Zero);
201+
Runtime.XDecref(dict);
202+
}
203+
204+
private static IntPtr GetObjectDict(IntPtr ob)
205+
{
206+
return Marshal.ReadIntPtr(ob, ObjectOffset.DictOffset(ob));
207+
}
208+
209+
private static void SetObjectDict(IntPtr ob, IntPtr value)
210+
{
211+
Marshal.WriteIntPtr(ob, ObjectOffset.DictOffset(ob), value);
212+
}
187213
}
188214
}

src/runtime/methodobject.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,15 @@ public static IntPtr tp_repr(IntPtr ob)
208208
{
209209
var self = (MethodObject)GetManagedObject(ob);
210210
self.ClearMembers();
211+
ClearObjectDict(ob);
211212
self.Dealloc();
212213
}
213214

214215
public static int tp_clear(IntPtr ob)
215216
{
216217
var self = (MethodObject)GetManagedObject(ob);
217218
self.ClearMembers();
219+
ClearObjectDict(ob);
218220
return 0;
219221
}
220222
}

src/runtime/pyscope.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,8 @@ public PyObject Eval(string code, PyDict locals = null)
277277
{
278278
Check();
279279
IntPtr _locals = locals == null ? variables : locals.obj;
280-
var flag = (IntPtr)Runtime.Py_eval_input;
281280
IntPtr ptr = Runtime.PyRun_String(
282-
code, flag, variables, _locals
281+
code, RunFlagType.Eval, variables, _locals
283282
);
284283
Runtime.CheckExceptionOccurred();
285284
return new PyObject(ptr);
@@ -315,9 +314,8 @@ public void Exec(string code, PyDict locals = null)
315314

316315
private void Exec(string code, IntPtr _globals, IntPtr _locals)
317316
{
318-
var flag = (IntPtr)Runtime.Py_file_input;
319317
IntPtr ptr = Runtime.PyRun_String(
320-
code, flag, _globals, _locals
318+
code, RunFlagType.File, _globals, _locals
321319
);
322320
Runtime.CheckExceptionOccurred();
323321
if (ptr != Runtime.PyNone)

src/runtime/pythonengine.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ internal static PyObject RunString(string code, IntPtr? globals, IntPtr? locals,
600600
try
601601
{
602602
IntPtr result = Runtime.PyRun_String(
603-
code, (IntPtr)flag, globals.Value, locals.Value
603+
code, flag, globals.Value, locals.Value
604604
);
605605

606606
Runtime.CheckExceptionOccurred();

src/runtime/runtime.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ internal static void Initialize(bool initSigs = false, bool softShutdown = false
209209
PyScopeManager.Reset();
210210
ClassManager.Reset();
211211
ClassDerivedObject.Reset();
212-
TypeManager.Reset();
212+
TypeManager.Initialize();
213213

214214
IntPtr op;
215215
{
@@ -527,7 +527,7 @@ private static void MoveClrInstancesOnwershipToPython()
527527
{
528528
continue;
529529
}
530-
obj.TypeClear();
530+
obj.CallTypeClear();
531531
// obj's tp_type will degenerate to a pure Python type after TypeManager.RemoveTypes(),
532532
// thus just be safe to give it back to GC chain.
533533
PyObject_GC_Track(obj.pyHandle);
@@ -537,11 +537,6 @@ private static void MoveClrInstancesOnwershipToPython()
537537
ManagedType.ClearTrackedObjects();
538538
}
539539

540-
541-
internal static IntPtr Py_single_input = (IntPtr)256;
542-
internal static IntPtr Py_file_input = (IntPtr)257;
543-
internal static IntPtr Py_eval_input = (IntPtr)258;
544-
545540
internal static IntPtr PyBaseObjectType;
546541
internal static IntPtr PyModuleType;
547542
internal static IntPtr PyClassType;
@@ -903,7 +898,7 @@ public static extern int Py_Main(
903898
internal static extern int PyRun_SimpleString(string code);
904899

905900
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
906-
internal static extern IntPtr PyRun_String(string code, IntPtr st, IntPtr globals, IntPtr locals);
901+
internal static extern IntPtr PyRun_String(string code, RunFlagType st, IntPtr globals, IntPtr locals);
907902

908903
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
909904
internal static extern IntPtr PyEval_EvalCode(IntPtr co, IntPtr globals, IntPtr locals);
@@ -2013,7 +2008,7 @@ internal static IntPtr PyType_GenericAlloc(IntPtr type, long n)
20132008
private static extern IntPtr PyType_GenericAlloc(IntPtr type, IntPtr n);
20142009

20152010
/// <summary>
2016-
/// Finalize a type object. This should be called on all type objects to finish their initialization. This function is responsible for adding inherited slots from a type¡¯s base class. Return 0 on success, or return -1 and sets an exception on error.
2011+
/// Finalize a type object. This should be called on all type objects to finish their initialization. This function is responsible for adding inherited slots from a types base class. Return 0 on success, or return -1 and sets an exception on error.
20172012
/// </summary>
20182013
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
20192014
internal static extern int PyType_Ready(IntPtr type);

0 commit comments

Comments
 (0)