| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -35,27 +35,6 @@ internal static void ReleaseModuleDef() | |||
| 35 | 35 | } | |
| 36 | 36 | #endif | |
| 37 | 37 | ||
| 38 | - /// <summary> | ||
| 39 | - /// Get a <i>New reference</i> to the builtins module. | ||
| 40 | - /// </summary> | ||
| 41 | - static IntPtr GetNewRefToBuiltins() | ||
| 42 | - { | ||
| 43 | - if (Runtime.IsPython3) | ||
| 44 | - { | ||
| 45 | - return Runtime.PyImport_ImportModule("builtins"); | ||
| 46 | - } | ||
| 47 | - else | ||
| 48 | - { | ||
| 49 | - // dict is a borrowed ref, no need to decref | ||
| 50 | - IntPtr dict = Runtime.PyImport_GetModuleDict(); | ||
| 51 | - | ||
| 52 | - // GetItemString is a borrowed ref; incref to get a new ref | ||
| 53 | - IntPtr builtins = Runtime.PyDict_GetItemString(dict, "__builtin__"); | ||
| 54 | - Runtime.XIncref(builtins); | ||
| 55 | - return builtins; | ||
| 56 | - } | ||
| 57 | - } | ||
| 58 | - | ||
| 59 | 38 | /// <summary> | |
| 60 | 39 | /// Initialize just the __import__ hook itself. | |
| 61 | 40 | /// </summary> | |
@@ -64,7 +43,7 @@ static void InitImport() | |||
| 64 | 43 | // We replace the built-in Python __import__ with our own: first | |
| 65 | 44 | // look in CLR modules, then if we don't find any call the default | |
| 66 | 45 | // Python __import__. | |
| 67 | - IntPtr builtins = GetNewRefToBuiltins(); | ||
| 46 | + IntPtr builtins = Runtime.GetBuiltins(); | ||
| 68 | 47 | py_import = Runtime.PyObject_GetAttrString(builtins, "__import__"); | |
| 69 | 48 | PythonException.ThrowIfIsNull(py_import); | |
| 70 | 49 | ||
@@ -80,7 +59,7 @@ static void InitImport() | |||
| 80 | 59 | /// </summary> | |
| 81 | 60 | static void RestoreImport() | |
| 82 | 61 | { | |
| 83 | - IntPtr builtins = GetNewRefToBuiltins(); | ||
| 62 | + IntPtr builtins = Runtime.GetBuiltins(); | ||
| 84 | 63 | ||
| 85 | 64 | int res = Runtime.PyObject_SetAttrString(builtins, "__import__", py_import); | |
| 86 | 65 | PythonException.ThrowIfIsNotZero(res); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -169,6 +169,8 @@ public class Runtime | |||
| 169 | 169 | /// </summary> | |
| 170 | 170 | internal static readonly Encoding PyEncoding = _UCS == 2 ? Encoding.Unicode : Encoding.UTF32; | |
| 171 | 171 | ||
| 172 | + private static PyReferenceCollection _pyRefs = new PyReferenceCollection(); | ||
| 173 | + | ||
| 172 | 174 | /// <summary> | |
| 173 | 175 | /// Initialize the runtime... | |
| 174 | 176 | /// </summary> | |
@@ -194,99 +196,94 @@ internal static void Initialize(bool initSigs = false) | |||
| 194 | 196 | TypeManager.Reset(); | |
| 195 | 197 | ||
| 196 | 198 | IntPtr op; | |
| 197 | - IntPtr dict; | ||
| 198 | - if (IsPython3) | ||
| 199 | - { | ||
| 200 | - op = PyImport_ImportModule("builtins"); | ||
| 201 | - dict = PyObject_GetAttrString(op, "__dict__"); | ||
| 202 | - } | ||
| 203 | - else // Python2 | ||
| 204 | 199 | { | |
| 205 | - dict = PyImport_GetModuleDict(); | ||
| 206 | - op = PyDict_GetItemString(dict, "__builtin__"); | ||
| 207 | - } | ||
| 208 | - PyNotImplemented = PyObject_GetAttrString(op, "NotImplemented"); | ||
| 209 | - PyBaseObjectType = PyObject_GetAttrString(op, "object"); | ||
| 200 | + var builtins = GetBuiltins(); | ||
| 201 | + SetPyMember(ref PyNotImplemented, PyObject_GetAttrString(builtins, "NotImplemented")); | ||
| 210 | 202 | ||
| 211 | - PyNone = PyObject_GetAttrString(op, "None"); | ||
| 212 | - PyTrue = PyObject_GetAttrString(op, "True"); | ||
| 213 | - PyFalse = PyObject_GetAttrString(op, "False"); | ||
| 203 | + SetPyMember(ref PyBaseObjectType, PyObject_GetAttrString(builtins, "object")); | ||
| 214 | 204 | ||
| 215 | - PyBoolType = PyObject_Type(PyTrue); | ||
| 216 | - PyNoneType = PyObject_Type(PyNone); | ||
| 217 | - PyTypeType = PyObject_Type(PyNoneType); | ||
| 205 | + SetPyMember(ref PyNone, PyObject_GetAttrString(builtins, "None")); | ||
| 206 | + SetPyMember(ref PyTrue, PyObject_GetAttrString(builtins, "True")); | ||
| 207 | + SetPyMember(ref PyFalse, PyObject_GetAttrString(builtins, "False")); | ||
| 218 | 208 | ||
| 219 | - op = PyObject_GetAttrString(dict, "keys"); | ||
| 220 | - PyMethodType = PyObject_Type(op); | ||
| 221 | - XDecref(op); | ||
| 209 | + SetPyMember(ref PyBoolType, PyObject_Type(PyTrue)); | ||
| 210 | + SetPyMember(ref PyNoneType, PyObject_Type(PyNone)); | ||
| 211 | + SetPyMember(ref PyTypeType, PyObject_Type(PyNoneType)); | ||
| 222 | 212 | ||
| 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); | ||
| 213 | + op = PyObject_GetAttrString(builtins, "len"); | ||
| 214 | + SetPyMember(ref PyMethodType, PyObject_Type(op)); | ||
| 215 | + XDecref(op); | ||
| 230 | 216 | ||
| 231 | - #if PYTHON3 | ||
| 232 | - XDecref(dict); | ||
| 233 | - #endif | ||
| 217 | + // For some arcane reason, builtins.__dict__.__setitem__ is *not* | ||
| 218 | + // a wrapper_descriptor, even though dict.__setitem__ is. | ||
| 219 | + // | ||
| 220 | + // object.__init__ seems safe, though. | ||
| 221 | + op = PyObject_GetAttrString(PyBaseObjectType, "__init__"); | ||
| 222 | + SetPyMember(ref PyWrapperDescriptorType, PyObject_Type(op)); | ||
| 223 | + XDecref(op); | ||
| 224 | + | ||
| 225 | + SetPyMember(ref PySuper_Type, PyObject_GetAttrString(builtins, "super")); | ||
| 226 | + | ||
| 227 | + XDecref(builtins); | ||
| 228 | + } | ||
| 234 | 229 | ||
| 235 | 230 | op = PyString_FromString("string"); | |
| 236 | - PyStringType = PyObject_Type(op); | ||
| 231 | + SetPyMember(ref PyStringType, PyObject_Type(op)); | ||
| 237 | 232 | XDecref(op); | |
| 238 | 233 | ||
| 239 | 234 | op = PyUnicode_FromString("unicode"); | |
| 240 | - PyUnicodeType = PyObject_Type(op); | ||
| 235 | + SetPyMember(ref PyUnicodeType, PyObject_Type(op)); | ||
| 241 | 236 | XDecref(op); | |
| 242 | 237 | ||
| 243 | 238 | #if PYTHON3 | |
| 244 | 239 | op = PyBytes_FromString("bytes"); | |
| 245 | - PyBytesType = PyObject_Type(op); | ||
| 240 | + SetPyMember(ref PyBytesType, PyObject_Type(op)); | ||
| 246 | 241 | XDecref(op); | |
| 247 | 242 | #endif | |
| 248 | 243 | ||
| 249 | 244 | op = PyTuple_New(0); | |
| 250 | - PyTupleType = PyObject_Type(op); | ||
| 245 | + SetPyMember(ref PyTupleType, PyObject_Type(op)); | ||
| 251 | 246 | XDecref(op); | |
| 252 | 247 | ||
| 253 | 248 | op = PyList_New(0); | |
| 254 | - PyListType = PyObject_Type(op); | ||
| 249 | + SetPyMember(ref PyListType, PyObject_Type(op)); | ||
| 255 | 250 | XDecref(op); | |
| 256 | 251 | ||
| 257 | 252 | op = PyDict_New(); | |
| 258 | - PyDictType = PyObject_Type(op); | ||
| 253 | + SetPyMember(ref PyDictType, PyObject_Type(op)); | ||
| 259 | 254 | XDecref(op); | |
| 260 | 255 | ||
| 261 | 256 | op = PyInt_FromInt32(0); | |
| 262 | - PyIntType = PyObject_Type(op); | ||
| 257 | + SetPyMember(ref PyIntType, PyObject_Type(op)); | ||
| 263 | 258 | XDecref(op); | |
| 264 | 259 | ||
| 265 | 260 | op = PyLong_FromLong(0); | |
| 266 | - PyLongType = PyObject_Type(op); | ||
| 261 | + SetPyMember(ref PyLongType, PyObject_Type(op)); | ||
| 267 | 262 | XDecref(op); | |
| 268 | 263 | ||
| 269 | 264 | op = PyFloat_FromDouble(0); | |
| 270 | - PyFloatType = PyObject_Type(op); | ||
| 265 | + SetPyMember(ref PyFloatType, PyObject_Type(op)); | ||
| 271 | 266 | XDecref(op); | |
| 272 | 267 | ||
| 273 | - #if PYTHON3 | ||
| 268 | + #if !PYTHON2 | ||
| 274 | 269 | PyClassType = IntPtr.Zero; | |
| 275 | 270 | PyInstanceType = IntPtr.Zero; | |
| 276 | - #elif PYTHON2 | ||
| 277 | - IntPtr s = PyString_FromString("_temp"); | ||
| 278 | - IntPtr d = PyDict_New(); | ||
| 271 | + #else | ||
| 272 | + { | ||
| 273 | + IntPtr s = PyString_FromString("_temp"); | ||
| 274 | + IntPtr d = PyDict_New(); | ||
| 279 | 275 | ||
| 280 | - IntPtr c = PyClass_New(IntPtr.Zero, d, s); | ||
| 281 | - PyClassType = PyObject_Type(c); | ||
| 276 | + IntPtr c = PyClass_New(IntPtr.Zero, d, s); | ||
| 277 | + SetPyMember(ref PyClassType, PyObject_Type(c)); | ||
| 282 | 278 | ||
| 283 | - IntPtr i = PyInstance_New(c, IntPtr.Zero, IntPtr.Zero); | ||
| 284 | - PyInstanceType = PyObject_Type(i); | ||
| 279 | + IntPtr i = PyInstance_New(c, IntPtr.Zero, IntPtr.Zero); | ||
| 280 | + SetPyMember(ref PyInstanceType, PyObject_Type(i)); | ||
| 285 | 281 | ||
| 286 | - XDecref(s); | ||
| 287 | - XDecref(i); | ||
| 288 | - XDecref(c); | ||
| 289 | - XDecref(d); | ||
| 282 | + XDecref(s); | ||
| 283 | + XDecref(i); | ||
| 284 | + XDecref(c); | ||
| 285 | + XDecref(d); | ||
| 286 | + } | ||
| 290 | 287 | #endif | |
| 291 | 288 | ||
| 292 | 289 | Error = new IntPtr(-1); | |
@@ -380,6 +377,9 @@ internal static void Shutdown() | |||
| 380 | 377 | Exceptions.Shutdown(); | |
| 381 | 378 | ImportHook.Shutdown(); | |
| 382 | 379 | Finalizer.Shutdown(); | |
| 380 | + // TOOD: PyCLRMetaType's release operation still in #958 | ||
| 381 | + PyCLRMetaType = IntPtr.Zero; | ||
| 382 | + ResetPyMembers(); | ||
| 383 | 383 | Py_Finalize(); | |
| 384 | 384 | } | |
| 385 | 385 | ||
@@ -393,6 +393,19 @@ internal static int AtExit() | |||
| 393 | 393 | return 0; | |
| 394 | 394 | } | |
| 395 | 395 | ||
| 396 | + private static void SetPyMember(ref IntPtr obj, IntPtr value) | ||
| 397 | + { | ||
| 398 | + // XXX: For current usages, value should not be null. | ||
| 399 | + PythonException.ThrowIfIsNull(value); | ||
| 400 | + obj = value; | ||
| 401 | + _pyRefs.Add(ref obj); | ||
| 402 | + } | ||
| 403 | + | ||
| 404 | + private static void ResetPyMembers() | ||
| 405 | + { | ||
| 406 | + _pyRefs.Release(); | ||
| 407 | + } | ||
| 408 | + | ||
| 396 | 409 | internal static IntPtr Py_single_input = (IntPtr)256; | |
| 397 | 410 | internal static IntPtr Py_file_input = (IntPtr)257; | |
| 398 | 411 | internal static IntPtr Py_eval_input = (IntPtr)258; | |
@@ -401,6 +414,7 @@ internal static int AtExit() | |||
| 401 | 414 | internal static IntPtr PyModuleType; | |
| 402 | 415 | internal static IntPtr PyClassType; | |
| 403 | 416 | internal static IntPtr PyInstanceType; | |
| 417 | + internal static IntPtr PySuper_Type; | ||
| 404 | 418 | internal static IntPtr PyCLRMetaType; | |
| 405 | 419 | internal static IntPtr PyMethodType; | |
| 406 | 420 | internal static IntPtr PyWrapperDescriptorType; | |
@@ -1746,6 +1760,9 @@ internal static bool PyIter_Check(IntPtr pointer) | |||
| 1746 | 1760 | [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] | |
| 1747 | 1761 | internal static extern IntPtr PyImport_Import(IntPtr name); | |
| 1748 | 1762 | ||
| 1763 | + /// <summary> | ||
| 1764 | + /// Return value: New reference. | ||
| 1765 | + /// </summary> | ||
| 1749 | 1766 | [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] | |
| 1750 | 1767 | internal static extern IntPtr PyImport_ImportModule(string name); | |
| 1751 | 1768 | ||
@@ -1945,5 +1962,54 @@ internal static void SetNoSiteFlag() | |||
| 1945 | 1962 | } | |
| 1946 | 1963 | } | |
| 1947 | 1964 | } | |
| 1965 | + | ||
| 1966 | + /// <summary> | ||
| 1967 | + /// Return value: New reference. | ||
| 1968 | + /// </summary> | ||
| 1969 | + internal static IntPtr GetBuiltins() | ||
| 1970 | + { | ||
| 1971 | + return IsPython3 ? PyImport_ImportModule("builtins") | ||
| 1972 | + : PyImport_ImportModule("__builtin__"); | ||
| 1973 | + } | ||
| 1974 | + } | ||
| 1975 | + | ||
| 1976 | + | ||
| 1977 | + class PyReferenceCollection | ||
| 1978 | + { | ||
| 1979 | + public List<IntPtr> _objects { get; private set; } | ||
| 1980 | + | ||
| 1981 | + public PyReferenceCollection() | ||
| 1982 | + { | ||
| 1983 | + _objects = new List<IntPtr>(); | ||
| 1984 | + } | ||
| 1985 | + | ||
| 1986 | + /// <summary> | ||
| 1987 | + /// Record obj's address to release the obj in the future, | ||
| 1988 | + /// obj must alive before calling Release. | ||
| 1989 | + /// </summary> | ||
| 1990 | + public void Add(ref IntPtr obj) | ||
| 1991 | + { | ||
| 1992 | + unsafe | ||
| 1993 | + { | ||
| 1994 | + fixed (void* p = &obj) | ||
| 1995 | + { | ||
| 1996 | + _objects.Add((IntPtr)p); | ||
| 1997 | + } | ||
| 1998 | + } | ||
| 1999 | + } | ||
| 2000 | + | ||
| 2001 | + public void Release() | ||
| 2002 | + { | ||
| 2003 | + foreach (var objRef in _objects) | ||
| 2004 | + { | ||
| 2005 | + unsafe | ||
| 2006 | + { | ||
| 2007 | + var p = (void**)objRef; | ||
| 2008 | + Runtime.XDecref((IntPtr)(*p)); | ||
| 2009 | + *p = null; | ||
| 2010 | + } | ||
| 2011 | + } | ||
| 2012 | + _objects.Clear(); | ||
| 2013 | + } | ||
| 1948 | 2014 | } | |
| 1949 | 2015 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments