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); }
public MethodWrapper(Type type, string name) { // Turn the managed method into a function pointer IntPtr fp = Interop.GetThunk(type.GetMethod(name)); // XXX - here we create a Python string object, then take the // char * of the internal string to pass to our methoddef // structure. Its a hack, and the name is leaked! #if (PYTHON32 || PYTHON33 || PYTHON34) IntPtr ps = Runtime.PyBytes_FromString(name); IntPtr sp = Runtime.PyBytes_AS_STRING(ps); #else IntPtr ps = Runtime.PyString_FromString(name); IntPtr sp = Runtime.PyString_AS_STRING(ps); #endif // Allocate and initialize a PyMethodDef structure to represent // the managed method, then create a PyCFunction. mdef = Runtime.PyMem_Malloc(4 * IntPtr.Size); Marshal.WriteIntPtr(mdef, sp); Marshal.WriteIntPtr(mdef, (1 * IntPtr.Size), fp); Marshal.WriteIntPtr(mdef, (2 * IntPtr.Size), (IntPtr)0x0003); // METH_VARARGS | METH_KEYWORDS Marshal.WriteIntPtr(mdef, (3 * IntPtr.Size), IntPtr.Zero); ptr = Runtime.PyCFunction_New(mdef, IntPtr.Zero); }
public MethodWrapper(Type type, string name, string funcType = null) { // Turn the managed method into a function pointer IntPtr fp = 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, fp, 0x0003); ptr = Runtime.PyCFunction_NewEx(mdef, IntPtr.Zero, IntPtr.Zero); }
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); // Copy gc and other type slots from the base Python metatype. CopySlot(py_type, type, TypeOffset.tp_basicsize); CopySlot(py_type, type, TypeOffset.tp_itemsize); CopySlot(py_type, type, TypeOffset.tp_dictoffset); CopySlot(py_type, type, TypeOffset.tp_weaklistoffset); CopySlot(py_type, type, TypeOffset.tp_traverse); CopySlot(py_type, type, TypeOffset.tp_clear); CopySlot(py_type, type, TypeOffset.tp_is_gc); // 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; mdef = WriteMethodDef( mdef, "__instancecheck__", Interop.GetThunk(typeof(MetaType).GetMethod("__instancecheck__"), "BinaryFunc") ); mdef = WriteMethodDef( mdef, "__subclasscheck__", Interop.GetThunk(typeof(MetaType).GetMethod("__subclasscheck__"), "BinaryFunc") ); // 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); }