internal static SlotsHolder SetupMetaSlots(Type impl, IntPtr type) { // Override type slots with those of the managed implementation. SlotsHolder slotsHolder = new SlotsHolder(type); InitializeSlots(type, impl, slotsHolder); // We need space for 3 PyMethodDef structs. int mdefSize = (MetaType.CustomMethods.Length + 1) * Marshal.SizeOf(typeof(PyMethodDef)); IntPtr mdef = Runtime.PyMem_Malloc(mdefSize); IntPtr mdefStart = mdef; foreach (var methodName in MetaType.CustomMethods) { mdef = AddCustomMetaMethod(methodName, type, mdef, slotsHolder); } mdef = WriteMethodDefSentinel(mdef); Debug.Assert((long)(mdefStart + mdefSize) <= (long)mdef); Marshal.WriteIntPtr(type, TypeOffset.tp_methods, mdefStart); // XXX: Hard code with mode check. if (Runtime.ShutdownMode != ShutdownMode.Reload) { slotsHolder.Set(TypeOffset.tp_methods, (t, offset) => { var p = Marshal.ReadIntPtr(t, offset); Runtime.PyMem_Free(p); Marshal.WriteIntPtr(t, offset, IntPtr.Zero); }); } return(slotsHolder); }
static void InitializeSlot(IntPtr type, int slotOffset, MethodInfo method, SlotsHolder slotsHolder = null) { var thunk = Interop.GetThunk(method); Marshal.WriteIntPtr(type, slotOffset, thunk.Address); if (slotsHolder != null) { slotsHolder.Set(slotOffset, thunk); } }
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); } }