Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit430ea6e

Browse files
authored
Merge branch 'master' into features/PerfTests-CI
2 parentsfb6015e +3b938a5 commit430ea6e

File tree

2 files changed

+139
-87
lines changed

2 files changed

+139
-87
lines changed

‎src/runtime/importhook.cs

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,6 @@ internal static void ReleaseModuleDef()
3535
}
3636
#endif
3737

38-
/// <summary>
39-
/// Get a <i>New reference</i> to the builtins module.
40-
/// </summary>
41-
staticIntPtrGetNewRefToBuiltins()
42-
{
43-
if(Runtime.IsPython3)
44-
{
45-
returnRuntime.PyImport_ImportModule("builtins");
46-
}
47-
else
48-
{
49-
// dict is a borrowed ref, no need to decref
50-
IntPtrdict=Runtime.PyImport_GetModuleDict();
51-
52-
// GetItemString is a borrowed ref; incref to get a new ref
53-
IntPtrbuiltins=Runtime.PyDict_GetItemString(dict,"__builtin__");
54-
Runtime.XIncref(builtins);
55-
returnbuiltins;
56-
}
57-
}
58-
5938
/// <summary>
6039
/// Initialize just the __import__ hook itself.
6140
/// </summary>
@@ -64,7 +43,7 @@ static void InitImport()
6443
// We replace the built-in Python __import__ with our own: first
6544
// look in CLR modules, then if we don't find any call the default
6645
// Python __import__.
67-
IntPtrbuiltins=GetNewRefToBuiltins();
46+
IntPtrbuiltins=Runtime.GetBuiltins();
6847
py_import=Runtime.PyObject_GetAttrString(builtins,"__import__");
6948
PythonException.ThrowIfIsNull(py_import);
7049

@@ -80,7 +59,7 @@ static void InitImport()
8059
/// </summary>
8160
staticvoidRestoreImport()
8261
{
83-
IntPtrbuiltins=GetNewRefToBuiltins();
62+
IntPtrbuiltins=Runtime.GetBuiltins();
8463

8564
intres=Runtime.PyObject_SetAttrString(builtins,"__import__",py_import);
8665
PythonException.ThrowIfIsNotZero(res);

‎src/runtime/runtime.cs

Lines changed: 137 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ public class Runtime
169169
/// </summary>
170170
internalstaticreadonlyEncodingPyEncoding=_UCS==2?Encoding.Unicode:Encoding.UTF32;
171171

172+
privatestaticPyReferenceCollection_pyRefs=newPyReferenceCollection();
173+
172174
/// <summary>
173175
/// Initialize the runtime...
174176
/// </summary>
@@ -194,99 +196,116 @@ internal static void Initialize(bool initSigs = false)
194196
TypeManager.Reset();
195197

196198
IntPtrop;
197-
IntPtrdict;
198-
if(IsPython3)
199-
{
200-
op=PyImport_ImportModule("builtins");
201-
dict=PyObject_GetAttrString(op,"__dict__");
202-
}
203-
else// Python2
204199
{
205-
dict=PyImport_GetModuleDict();
206-
op=PyDict_GetItemString(dict,"__builtin__");
200+
varbuiltins=GetBuiltins();
201+
SetPyMember(refPyNotImplemented,PyObject_GetAttrString(builtins,"NotImplemented"),
202+
()=>PyNotImplemented=IntPtr.Zero);
203+
204+
SetPyMember(refPyBaseObjectType,PyObject_GetAttrString(builtins,"object"),
205+
()=>PyBaseObjectType=IntPtr.Zero);
206+
207+
SetPyMember(refPyNone,PyObject_GetAttrString(builtins,"None"),
208+
()=>PyNone=IntPtr.Zero);
209+
SetPyMember(refPyTrue,PyObject_GetAttrString(builtins,"True"),
210+
()=>PyTrue=IntPtr.Zero);
211+
SetPyMember(refPyFalse,PyObject_GetAttrString(builtins,"False"),
212+
()=>PyFalse=IntPtr.Zero);
213+
214+
SetPyMember(refPyBoolType,PyObject_Type(PyTrue),
215+
()=>PyBoolType=IntPtr.Zero);
216+
SetPyMember(refPyNoneType,PyObject_Type(PyNone),
217+
()=>PyNoneType=IntPtr.Zero);
218+
SetPyMember(refPyTypeType,PyObject_Type(PyNoneType),
219+
()=>PyTypeType=IntPtr.Zero);
220+
221+
op=PyObject_GetAttrString(builtins,"len");
222+
SetPyMember(refPyMethodType,PyObject_Type(op),
223+
()=>PyMethodType=IntPtr.Zero);
224+
XDecref(op);
225+
226+
// For some arcane reason, builtins.__dict__.__setitem__ is *not*
227+
// a wrapper_descriptor, even though dict.__setitem__ is.
228+
//
229+
// object.__init__ seems safe, though.
230+
op=PyObject_GetAttrString(PyBaseObjectType,"__init__");
231+
SetPyMember(refPyWrapperDescriptorType,PyObject_Type(op),
232+
()=>PyWrapperDescriptorType=IntPtr.Zero);
233+
XDecref(op);
234+
235+
SetPyMember(refPySuper_Type,PyObject_GetAttrString(builtins,"super"),
236+
()=>PySuper_Type=IntPtr.Zero);
237+
238+
XDecref(builtins);
207239
}
208-
PyNotImplemented=PyObject_GetAttrString(op,"NotImplemented");
209-
PyBaseObjectType=PyObject_GetAttrString(op,"object");
210-
211-
PyNone=PyObject_GetAttrString(op,"None");
212-
PyTrue=PyObject_GetAttrString(op,"True");
213-
PyFalse=PyObject_GetAttrString(op,"False");
214-
215-
PyBoolType=PyObject_Type(PyTrue);
216-
PyNoneType=PyObject_Type(PyNone);
217-
PyTypeType=PyObject_Type(PyNoneType);
218-
219-
op=PyObject_GetAttrString(dict,"keys");
220-
PyMethodType=PyObject_Type(op);
221-
XDecref(op);
222-
223-
// For some arcane reason, builtins.__dict__.__setitem__ is *not*
224-
// a wrapper_descriptor, even though dict.__setitem__ is.
225-
//
226-
// object.__init__ seems safe, though.
227-
op=PyObject_GetAttrString(PyBaseObjectType,"__init__");
228-
PyWrapperDescriptorType=PyObject_Type(op);
229-
XDecref(op);
230-
231-
#ifPYTHON3
232-
XDecref(dict);
233-
#endif
234240

235241
op=PyString_FromString("string");
236-
PyStringType=PyObject_Type(op);
242+
SetPyMember(refPyStringType,PyObject_Type(op),
243+
()=>PyStringType=IntPtr.Zero);
237244
XDecref(op);
238245

239246
op=PyUnicode_FromString("unicode");
240-
PyUnicodeType=PyObject_Type(op);
247+
SetPyMember(refPyUnicodeType,PyObject_Type(op),
248+
()=>PyUnicodeType=IntPtr.Zero);
241249
XDecref(op);
242250

243251
#ifPYTHON3
244252
op=PyBytes_FromString("bytes");
245-
PyBytesType=PyObject_Type(op);
253+
SetPyMember(refPyBytesType,PyObject_Type(op),
254+
()=>PyBytesType=IntPtr.Zero);
246255
XDecref(op);
247256
#endif
248257

249258
op=PyTuple_New(0);
250-
PyTupleType=PyObject_Type(op);
259+
SetPyMember(refPyTupleType,PyObject_Type(op),
260+
()=>PyTupleType=IntPtr.Zero);
251261
XDecref(op);
252262

253263
op=PyList_New(0);
254-
PyListType=PyObject_Type(op);
264+
SetPyMember(refPyListType,PyObject_Type(op),
265+
()=>PyListType=IntPtr.Zero);
255266
XDecref(op);
256267

257268
op=PyDict_New();
258-
PyDictType=PyObject_Type(op);
269+
SetPyMember(refPyDictType,PyObject_Type(op),
270+
()=>PyDictType=IntPtr.Zero);
259271
XDecref(op);
260272

261273
op=PyInt_FromInt32(0);
262-
PyIntType=PyObject_Type(op);
274+
SetPyMember(refPyIntType,PyObject_Type(op),
275+
()=>PyIntType=IntPtr.Zero);
263276
XDecref(op);
264277

265278
op=PyLong_FromLong(0);
266-
PyLongType=PyObject_Type(op);
279+
SetPyMember(refPyLongType,PyObject_Type(op),
280+
()=>PyLongType=IntPtr.Zero);
267281
XDecref(op);
268282

269283
op=PyFloat_FromDouble(0);
270-
PyFloatType=PyObject_Type(op);
284+
SetPyMember(refPyFloatType,PyObject_Type(op),
285+
()=>PyFloatType=IntPtr.Zero);
271286
XDecref(op);
272287

273-
#ifPYTHON3
288+
#if!PYTHON2
274289
PyClassType=IntPtr.Zero;
275290
PyInstanceType=IntPtr.Zero;
276-
#elifPYTHON2
277-
IntPtrs=PyString_FromString("_temp");
278-
IntPtrd=PyDict_New();
291+
#else
292+
{
293+
IntPtrs=PyString_FromString("_temp");
294+
IntPtrd=PyDict_New();
279295

280-
IntPtrc=PyClass_New(IntPtr.Zero,d,s);
281-
PyClassType=PyObject_Type(c);
296+
IntPtrc=PyClass_New(IntPtr.Zero,d,s);
297+
SetPyMember(refPyClassType,PyObject_Type(c),
298+
()=>PyClassType=IntPtr.Zero);
282299

283-
IntPtri=PyInstance_New(c,IntPtr.Zero,IntPtr.Zero);
284-
PyInstanceType=PyObject_Type(i);
300+
IntPtri=PyInstance_New(c,IntPtr.Zero,IntPtr.Zero);
301+
SetPyMember(refPyInstanceType,PyObject_Type(i),
302+
()=>PyInstanceType=IntPtr.Zero);
285303

286-
XDecref(s);
287-
XDecref(i);
288-
XDecref(c);
289-
XDecref(d);
304+
XDecref(s);
305+
XDecref(i);
306+
XDecref(c);
307+
XDecref(d);
308+
}
290309
#endif
291310

292311
Error=newIntPtr(-1);
@@ -380,6 +399,9 @@ internal static void Shutdown()
380399
Exceptions.Shutdown();
381400
ImportHook.Shutdown();
382401
Finalizer.Shutdown();
402+
// TOOD: PyCLRMetaType's release operation still in #958
403+
PyCLRMetaType=IntPtr.Zero;
404+
ResetPyMembers();
383405
Py_Finalize();
384406
}
385407

@@ -393,6 +415,19 @@ internal static int AtExit()
393415
return0;
394416
}
395417

418+
privatestaticvoidSetPyMember(refIntPtrobj,IntPtrvalue,ActiononRelease)
419+
{
420+
// XXX: For current usages, value should not be null.
421+
PythonException.ThrowIfIsNull(value);
422+
obj=value;
423+
_pyRefs.Add(value,onRelease);
424+
}
425+
426+
privatestaticvoidResetPyMembers()
427+
{
428+
_pyRefs.Release();
429+
}
430+
396431
internalstaticIntPtrPy_single_input=(IntPtr)256;
397432
internalstaticIntPtrPy_file_input=(IntPtr)257;
398433
internalstaticIntPtrPy_eval_input=(IntPtr)258;
@@ -401,6 +436,7 @@ internal static int AtExit()
401436
internalstaticIntPtrPyModuleType;
402437
internalstaticIntPtrPyClassType;
403438
internalstaticIntPtrPyInstanceType;
439+
internalstaticIntPtrPySuper_Type;
404440
internalstaticIntPtrPyCLRMetaType;
405441
internalstaticIntPtrPyMethodType;
406442
internalstaticIntPtrPyWrapperDescriptorType;
@@ -963,7 +999,7 @@ internal static int PyObject_Compare(IntPtr value1, IntPtr value2)
963999

9641000
internalstaticlong PyObject_Size(IntPtr pointer)
9651001
{
966-
return(long)_PyObject_Size(pointer);
1002+
return(long)_PyObject_Size(pointer);
9671003
}
9681004

9691005
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl, EntryPoint= "PyObject_Size")]
@@ -1079,7 +1115,7 @@ internal static bool PyLong_Check(IntPtr ob)
10791115

10801116
internalstatic IntPtr PyLong_FromUnsignedLong(object value)
10811117
{
1082-
if(Is32Bit|| IsWindows)
1118+
if(Is32Bit|| IsWindows)
10831119
return PyLong_FromUnsignedLong32(Convert.ToUInt32(value));
10841120
else
10851121
return PyLong_FromUnsignedLong64(Convert.ToUInt64(value));
@@ -1269,7 +1305,7 @@ internal static int PySequence_DelSlice(IntPtr pointer, long i1, long i2)
12691305

12701306
internalstaticlong PySequence_Size(IntPtr pointer)
12711307
{
1272-
return(long)_PySequence_Size(pointer);
1308+
return(long)_PySequence_Size(pointer);
12731309
}
12741310

12751311
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl, EntryPoint= "PySequence_Size")]
@@ -1294,7 +1330,7 @@ internal static IntPtr PySequence_Repeat(IntPtr pointer, long count)
12941330

12951331
internalstaticlong PySequence_Count(IntPtr pointer, IntPtr value)
12961332
{
1297-
return(long)_PySequence_Count(pointer, value);
1333+
return(long)_PySequence_Count(pointer, value);
12981334
}
12991335

13001336
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl, EntryPoint= "PySequence_Count")]
@@ -1337,7 +1373,7 @@ internal static IntPtr PyString_FromString(string value)
13371373

13381374
internalstaticlong PyBytes_Size(IntPtr op)
13391375
{
1340-
return(long)_PyBytes_Size(op);
1376+
return(long)_PyBytes_Size(op);
13411377
}
13421378

13431379
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl, EntryPoint= "PyBytes_Size")]
@@ -1568,7 +1604,7 @@ internal static bool PyDict_Check(IntPtr ob)
15681604

15691605
internalstaticlong PyDict_Size(IntPtr pointer)
15701606
{
1571-
return(long)_PyDict_Size(pointer);
1607+
return(long)_PyDict_Size(pointer);
15721608
}
15731609

15741610
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl, EntryPoint= "PyDict_Size")]
@@ -1646,7 +1682,7 @@ internal static int PyList_SetSlice(IntPtr pointer, long start, long end, IntPtr
16461682

16471683
internalstaticlong PyList_Size(IntPtr pointer)
16481684
{
1649-
return(long)_PyList_Size(pointer);
1685+
return(long)_PyList_Size(pointer);
16501686
}
16511687

16521688
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl, EntryPoint= "PyList_Size")]
@@ -1695,7 +1731,7 @@ internal static IntPtr PyTuple_GetSlice(IntPtr pointer, long start, long end)
16951731

16961732
internalstaticlong PyTuple_Size(IntPtr pointer)
16971733
{
1698-
return(long)_PyTuple_Size(pointer);
1734+
return(long)_PyTuple_Size(pointer);
16991735
}
17001736

17011737
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl, EntryPoint= "PyTuple_Size")]
@@ -1746,6 +1782,9 @@ internal static bool PyIter_Check(IntPtr pointer)
17461782
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
17471783
internalstaticextern IntPtr PyImport_Import(IntPtr name);
17481784

1785+
/// <summary>
1786+
/// Return value: New reference.
1787+
/// </summary>
17491788
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
17501789
internalstaticextern IntPtr PyImport_ImportModule(string name);
17511790

@@ -1945,5 +1984,39 @@ internal static void SetNoSiteFlag()
19451984
}
19461985
}
19471986
}
1987+
1988+
/// <summary>
1989+
/// Return value: New reference.
1990+
/// </summary>
1991+
internalstatic IntPtr GetBuiltins()
1992+
{
1993+
return IsPython3? PyImport_ImportModule("builtins")
1994+
: PyImport_ImportModule("__builtin__");
1995+
}
1996+
}
1997+
1998+
1999+
class PyReferenceCollection
2000+
{
2001+
private List<KeyValuePair<IntPtr, Action>> _actions=new List<KeyValuePair<IntPtr, Action>>();
2002+
2003+
/// <summary>
2004+
/// Record obj's address to release the obj in the future,
2005+
/// obj must alive before calling Release.
2006+
/// </summary>
2007+
publicvoid Add(IntPtr ob, Action onRelease)
2008+
{
2009+
_actions.Add(new KeyValuePair<IntPtr, Action>(ob, onRelease));
2010+
}
2011+
2012+
publicvoid Release()
2013+
{
2014+
foreach(var itemin _actions)
2015+
{
2016+
Runtime.XDecref(item.Key);
2017+
item.Value?.Invoke();
2018+
}
2019+
_actions.Clear();
2020+
}
19482021
}
19492022
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp