FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

GitHub Viewer

using System.Reflection.Emit; using System; using System.Diagnostics.Contracts; using System.Runtime.InteropServices; using System.Security; using System.Text; using System.Threading; using System.Collections.Generic; using Python.Runtime.Native; using Python.Runtime.Platform; using System.Linq; namespace Python.Runtime { /// /// Encapsulates the low-level Python C API. Note that it is /// the responsibility of the caller to have acquired the GIL /// before calling any of these methods. /// public class Runtime { public static int UCS => _UCS; internal static readonly int _UCS = PyUnicode_GetMax() PyTuple_GetItem(pointer, new IntPtr(index)); internal static IntPtr PyTuple_GetItem(IntPtr pointer, long index) { return PyTuple_GetItem(pointer, new IntPtr(index)); } [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] private static extern BorrowedReference PyTuple_GetItem(BorrowedReference pointer, IntPtr index); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr PyTuple_GetItem(IntPtr pointer, IntPtr index); internal static int PyTuple_SetItem(IntPtr pointer, long index, IntPtr value) { return PyTuple_SetItem(pointer, new IntPtr(index), value); } [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] private static extern int PyTuple_SetItem(IntPtr pointer, IntPtr index, IntPtr value); internal static IntPtr PyTuple_GetSlice(IntPtr pointer, long start, long end) { return PyTuple_GetSlice(pointer, new IntPtr(start), new IntPtr(end)); } [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr PyTuple_GetSlice(IntPtr pointer, IntPtr start, IntPtr end); internal static long PyTuple_Size(IntPtr pointer) { return (long)_PyTuple_Size(pointer); } [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "PyTuple_Size")] private static extern IntPtr _PyTuple_Size(IntPtr pointer); //==================================================================== // Python iterator API //==================================================================== internal static bool PyIter_Check(IntPtr pointer) { var ob_type = Marshal.ReadIntPtr(pointer, ObjectOffset.ob_type); IntPtr tp_iternext = Marshal.ReadIntPtr(ob_type, TypeOffset.tp_iternext); return tp_iternext != IntPtr.Zero && tp_iternext != _PyObject_NextNotImplemented; } [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyIter_Next(IntPtr pointer); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern NewReference PyIter_Next(BorrowedReference pointer); //==================================================================== // Python module API //==================================================================== [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyModule_New(string name); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern string PyModule_GetName(IntPtr module); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyModule_GetDict(IntPtr module); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern string PyModule_GetFilename(IntPtr module); #if PYTHON_WITH_PYDEBUG [DllImport(_PythonDll, EntryPoint = "PyModule_Create2TraceRefs", CallingConvention = CallingConvention.Cdecl)] #else [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] #endif internal static extern IntPtr PyModule_Create2(IntPtr module, int apiver); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyImport_Import(IntPtr name); /// /// Return value: New reference. /// [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyImport_ImportModule(string name); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyImport_ReloadModule(IntPtr module); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyImport_AddModule(string name); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyImport_GetModuleDict(); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PySys_SetArgvEx( int argc, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(StrArrayMarshaler))] string[] argv, int updatepath ); /// /// Return value: Borrowed reference. /// Return the object name from the sys module or NULL if it does not exist, without setting an exception. /// [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern BorrowedReference PySys_GetObject(string name); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern int PySys_SetObject(string name, IntPtr ob); //==================================================================== // Python type object API //==================================================================== internal static bool PyType_Check(IntPtr ob) { return PyObject_TypeCheck(ob, PyTypeType); } [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyType_Modified(IntPtr type); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern bool PyType_IsSubtype(IntPtr t1, IntPtr t2); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern bool PyType_IsSubtype(BorrowedReference t1, BorrowedReference t2); internal static bool PyObject_TypeCheck(IntPtr ob, IntPtr tp) => PyObject_TypeCheck(new BorrowedReference(ob), new BorrowedReference(tp)); internal static bool PyObject_TypeCheck(BorrowedReference ob, BorrowedReference tp) { BorrowedReference t = PyObject_TYPE(ob); return (t == tp) || PyType_IsSubtype(t, tp); } internal static bool PyType_IsSameAsOrSubtype(IntPtr type, IntPtr ofType) { return (type == ofType) || PyType_IsSubtype(type, ofType); } [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyType_GenericNew(IntPtr type, IntPtr args, IntPtr kw); internal static IntPtr PyType_GenericAlloc(IntPtr type, long n) { return PyType_GenericAlloc(type, new IntPtr(n)); } [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr PyType_GenericAlloc(IntPtr type, IntPtr n); /// /// 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. /// [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern int PyType_Ready(IntPtr type); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr _PyType_Lookup(IntPtr type, IntPtr name); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyObject_GenericGetAttr(IntPtr obj, IntPtr name); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern int PyObject_GenericSetAttr(IntPtr obj, IntPtr name, IntPtr value); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr _PyObject_GetDictPtr(IntPtr obj); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyObject_GC_Del(IntPtr tp); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyObject_GC_Track(IntPtr tp); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyObject_GC_UnTrack(IntPtr tp); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void _PyObject_Dump(IntPtr ob); //==================================================================== // Python memory API //==================================================================== internal static IntPtr PyMem_Malloc(long size) { return PyMem_Malloc(new IntPtr(size)); } [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr PyMem_Malloc(IntPtr size); internal static IntPtr PyMem_Realloc(IntPtr ptr, long size) { return PyMem_Realloc(ptr, new IntPtr(size)); } [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr PyMem_Realloc(IntPtr ptr, IntPtr size); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyMem_Free(IntPtr ptr); //==================================================================== // Python exception API //==================================================================== [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyErr_SetString(IntPtr ob, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))] string message); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyErr_SetObject(BorrowedReference type, BorrowedReference exceptionObject); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyErr_SetFromErrno(IntPtr ob); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyErr_SetNone(IntPtr ob); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern int PyErr_ExceptionMatches(IntPtr exception); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern int PyErr_GivenExceptionMatches(IntPtr ob, IntPtr val); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyErr_NormalizeException(ref IntPtr ob, ref IntPtr val, ref IntPtr tb); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyErr_Occurred(); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyErr_Fetch(out IntPtr ob, out IntPtr val, out IntPtr tb); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyErr_Restore(IntPtr ob, IntPtr val, IntPtr tb); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyErr_Clear(); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyErr_Print(); //==================================================================== // Cell API //==================================================================== [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern NewReference PyCell_Get(BorrowedReference cell); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern int PyCell_Set(BorrowedReference cell, IntPtr value); //==================================================================== // Python GC API //==================================================================== internal const int _PyGC_REFS_SHIFT = 1; internal const long _PyGC_REFS_UNTRACKED = -2; internal const long _PyGC_REFS_REACHABLE = -3; internal const long _PyGC_REFS_TENTATIVELY_UNREACHABLE = -4; [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyGC_Collect(); internal static IntPtr _Py_AS_GC(IntPtr ob) { // XXX: PyGC_Head has a force alignment depend on platform. // See PyGC_Head in objimpl.h for more details. return Is32Bit ? ob - 16 : ob - 24; } internal static IntPtr _Py_FROM_GC(IntPtr gc) { return Is32Bit ? gc + 16 : gc + 24; } internal static IntPtr _PyGCHead_REFS(IntPtr gc) { unsafe { var pGC = (PyGC_Head*)gc; var refs = pGC->gc.gc_refs; if (Is32Bit) { return new IntPtr(refs.ToInt32() >> _PyGC_REFS_SHIFT); } return new IntPtr(refs.ToInt64() >> _PyGC_REFS_SHIFT); } } internal static IntPtr _PyGC_REFS(IntPtr ob) { return _PyGCHead_REFS(_Py_AS_GC(ob)); } internal static bool _PyObject_GC_IS_TRACKED(IntPtr ob) { return (long)_PyGC_REFS(ob) != _PyGC_REFS_UNTRACKED; } internal static void Py_CLEAR(ref IntPtr ob) { XDecref(ob); ob = IntPtr.Zero; } //==================================================================== // Python Capsules API //==================================================================== [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern NewReference PyCapsule_New(IntPtr pointer, string name, IntPtr destructor); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyCapsule_GetPointer(BorrowedReference capsule, string name); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern int PyCapsule_SetPointer(BorrowedReference capsule, IntPtr pointer); //==================================================================== // Miscellaneous //==================================================================== [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyMethod_Self(IntPtr ob); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr PyMethod_Function(IntPtr ob); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern int Py_AddPendingCall(IntPtr func, IntPtr arg); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern int Py_MakePendingCalls(); internal static void SetNoSiteFlag() { var loader = LibraryLoader.Instance; IntPtr dllLocal = IntPtr.Zero; if (_PythonDll != "__Internal") { dllLocal = loader.Load(_PythonDll); if (dllLocal == IntPtr.Zero) { throw new Exception($"Cannot load {_PythonDll}"); } } try { Py_NoSiteFlag = loader.GetFunction(dllLocal, "Py_NoSiteFlag"); Marshal.WriteInt32(Py_NoSiteFlag, 1); } finally { if (dllLocal != IntPtr.Zero) { loader.Free(dllLocal); } } } /// /// Return value: New reference. /// internal static IntPtr GetBuiltins() { return PyImport_Import(PyIdentifier.builtins); } } public enum ShutdownMode { Default, Normal, Soft, Reload, } class PyReferenceCollection { private List _actions = new List(); /// /// Record obj's address to release the obj in the future, /// obj must alive before calling Release. /// public void Add(IntPtr ob, Action onRelease) { _actions.Add(new KeyValuePair(ob, onRelease)); } public void Release() { foreach (var item in _actions) { Runtime.XDecref(item.Key); item.Value?.Invoke(); } _actions.Clear(); } } }

Back | FazBrowse Home | New Git URL