@@ -198,71 +198,91 @@ internal static void Initialize(bool initSigs = false)
198
198
IntPtr op ;
199
199
{
200
200
var builtins = GetBuiltins ( ) ;
201
- SetPyMember ( ref PyNotImplemented , PyObject_GetAttrString ( builtins , "NotImplemented" ) ) ;
202
-
203
- SetPyMember ( ref PyBaseObjectType , PyObject_GetAttrString ( builtins , "object" ) ) ;
204
-
205
- SetPyMember ( ref PyNone , PyObject_GetAttrString ( builtins , "None" ) ) ;
206
- SetPyMember ( ref PyTrue , PyObject_GetAttrString ( builtins , "True" ) ) ;
207
- SetPyMember ( ref PyFalse , PyObject_GetAttrString ( builtins , "False" ) ) ;
208
-
209
- SetPyMember ( ref PyBoolType , PyObject_Type ( PyTrue ) ) ;
210
- SetPyMember ( ref PyNoneType , PyObject_Type ( PyNone ) ) ;
211
- SetPyMember ( ref PyTypeType , PyObject_Type ( PyNoneType ) ) ;
201
+ SetPyMember ( ref PyNotImplemented , PyObject_GetAttrString ( builtins , "NotImplemented" ) ,
202
+ ( ) => PyNotImplemented = IntPtr . Zero ) ;
203
+
204
+ SetPyMember ( ref PyBaseObjectType , PyObject_GetAttrString ( builtins , "object" ) ,
205
+ ( ) => PyBaseObjectType = IntPtr . Zero ) ;
206
+
207
+ SetPyMember ( ref PyNone , PyObject_GetAttrString ( builtins , "None" ) ,
208
+ ( ) => PyNone = IntPtr . Zero ) ;
209
+ SetPyMember ( ref PyTrue , PyObject_GetAttrString ( builtins , "True" ) ,
210
+ ( ) => PyTrue = IntPtr . Zero ) ;
211
+ SetPyMember ( ref PyFalse , PyObject_GetAttrString ( builtins , "False" ) ,
212
+ ( ) => PyFalse = IntPtr . Zero ) ;
213
+
214
+ SetPyMember ( ref PyBoolType , PyObject_Type ( PyTrue ) ,
215
+ ( ) => PyBoolType = IntPtr . Zero ) ;
216
+ SetPyMember ( ref PyNoneType , PyObject_Type ( PyNone ) ,
217
+ ( ) => PyNoneType = IntPtr . Zero ) ;
218
+ SetPyMember ( ref PyTypeType , PyObject_Type ( PyNoneType ) ,
219
+ ( ) => PyTypeType = IntPtr . Zero ) ;
212
220
213
221
op = PyObject_GetAttrString ( builtins , "len" ) ;
214
- SetPyMember ( ref PyMethodType , PyObject_Type ( op ) ) ;
222
+ SetPyMember ( ref PyMethodType , PyObject_Type ( op ) ,
223
+ ( ) => PyMethodType = IntPtr . Zero ) ;
215
224
XDecref ( op ) ;
216
225
217
226
// For some arcane reason, builtins.__dict__.__setitem__ is *not*
218
227
// a wrapper_descriptor, even though dict.__setitem__ is.
219
228
//
220
229
// object.__init__ seems safe, though.
221
230
op = PyObject_GetAttrString ( PyBaseObjectType , "__init__" ) ;
222
- SetPyMember ( ref PyWrapperDescriptorType , PyObject_Type ( op ) ) ;
231
+ SetPyMember ( ref PyWrapperDescriptorType , PyObject_Type ( op ) ,
232
+ ( ) => PyWrapperDescriptorType = IntPtr . Zero ) ;
223
233
XDecref ( op ) ;
224
234
225
- SetPyMember ( ref PySuper_Type , PyObject_GetAttrString ( builtins , "super" ) ) ;
235
+ SetPyMember ( ref PySuper_Type , PyObject_GetAttrString ( builtins , "super" ) ,
236
+ ( ) => PySuper_Type = IntPtr . Zero ) ;
226
237
227
238
XDecref ( builtins ) ;
228
239
}
229
240
230
241
op = PyString_FromString ( "string" ) ;
231
- SetPyMember ( ref PyStringType , PyObject_Type ( op ) ) ;
242
+ SetPyMember ( ref PyStringType , PyObject_Type ( op ) ,
243
+ ( ) => PyStringType = IntPtr . Zero ) ;
232
244
XDecref ( op ) ;
233
245
234
246
op = PyUnicode_FromString ( "unicode" ) ;
235
- SetPyMember ( ref PyUnicodeType , PyObject_Type ( op ) ) ;
247
+ SetPyMember ( ref PyUnicodeType , PyObject_Type ( op ) ,
248
+ ( ) => PyUnicodeType = IntPtr . Zero ) ;
236
249
XDecref ( op ) ;
237
250
238
251
#if PYTHON3
239
252
op = PyBytes_FromString ( "bytes" ) ;
240
- SetPyMember ( ref PyBytesType , PyObject_Type ( op ) ) ;
253
+ SetPyMember ( ref PyBytesType , PyObject_Type ( op ) ,
254
+ ( ) => PyBytesType = IntPtr . Zero ) ;
241
255
XDecref ( op ) ;
242
256
#endif
243
257
244
258
op = PyTuple_New ( 0 ) ;
245
- SetPyMember ( ref PyTupleType , PyObject_Type ( op ) ) ;
259
+ SetPyMember ( ref PyTupleType , PyObject_Type ( op ) ,
260
+ ( ) => PyTupleType = IntPtr . Zero ) ;
246
261
XDecref ( op ) ;
247
262
248
263
op = PyList_New ( 0 ) ;
249
- SetPyMember ( ref PyListType , PyObject_Type ( op ) ) ;
264
+ SetPyMember ( ref PyListType , PyObject_Type ( op ) ,
265
+ ( ) => PyListType = IntPtr . Zero ) ;
250
266
XDecref ( op ) ;
251
267
252
268
op = PyDict_New ( ) ;
253
- SetPyMember ( ref PyDictType , PyObject_Type ( op ) ) ;
269
+ SetPyMember ( ref PyDictType , PyObject_Type ( op ) ,
270
+ ( ) => PyDictType = IntPtr . Zero ) ;
254
271
XDecref ( op ) ;
255
272
256
273
op = PyInt_FromInt32 ( 0 ) ;
257
- SetPyMember ( ref PyIntType , PyObject_Type ( op ) ) ;
274
+ SetPyMember ( ref PyIntType , PyObject_Type ( op ) ,
275
+ ( ) => PyIntType = IntPtr . Zero ) ;
258
276
XDecref ( op ) ;
259
277
260
278
op = PyLong_FromLong ( 0 ) ;
261
- SetPyMember ( ref PyLongType , PyObject_Type ( op ) ) ;
279
+ SetPyMember ( ref PyLongType , PyObject_Type ( op ) ,
280
+ ( ) => PyLongType = IntPtr . Zero ) ;
262
281
XDecref ( op ) ;
263
282
264
283
op = PyFloat_FromDouble ( 0 ) ;
265
- SetPyMember ( ref PyFloatType , PyObject_Type ( op ) ) ;
284
+ SetPyMember ( ref PyFloatType , PyObject_Type ( op ) ,
285
+ ( ) => PyFloatType = IntPtr . Zero ) ;
266
286
XDecref ( op ) ;
267
287
268
288
#if ! PYTHON2
@@ -274,10 +294,12 @@ internal static void Initialize(bool initSigs = false)
274
294
IntPtr d = PyDict_New ( ) ;
275
295
276
296
IntPtr c = PyClass_New ( IntPtr . Zero , d , s ) ;
277
- SetPyMember ( ref PyClassType , PyObject_Type ( c ) ) ;
297
+ SetPyMember ( ref PyClassType , PyObject_Type ( c ) ,
298
+ ( ) => PyClassType = IntPtr . Zero ) ;
278
299
279
300
IntPtr i = PyInstance_New ( c , IntPtr . Zero , IntPtr . Zero ) ;
280
- SetPyMember ( ref PyInstanceType , PyObject_Type ( i ) ) ;
301
+ SetPyMember ( ref PyInstanceType , PyObject_Type ( i ) ,
302
+ ( ) => PyInstanceType = IntPtr . Zero ) ;
281
303
282
304
XDecref ( s ) ;
283
305
XDecref ( i ) ;
@@ -393,12 +415,12 @@ internal static int AtExit()
393
415
return 0 ;
394
416
}
395
417
396
- private static void SetPyMember ( ref IntPtr obj , IntPtr value )
418
+ private static void SetPyMember ( ref IntPtr obj , IntPtr value , Action onRelease )
397
419
{
398
420
// XXX: For current usages, value should not be null.
399
421
PythonException . ThrowIfIsNull ( value ) ;
400
422
obj = value ;
401
- _pyRefs . Add ( ref obj ) ;
423
+ _pyRefs . Add ( value , onRelease ) ;
402
424
}
403
425
404
426
private static void ResetPyMembers ( )
@@ -977,7 +999,7 @@ internal static int PyObject_Compare(IntPtr value1, IntPtr value2)
977
999
978
1000
internal static long PyObject_Size( IntPtr pointer)
979
1001
{
980
- return ( long ) _PyObject_Size( pointer) ;
1002
+ return ( long ) _PyObject_Size( pointer) ;
981
1003
}
982
1004
983
1005
[ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PyObject_Size") ]
@@ -1093,7 +1115,7 @@ internal static bool PyLong_Check(IntPtr ob)
1093
1115
1094
1116
internal static IntPtr PyLong_FromUnsignedLong( object value)
1095
1117
{
1096
- if ( Is32Bit || IsWindows)
1118
+ if ( Is32Bit || IsWindows)
1097
1119
return PyLong_FromUnsignedLong32( Convert. ToUInt32( value) ) ;
1098
1120
else
1099
1121
return PyLong_FromUnsignedLong64( Convert. ToUInt64( value) ) ;
@@ -1283,7 +1305,7 @@ internal static int PySequence_DelSlice(IntPtr pointer, long i1, long i2)
1283
1305
1284
1306
internal static long PySequence_Size( IntPtr pointer)
1285
1307
{
1286
- return ( long ) _PySequence_Size( pointer) ;
1308
+ return ( long ) _PySequence_Size( pointer) ;
1287
1309
}
1288
1310
1289
1311
[ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PySequence_Size") ]
@@ -1308,7 +1330,7 @@ internal static IntPtr PySequence_Repeat(IntPtr pointer, long count)
1308
1330
1309
1331
internal static long PySequence_Count( IntPtr pointer, IntPtr value)
1310
1332
{
1311
- return ( long ) _PySequence_Count( pointer, value) ;
1333
+ return ( long ) _PySequence_Count( pointer, value) ;
1312
1334
}
1313
1335
1314
1336
[ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PySequence_Count") ]
@@ -1351,7 +1373,7 @@ internal static IntPtr PyString_FromString(string value)
1351
1373
1352
1374
internal static long PyBytes_Size( IntPtr op)
1353
1375
{
1354
- return ( long ) _PyBytes_Size( op) ;
1376
+ return ( long ) _PyBytes_Size( op) ;
1355
1377
}
1356
1378
1357
1379
[ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PyBytes_Size") ]
@@ -1582,7 +1604,7 @@ internal static bool PyDict_Check(IntPtr ob)
1582
1604
1583
1605
internal static long PyDict_Size( IntPtr pointer)
1584
1606
{
1585
- return ( long ) _PyDict_Size( pointer) ;
1607
+ return ( long ) _PyDict_Size( pointer) ;
1586
1608
}
1587
1609
1588
1610
[ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PyDict_Size") ]
@@ -1660,7 +1682,7 @@ internal static int PyList_SetSlice(IntPtr pointer, long start, long end, IntPtr
1660
1682
1661
1683
internal static long PyList_Size( IntPtr pointer)
1662
1684
{
1663
- return ( long ) _PyList_Size( pointer) ;
1685
+ return ( long ) _PyList_Size( pointer) ;
1664
1686
}
1665
1687
1666
1688
[ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PyList_Size") ]
@@ -1709,7 +1731,7 @@ internal static IntPtr PyTuple_GetSlice(IntPtr pointer, long start, long end)
1709
1731
1710
1732
internal static long PyTuple_Size( IntPtr pointer)
1711
1733
{
1712
- return ( long ) _PyTuple_Size( pointer) ;
1734
+ return ( long ) _PyTuple_Size( pointer) ;
1713
1735
}
1714
1736
1715
1737
[ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PyTuple_Size") ]
@@ -1976,40 +1998,25 @@ internal static IntPtr GetBuiltins()
1976
1998
1977
1999
class PyReferenceCollection
1978
2000
{
1979
- public List< IntPtr> _objects { get ; private set ; }
1980
-
1981
- public PyReferenceCollection( )
1982
- {
1983
- _objects = new List< IntPtr> ( ) ;
1984
- }
2001
+ private List< KeyValuePair< IntPtr, Action>> _actions = new List< KeyValuePair< IntPtr, Action>> ( ) ;
1985
2002
1986
2003
/// <summary>
1987
2004
/// Record obj's address to release the obj in the future,
1988
2005
/// obj must alive before calling Release.
1989
2006
/// </summary>
1990
- public void Add( ref IntPtr obj )
2007
+ public void Add( IntPtr ob , Action onRelease )
1991
2008
{
1992
- unsafe
1993
- {
1994
- fixed ( void * p = & obj)
1995
- {
1996
- _objects. Add( ( IntPtr) p) ;
1997
- }
1998
- }
2009
+ _actions. Add( new KeyValuePair< IntPtr, Action> ( ob, onRelease) ) ;
1999
2010
}
2000
2011
2001
2012
public void Release( )
2002
2013
{
2003
- foreach ( var objRef in _objects )
2014
+ foreach ( var item in _actions )
2004
2015
{
2005
- unsafe
2006
- {
2007
- var p = ( void * * ) objRef;
2008
- Runtime. XDecref( ( IntPtr) ( * p) ) ;
2009
- * p = null ;
2010
- }
2016
+ Runtime. XDecref( item. Key) ;
2017
+ item. Value? . Invoke( ) ;
2011
2018
}
2012
- _objects . Clear( ) ;
2019
+ _actions . Clear( ) ;
2013
2020
}
2014
2021
}
2015
2022
}
0 commit comments