Exemple #1
0
        internal static ThunkInfo GetThunk(Delegate @delegate)
        {
            var info = new ThunkInfo(@delegate);

            allocatedThunks[info.Address] = @delegate;
            return(info);
        }
Exemple #2
0
        private static IntPtr AddCustomMetaMethod(string name, IntPtr type, IntPtr mdef, SlotsHolder slotsHolder)
        {
            MethodInfo mi        = typeof(MetaType).GetMethod(name);
            ThunkInfo  thunkInfo = Interop.GetThunk(mi, "BinaryFunc");

            slotsHolder.KeeapAlive(thunkInfo);

            // XXX: Hard code with mode check.
            if (Runtime.ShutdownMode != ShutdownMode.Reload)
            {
                IntPtr mdefAddr = mdef;
                slotsHolder.AddDealloctor(() =>
                {
                    var tp_dict = new BorrowedReference(Marshal.ReadIntPtr(type, TypeOffset.tp_dict));
                    if (Runtime.PyDict_DelItemString(tp_dict, name) != 0)
                    {
                        Runtime.PyErr_Print();
                        Debug.Fail($"Cannot remove {name} from metatype");
                    }
                    FreeMethodDef(mdefAddr);
                });
            }
            mdef = WriteMethodDef(mdef, name, thunkInfo.Address);
            return(mdef);
        }
Exemple #3
0
        public MethodWrapper(Type type, string name, string funcType = null)
        {
            // Turn the managed method into a function pointer

            _thunk = Interop.GetThunk(type.GetMethod(name), funcType);

            // Allocate and initialize a PyMethodDef structure to represent
            // the managed method, then create a PyCFunction.

            mdef = Runtime.PyMem_Malloc(4 * IntPtr.Size);
            TypeManager.WriteMethodDef(mdef, name, _thunk.Address, 0x0003);
            ptr = Runtime.PyCFunction_NewEx(mdef, IntPtr.Zero, IntPtr.Zero);
        }
Exemple #4
0
        static void InitializeSlot(IntPtr type, ThunkInfo thunk, string name, SlotsHolder slotsHolder = null, bool canOverride = true)
        {
            int offset = ManagedDataOffsets.GetSlotOffset(name);

            if (!canOverride && Marshal.ReadIntPtr(type, offset) != IntPtr.Zero)
            {
                return;
            }
            Marshal.WriteIntPtr(type, offset, thunk.Address);
            if (slotsHolder != null)
            {
                slotsHolder.Set(offset, thunk);
            }
        }
Exemple #5
0
        static void InitializeSlot(IntPtr type, ThunkInfo thunk, string name, SlotsHolder slotsHolder = null, bool canOverride = true)
        {
            Type      typeOffset = typeof(TypeOffset);
            FieldInfo fi         = typeOffset.GetField(name);
            var       offset     = (int)fi.GetValue(typeOffset);

            if (!canOverride && Marshal.ReadIntPtr(type, offset) != IntPtr.Zero)
            {
                return;
            }
            Marshal.WriteIntPtr(type, offset, thunk.Address);
            if (slotsHolder != null)
            {
                slotsHolder.Set(offset, thunk);
            }
        }
Exemple #6
0
        internal static IntPtr RestoreRuntimeData(RuntimeDataStorage storage)
        {
            PyCLRMetaType    = storage.PopValue <IntPtr>();
            _metaSlotsHodler = new SlotsHolder(PyCLRMetaType);
            TypeManager.InitializeSlots(PyCLRMetaType, typeof(MetaType), _metaSlotsHodler);

            IntPtr mdef = Marshal.ReadIntPtr(PyCLRMetaType, TypeOffset.tp_methods);

            foreach (var methodName in CustomMethods)
            {
                var       mi        = typeof(MetaType).GetMethod(methodName);
                ThunkInfo thunkInfo = Interop.GetThunk(mi, "BinaryFunc");
                _metaSlotsHodler.KeeapAlive(thunkInfo);
                mdef = TypeManager.WriteMethodDef(mdef, methodName, thunkInfo.Address);
            }
            return(PyCLRMetaType);
        }
Exemple #7
0
        internal static ThunkInfo GetThunk(MethodInfo method, string funcType = null)
        {
            Type dt;

            if (funcType != null)
            {
                dt = typeof(Interop).GetNestedType(funcType) as Type;
            }
            else
            {
                dt = GetPrototype(method.Name);
            }

            if (dt == null)
            {
                return(ThunkInfo.Empty);
            }
            Delegate d    = Delegate.CreateDelegate(dt, method);
            var      info = new ThunkInfo(d);

            allocatedThunks[info.Address] = d;
            return(info);
        }
Exemple #8
0
        internal static ThunkInfo GetThunk(MethodInfo method, string funcType = null)
        {
            Type dt;

            if (funcType != null)
            {
                dt = typeof(Interop).GetNestedType(funcType) as Type;
            }
            else
            {
                dt = GetPrototype(method.Name);
            }

            if (dt == null)
            {
                return(ThunkInfo.Empty);
            }
            Delegate d    = Delegate.CreateDelegate(dt, method);
            var      info = new ThunkInfo(d);

            // TODO: remove keepAlive when #958 merged, let the lifecycle of ThunkInfo transfer to caller.
            keepAlive.Add(info);
            return(info);
        }
        internal static IntPtr CreateMetaType(Type impl)
        {
            // The managed metatype is functionally little different than the
            // standard Python metatype (PyType_Type). It overrides certain of
            // the standard type slots, and has to subclass PyType_Type for
            // certain functions in the C runtime to work correctly with it.

            IntPtr type    = AllocateTypeObject("CLR Metatype");
            IntPtr py_type = Runtime.PyTypeType;

            Marshal.WriteIntPtr(type, TypeOffset.tp_base, py_type);
            Runtime.XIncref(py_type);

            // Slots will inherit from TypeType, it's not neccesary for setting them.
            // Inheried slots:
            // tp_basicsize, tp_itemsize,
            // tp_dictoffset, tp_weaklistoffset,
            // tp_traverse, tp_clear, tp_is_gc, etc.

            // Override type slots with those of the managed implementation.

            InitializeSlots(type, impl);

            int flags = TypeFlags.Default;

            flags |= TypeFlags.Managed;
            flags |= TypeFlags.HeapType;
            flags |= TypeFlags.HaveGC;
            Util.WriteCLong(type, TypeOffset.tp_flags, flags);

            // We need space for 3 PyMethodDef structs, each of them
            // 4 int-ptrs in size.
            IntPtr    mdef      = Runtime.PyMem_Malloc(3 * 4 * IntPtr.Size);
            IntPtr    mdefStart = mdef;
            ThunkInfo thunkInfo = Interop.GetThunk(typeof(MetaType).GetMethod("__instancecheck__"), "BinaryFunc");

            mdef = WriteMethodDef(
                mdef,
                "__instancecheck__",
                thunkInfo.Address
                );

            thunkInfo = Interop.GetThunk(typeof(MetaType).GetMethod("__subclasscheck__"), "BinaryFunc");
            mdef      = WriteMethodDef(
                mdef,
                "__subclasscheck__",
                thunkInfo.Address
                );

            // FIXME: mdef is not used
            mdef = WriteMethodDefSentinel(mdef);

            Marshal.WriteIntPtr(type, TypeOffset.tp_methods, mdefStart);

            Runtime.PyType_Ready(type);

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

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

            //DebugUtil.DumpType(type);

            return(type);
        }
Exemple #10
0
 public void KeeapAlive(ThunkInfo thunk)
 {
     _keepalive.Add(thunk);
 }
Exemple #11
0
 public void Set(int offset, ThunkInfo thunk)
 {
     _slots[offset] = thunk;
 }