internal static ThunkInfo GetThunk(Delegate @delegate) { var info = new ThunkInfo(@delegate); allocatedThunks[info.Address] = @delegate; return(info); }
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); }
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); }
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); } }
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); } }
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); }
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); }
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); }
public void KeeapAlive(ThunkInfo thunk) { _keepalive.Add(thunk); }
public void Set(int offset, ThunkInfo thunk) { _slots[offset] = thunk; }