internal static bool ToManagedValue(BorrowedReference value, Type obType, out object result, bool setError) { var usedImplicit = false; return(ToManagedValue(value.DangerousGetAddress(), obType, out result, setError, out usedImplicit)); }
public ExtensionType() { // Create a new PyObject whose type is a generated type that is // implemented by the particular concrete ExtensionType subclass. // The Python instance object is related to an instance of a // particular concrete subclass with a hidden CLR gchandle. BorrowedReference tp = TypeManager.GetTypeReference(GetType()); //int rc = (int)Marshal.ReadIntPtr(tp, TypeOffset.ob_refcnt); //if (rc > 1050) //{ // DebugUtil.Print("tp is: ", tp); // DebugUtil.DumpType(tp); //} NewReference py = Runtime.PyType_GenericAlloc(tp, 0); // Borrowed reference. Valid as long as pyHandle is valid. tpHandle = tp.DangerousGetAddress(); pyHandle = py.DangerousMoveToPointer(); #if DEBUG GetGCHandle(ObjectReference, TypeReference, out var existing); System.Diagnostics.Debug.Assert(existing == IntPtr.Zero); #endif SetupGc(); }
internal unsafe static T *ReadPtr <T>(BorrowedReference ob, int offset) where T : unmanaged { Debug.Assert(offset >= 0); IntPtr ptr = Marshal.ReadIntPtr(ob.DangerousGetAddress(), offset); return((T *)ptr); }
/// <summary>Creates a <see cref="NewReference"/> pointing to the same object</summary> public NewReference(BorrowedReference reference, bool canBeNull = false) { var address = canBeNull ? reference.DangerousGetAddressOrNull() : reference.DangerousGetAddress(); Runtime.XIncref(address); this.pointer = address; }
internal static void SetGCHandle(BorrowedReference reflectedClrObject, BorrowedReference type, GCHandle newHandle) { Debug.Assert(Runtime.PyObject_TypeCheck(reflectedClrObject, type)); int offset = Marshal.ReadInt32(type.DangerousGetAddress(), Offsets.tp_clr_inst_offset); Debug.Assert(offset > 0); Marshal.WriteIntPtr(reflectedClrObject.DangerousGetAddress(), offset, (IntPtr)newHandle); }
internal static void GetGCHandle(BorrowedReference reflectedClrObject, BorrowedReference type, out IntPtr handle) { Debug.Assert(reflectedClrObject != null); Debug.Assert(IsManagedType(type) || type == Runtime.CLRMetaType); Debug.Assert(Runtime.PyObject_TypeCheck(reflectedClrObject, type)); int gcHandleOffset = Marshal.ReadInt32(type.DangerousGetAddress(), Offsets.tp_clr_inst_offset); Debug.Assert(gcHandleOffset > 0); handle = Marshal.ReadIntPtr(reflectedClrObject.DangerousGetAddress(), gcHandleOffset); }
public NewReference(BorrowedReference reference, bool canBeNull = false) { var address = canBeNull ? reference.DangerousGetAddressOrNull() : reference.DangerousGetAddress(); #pragma warning disable CS0618 // Type or member is obsolete Runtime.XIncref(reference); #pragma warning restore CS0618 // Type or member is obsolete this.pointer = address; }
/// <summary> /// Creates new <see cref="PyObject"/> pointing to the same object as /// the <paramref name="reference"/>. Increments refcount, allowing <see cref="PyObject"/> /// to have ownership over its own reference. /// </summary> internal PyObject(BorrowedReference reference) { if (reference.IsNull) { throw new ArgumentNullException(nameof(reference)); } obj = Runtime.SelfIncRef(reference.DangerousGetAddress()); #if TRACE_ALLOC Traceback = new StackTrace(1); #endif }
internal static void DumpInst(BorrowedReference ob) { BorrowedReference tp = Runtime.PyObject_TYPE(ob); nint sz = Util.ReadIntPtr(tp, TypeOffset.tp_basicsize); for (nint i = 0; i < sz; i += IntPtr.Size) { var pp = new IntPtr(ob.DangerousGetAddress().ToInt64() + i); IntPtr v = Marshal.ReadIntPtr(pp); Console.WriteLine("offset {0}: {1}", i, v); } Console.WriteLine(""); Console.WriteLine(""); }
/// <summary> /// Creates a new managed type derived from a base type with any virtual /// methods overridden to call out to python if the associated python /// object has overridden the method. /// </summary> internal static Type CreateDerivedType(string name, Type baseType, BorrowedReference dictRef, string namespaceStr, string assemblyName, string moduleName = "Python.Runtime.Dynamic.dll") { // TODO: clean up IntPtr py_dict = dictRef.DangerousGetAddress(); if (null != namespaceStr) { name = namespaceStr + "." + name; } if (null == assemblyName) { assemblyName = "Python.Runtime.Dynamic"; } ModuleBuilder moduleBuilder = GetModuleBuilder(assemblyName, moduleName); Type baseClass = baseType; var interfaces = new List <Type> { typeof(IPythonDerivedType) }; // if the base type is an interface then use System.Object as the base class // and add the base type to the list of interfaces this new class will implement. if (baseType.IsInterface) { interfaces.Add(baseType); baseClass = typeof(object); } TypeBuilder typeBuilder = moduleBuilder.DefineType(name, TypeAttributes.Public | TypeAttributes.Class, baseClass, interfaces.ToArray()); // add a field for storing the python object pointer // FIXME: fb not used FieldBuilder fb = typeBuilder.DefineField("__pyobj__", typeof(CLRObject), FieldAttributes.Public); // override any constructors ConstructorInfo[] constructors = baseClass.GetConstructors(); foreach (ConstructorInfo ctor in constructors) { AddConstructor(ctor, baseType, typeBuilder); } // Override any properties explicitly overridden in python var pyProperties = new HashSet <string>(); if (py_dict != IntPtr.Zero && Runtime.PyDict_Check(py_dict)) { Runtime.XIncref(py_dict); using (var dict = new PyDict(py_dict)) using (PyObject keys = dict.Keys()) { foreach (PyObject pyKey in keys) { using (PyObject value = dict[pyKey]) { if (value.HasAttr("_clr_property_type_")) { string propertyName = pyKey.ToString(); pyProperties.Add(propertyName); // Add the property to the type AddPythonProperty(propertyName, value, typeBuilder); } } } } } // override any virtual methods not already overridden by the properties above MethodInfo[] methods = baseType.GetMethods(); var virtualMethods = new HashSet <string>(); foreach (MethodInfo method in methods) { if (!method.Attributes.HasFlag(MethodAttributes.Virtual) | method.Attributes.HasFlag(MethodAttributes.Final)) { continue; } // skip if this property has already been overridden if ((method.Name.StartsWith("get_") || method.Name.StartsWith("set_")) && pyProperties.Contains(method.Name.Substring(4))) { continue; } // keep track of the virtual methods redirected to the python instance virtualMethods.Add(method.Name); // override the virtual method to call out to the python method, if there is one. AddVirtualMethod(method, baseType, typeBuilder); } // Add any additional methods and properties explicitly exposed from Python. if (py_dict != IntPtr.Zero && Runtime.PyDict_Check(py_dict)) { Runtime.XIncref(py_dict); using (var dict = new PyDict(py_dict)) using (PyObject keys = dict.Keys()) { foreach (PyObject pyKey in keys) { using (PyObject value = dict[pyKey]) { if (value.HasAttr("_clr_return_type_") && value.HasAttr("_clr_arg_types_")) { string methodName = pyKey.ToString(); // if this method has already been redirected to the python method skip it if (virtualMethods.Contains(methodName)) { continue; } // Add the method to the type AddPythonMethod(methodName, value, typeBuilder); } } } } } // add the destructor so the python object created in the constructor gets destroyed MethodBuilder methodBuilder = typeBuilder.DefineMethod("Finalize", MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.Standard, typeof(void), Type.EmptyTypes); ILGenerator il = methodBuilder.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(PythonDerivedType).GetMethod("Finalize")); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, baseClass.GetMethod("Finalize", BindingFlags.NonPublic | BindingFlags.Instance)); il.Emit(OpCodes.Ret); Type type = typeBuilder.CreateType(); // scan the assembly so the newly added class can be imported Assembly assembly = Assembly.GetAssembly(type); AssemblyManager.ScanAssembly(assembly); // FIXME: assemblyBuilder not used AssemblyBuilder assemblyBuilder = assemblyBuilders[assemblyName]; return(type); }
internal unsafe static IntPtr ReadIntPtr(BorrowedReference ob, int offset) { Debug.Assert(offset >= 0); return(Marshal.ReadIntPtr(ob.DangerousGetAddress(), offset)); }
internal static ManagedType GetManagedObject(BorrowedReference ob) => GetManagedObject(ob.DangerousGetAddress());
internal CLRObject(object ob, BorrowedReference tp) : this(ob, tp.DangerousGetAddress()) { }
public static bool IsNone(this BorrowedReference reference) => reference.DangerousGetAddress() == Runtime.PyNone;
private static bool ToPrimitive(BorrowedReference value, Type obType, out object?result, bool setError) => ToPrimitive(value.DangerousGetAddress(), obType, out result, setError);
internal unsafe static void WriteIntPtr(BorrowedReference ob, int offset, IntPtr value) { Debug.Assert(offset >= 0); Marshal.WriteIntPtr(ob.DangerousGetAddress(), offset, value); }
internal static bool IsManagedType(BorrowedReference type) { var flags = (TypeFlags)Util.ReadCLong(type.DangerousGetAddress(), TypeOffset.tp_flags); return (flags & TypeFlags.HasClrInstance) != 0; }
internal static void WriteInt64(BorrowedReference ob, int offset, long value) { Debug.Assert(offset >= 0); Marshal.WriteInt64(ob.DangerousGetAddress(), offset, value); }
internal static NewReference GetInstHandle(object ob, BorrowedReference pyType) { CLRObject co = GetInstance(ob, pyType.DangerousGetAddress()); return(NewReference.DangerousFromPointer(co.pyHandle)); }
internal static bool ToManagedValue(BorrowedReference value, Type obType, out object result, bool setError) => ToManagedValue(value.DangerousGetAddress(), obType, out result, setError);
internal static long ReadInt64(BorrowedReference ob, int offset) { Debug.Assert(offset >= 0); return(Marshal.ReadInt64(ob.DangerousGetAddress(), offset)); }
internal static bool TryDecode(BorrowedReference value, BorrowedReference type, Type targetType, out object result) => TryDecode(value.DangerousGetAddress(), type.DangerousGetAddress(), targetType, out result);
/// <summary> /// The actual import hook that ties Python to the managed world. /// </summary> public static IntPtr __import__(IntPtr self, IntPtr argsRaw, IntPtr kw) { var args = new BorrowedReference(argsRaw); // Replacement for the builtin __import__. The original import // hook is saved as this.py_import. This version handles CLR // import and defers to the normal builtin for everything else. var num_args = Runtime.PyTuple_Size(args); if (num_args < 1) { return(Exceptions.RaiseTypeError("__import__() takes at least 1 argument (0 given)")); } BorrowedReference py_mod_name = Runtime.PyTuple_GetItem(args, 0); if (py_mod_name.IsNull || !Runtime.IsStringType(py_mod_name)) { return(Exceptions.RaiseTypeError("string expected")); } // Check whether the import is of the form 'from x import y'. // This determines whether we return the head or tail module. BorrowedReference fromList = default; var fromlist = false; if (num_args >= 4) { fromList = Runtime.PyTuple_GetItem(args, 3); if (fromList != null && Runtime.PyObject_IsTrue(fromList) == 1) { fromlist = true; } } string mod_name = Runtime.GetManagedString(py_mod_name); // Check these BEFORE the built-in import runs; may as well // do the Incref()ed return here, since we've already found // the module. if (mod_name == "clr") { NewReference clr_module = GetCLRModule(fromList); if (!clr_module.IsNull()) { BorrowedReference sys_modules = Runtime.PyImport_GetModuleDict(); if (!sys_modules.IsNull) { Runtime.PyDict_SetItemString(sys_modules, "clr", clr_module); } } return(clr_module.DangerousMoveToPointerOrNull()); } string realname = mod_name; // 2010-08-15: Always seemed smart to let python try first... // This shaves off a few tenths of a second on test_module.py // and works around a quirk where 'sys' is found by the // LoadImplicit() deprecation logic. // Turns out that the AssemblyManager.ResolveHandler() checks to see if any // Assembly's FullName.ToLower().StartsWith(name.ToLower()), which makes very // little sense to me. IntPtr res = Runtime.PyObject_Call(py_import, args.DangerousGetAddress(), kw); if (res != IntPtr.Zero) { // There was no error. if (fromlist && IsLoadAll(fromList)) { var mod = ManagedType.GetManagedObject(res) as ModuleObject; mod?.LoadNames(); } return(res); } // There was an error if (!Exceptions.ExceptionMatches(Exceptions.ImportError)) { // and it was NOT an ImportError; bail out here. return(IntPtr.Zero); } if (mod_name == string.Empty) { // Most likely a missing relative import. // For example site-packages\bs4\builder\__init__.py uses it to check if a package exists: // from . import _html5lib // We don't support them anyway return(IntPtr.Zero); } // Save the exception var originalException = new PythonException(); // Otherwise, just clear the it. Exceptions.Clear(); string[] names = realname.Split('.'); // See if sys.modules for this interpreter already has the // requested module. If so, just return the existing module. BorrowedReference modules = Runtime.PyImport_GetModuleDict(); BorrowedReference module = Runtime.PyDict_GetItem(modules, py_mod_name); if (module != null) { if (fromlist) { if (IsLoadAll(fromList)) { var mod = ManagedType.GetManagedObject(module) as ModuleObject; mod?.LoadNames(); } return(new NewReference(module).DangerousMoveToPointer()); } module = Runtime.PyDict_GetItemString(modules, names[0]); return(new NewReference(module, canBeNull: true).DangerousMoveToPointer()); } Exceptions.Clear(); // Traverse the qualified module name to get the named module // and place references in sys.modules as we go. Note that if // we are running in interactive mode we pre-load the names in // each module, which is often useful for introspection. If we // are not interactive, we stick to just-in-time creation of // objects at lookup time, which is much more efficient. // NEW: The clr got a new module variable preload. You can // enable preloading in a non-interactive python processing by // setting clr.preload = True ModuleObject head = mod_name == realname ? null : root; ModuleObject tail = root; root.InitializePreload(); foreach (string name in names) { ManagedType mt = tail.GetAttribute(name, true); if (!(mt is ModuleObject)) { originalException.Restore(); return(IntPtr.Zero); } if (head == null) { head = (ModuleObject)mt; } tail = (ModuleObject)mt; if (CLRModule.preload) { tail.LoadNames(); } // Add the module to sys.modules Runtime.PyDict_SetItemString(modules, tail.moduleName, tail.ObjectReference); } { var mod = fromlist ? tail : head; if (fromlist && IsLoadAll(fromList)) { mod.LoadNames(); } Runtime.XIncref(mod.pyHandle); return(mod.pyHandle); } }
/// <summary>Create a scope based on a Python Module.</summary> internal PyScope(BorrowedReference reference, PyScopeManager manager) : this(reference.DangerousGetAddress(), manager) { Runtime.XIncref(reference.DangerousGetAddress()); }