Beispiel #1
0
        internal CLRObject(object ob, IntPtr tp)
        {
            IntPtr py = Runtime.PyType_GenericAlloc(tp, 0);

            long flags = Util.ReadCLong(tp, TypeOffset.tp_flags);

            if ((flags & TypeFlags.Subclass) != 0)
            {
                IntPtr dict = Marshal.ReadIntPtr(py, ObjectOffset.TypeDictOffset(tp));
                if (dict == IntPtr.Zero)
                {
                    dict = Runtime.PyDict_New();
                    Marshal.WriteIntPtr(py, ObjectOffset.TypeDictOffset(tp), dict);
                }
            }

            GCHandle gc = GCHandle.Alloc(this);

            Marshal.WriteIntPtr(py, ObjectOffset.magic(tp), (IntPtr)gc);
            tpHandle = tp;
            pyHandle = py;
            gcHandle = gc;
            inst     = ob;

            // for performance before calling SetArgsAndCause() lets check if we are an exception
            if (inst is Exception)
            {
                // Fix the BaseException args (and __cause__ in case of Python 3)
                // slot if wrapping a CLR exception
                Exceptions.SetArgsAndCause(py);
            }
        }
Beispiel #2
0
        /// <summary>
        /// The following CreateType implementations do the necessary work to
        /// create Python types to represent managed extension types, reflected
        /// types, subclasses of reflected types and the managed metatype. The
        /// dance is slightly different for each kind of type due to different
        /// behavior needed and the desire to have the existing Python runtime
        /// do as much of the allocation and initialization work as possible.
        /// </summary>
        internal static IntPtr CreateType(Type impl)
        {
            IntPtr type    = AllocateTypeObject(impl.Name);
            int    ob_size = ObjectOffset.Size(type);

            // Set tp_basicsize to the size of our managed instance objects.
            Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)ob_size);

            var offset = (IntPtr)ObjectOffset.TypeDictOffset(type);

            Marshal.WriteIntPtr(type, TypeOffset.tp_dictoffset, offset);

            SlotsHolder slotsHolder = CreateSolotsHolder(type);

            InitializeSlots(type, impl, slotsHolder);

            int flags = TypeFlags.Default | TypeFlags.Managed |
                        TypeFlags.HeapType | TypeFlags.HaveGC;

            Util.WriteCLong(type, TypeOffset.tp_flags, flags);

            if (Runtime.PyType_Ready(type) != 0)
            {
                throw new PythonException();
            }

            IntPtr dict = Marshal.ReadIntPtr(type, TypeOffset.tp_dict);
            IntPtr mod  = Runtime.PyString_FromString("CLR");

            Runtime.PyDict_SetItem(dict, PyIdentifier.__module__, mod);
            Runtime.XDecref(mod);

            InitMethods(type, impl);
            return(type);
        }
Beispiel #3
0
        /// <summary>
        /// The following CreateType implementations do the necessary work to
        /// create Python types to represent managed extension types, reflected
        /// types, subclasses of reflected types and the managed metatype. The
        /// dance is slightly different for each kind of type due to different
        /// behavior needed and the desire to have the existing Python runtime
        /// do as much of the allocation and initialization work as possible.
        /// </summary>
        internal static IntPtr CreateType(Type impl)
        {
            IntPtr type    = AllocateTypeObject(impl.Name);
            int    ob_size = ObjectOffset.Size(type);

            // Set tp_basicsize to the size of our managed instance objects.
            Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)ob_size);

            var offset = (IntPtr)ObjectOffset.TypeDictOffset(type);

            Marshal.WriteIntPtr(type, TypeOffset.tp_dictoffset, offset);

            InitializeSlots(type, impl);

            int flags = TypeFlags.Default | TypeFlags.Managed |
                        TypeFlags.HeapType | TypeFlags.HaveGC;

            Util.WriteCLong(type, TypeOffset.tp_flags, flags);

            Runtime.PyType_Ready(type);

            IntPtr dict = Marshal.ReadIntPtr(type, TypeOffset.tp_dict);
            IntPtr mod  = Runtime.PyString_FromString("CLR");

            Runtime.PyDict_SetItemString(dict, "__module__", mod);

            InitMethods(type, impl);

            return(type);
        }
Beispiel #4
0
        internal CLRObject(object ob, IntPtr tp)
        {
            System.Diagnostics.Debug.Assert(tp != IntPtr.Zero);
            IntPtr py = Runtime.PyType_GenericAlloc(tp, 0);

            long flags = Util.ReadCLong(tp, TypeOffset.tp_flags);

            if ((flags & TypeFlags.Subclass) != 0)
            {
                IntPtr dict = Marshal.ReadIntPtr(py, ObjectOffset.TypeDictOffset(tp));
                if (dict == IntPtr.Zero)
                {
                    dict = Runtime.PyDict_New();
                    Marshal.WriteIntPtr(py, ObjectOffset.TypeDictOffset(tp), dict);
                }
            }

            GCHandle gc = AllocGCHandle(TrackTypes.Wrapper);

            Marshal.WriteIntPtr(py, ObjectOffset.magic(tp), (IntPtr)gc);
            tpHandle = tp;
            pyHandle = py;
            inst     = ob;

            // Fix the BaseException args (and __cause__ in case of Python 3)
            // slot if wrapping a CLR exception
            Exceptions.SetArgsAndCause(py);
        }
Beispiel #5
0
        public static void Finalize(IPythonDerivedType obj)
        {
            FieldInfo fi   = obj.GetType().GetField("__pyobj__");
            var       self = (CLRObject)fi.GetValue(obj);

            // If python's been terminated then just free the gchandle.
            lock (Runtime.IsFinalizingLock)
            {
                if (0 == Runtime.Py_IsInitialized() || Runtime.IsFinalizing)
                {
                    if (self.gcHandle.IsAllocated)
                    {
                        self.gcHandle.Free();
                    }
                    return;
                }
            }

            // delete the python object in an async task as we may not be able to acquire
            // the GIL immediately and we don't want to block the GC thread.
            // FIXME: t isn't used
            Task t = Task.Factory.StartNew(() =>
            {
                lock (Runtime.IsFinalizingLock)
                {
                    // If python's been terminated then just free the gchandle.
                    if (0 == Runtime.Py_IsInitialized() || Runtime.IsFinalizing)
                    {
                        if (self.gcHandle.IsAllocated)
                        {
                            self.gcHandle.Free();
                        }
                        return;
                    }

                    IntPtr gs = Runtime.PyGILState_Ensure();
                    try
                    {
                        // the C# object is being destroyed which must mean there are no more
                        // references to the Python object as well so now we can dealloc the
                        // python object.
                        IntPtr dict = Marshal.ReadIntPtr(self.pyHandle, ObjectOffset.TypeDictOffset(self.tpHandle));
                        if (dict != IntPtr.Zero)
                        {
                            Runtime.XDecref(dict);
                        }
                        Runtime.PyObject_GC_Del(self.pyHandle);
                        self.gcHandle.Free();
                    }
                    finally
                    {
                        Runtime.PyGILState_Release(gs);
                    }
                }
            });
        }
Beispiel #6
0
        /// <summary>
        /// Standard dealloc implementation for instances of reflected types.
        /// </summary>
        public static void tp_dealloc(IntPtr ob)
        {
            ManagedType self = GetManagedObject(ob);
            IntPtr      dict = Marshal.ReadIntPtr(ob, ObjectOffset.TypeDictOffset(self.tpHandle));

            if (dict != IntPtr.Zero)
            {
                Runtime.XDecref(dict);
            }
            Runtime.PyObject_GC_UnTrack(self.pyHandle);
            Runtime.PyObject_GC_Del(self.pyHandle);
            Runtime.XDecref(self.tpHandle);
            self.gcHandle.Free();
        }
Beispiel #7
0
        public ModuleObject(string name)
        {
            if (name == string.Empty)
            {
                throw new ArgumentException("Name must not be empty!");
            }
            moduleName = name;
            cache      = new Dictionary <string, ManagedType>();
            _namespace = name;

            // Use the filename from any of the assemblies just so there's something for
            // anything that expects __file__ to be set.
            var filename  = "unknown";
            var docstring = "Namespace containing types from the following assemblies:\n\n";

            foreach (Assembly a in AssemblyManager.GetAssemblies(name))
            {
                if (!a.IsDynamic && a.Location != null)
                {
                    filename = a.Location;
                }
                docstring += "- " + a.FullName + "\n";
            }

            dict = Runtime.PyDict_New();
            IntPtr pyname      = Runtime.PyString_FromString(moduleName);
            IntPtr pyfilename  = Runtime.PyString_FromString(filename);
            IntPtr pydocstring = Runtime.PyString_FromString(docstring);
            IntPtr pycls       = TypeManager.GetTypeHandle(GetType());

            Runtime.PyDict_SetItemString(dict, "__name__", pyname);
            Runtime.PyDict_SetItemString(dict, "__file__", pyfilename);
            Runtime.PyDict_SetItemString(dict, "__doc__", pydocstring);
            Runtime.PyDict_SetItemString(dict, "__class__", pycls);
            Runtime.XDecref(pyname);
            Runtime.XDecref(pyfilename);
            Runtime.XDecref(pydocstring);

            Marshal.WriteIntPtr(pyHandle, ObjectOffset.TypeDictOffset(tpHandle), dict);

            InitializeModuleMembers();
        }
Beispiel #8
0
        /// <summary>
        /// The following CreateType implementations do the necessary work to
        /// create Python types to represent managed extension types, reflected
        /// types, subclasses of reflected types and the managed metatype. The
        /// dance is slightly different for each kind of type due to different
        /// behavior needed and the desire to have the existing Python runtime
        /// do as much of the allocation and initialization work as possible.
        /// </summary>
        internal static IntPtr CreateType(Type impl)
        {
            IntPtr type    = AllocateTypeObject(impl.Name, metatype: Runtime.PyTypeType);
            int    ob_size = ObjectOffset.Size(type);

            // Set tp_basicsize to the size of our managed instance objects.
            Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)ob_size);

            var offset = (IntPtr)ObjectOffset.TypeDictOffset(type);

            Marshal.WriteIntPtr(type, TypeOffset.tp_dictoffset, offset);

            SlotsHolder slotsHolder = CreateSolotsHolder(type);

            InitializeSlots(type, impl, slotsHolder);

            var flags = TypeFlags.Default | TypeFlags.Managed |
                        TypeFlags.HeapType | TypeFlags.HaveGC;

            Util.WriteCLong(type, TypeOffset.tp_flags, (int)flags);

            if (Runtime.PyType_Ready(type) != 0)
            {
                throw new PythonException();
            }

            var dict = new BorrowedReference(Marshal.ReadIntPtr(type, TypeOffset.tp_dict));
            var mod  = NewReference.DangerousFromPointer(Runtime.PyString_FromString("CLR"));

            Runtime.PyDict_SetItem(dict, PyIdentifier.__module__, mod);
            mod.Dispose();

            InitMethods(type, impl);

            // The type has been modified after PyType_Ready has been called
            // Refresh the type
            Runtime.PyType_Modified(type);
            return(type);
        }
Beispiel #9
0
        protected static void SetObjectDict(IntPtr ob, IntPtr value)
        {
            IntPtr type = Runtime.PyObject_TYPE(ob);

            Marshal.WriteIntPtr(ob, ObjectOffset.TypeDictOffset(type), value);
        }
Beispiel #10
0
        protected static IntPtr GetObjectDict(IntPtr ob)
        {
            IntPtr type = Runtime.PyObject_TYPE(ob);

            return(Marshal.ReadIntPtr(ob, ObjectOffset.TypeDictOffset(type)));
        }