Register_PyString_Type(IntPtr address) { // not quite trivial to autogenerate CPyMarshal.Zero(address, Marshal.SizeOf(typeof(PyTypeObject))); CPyMarshal.WriteIntField(address, typeof(PyTypeObject), "ob_refcnt", 1); CPyMarshal.WriteIntField(address, typeof(PyTypeObject), "tp_basicsize", Marshal.SizeOf(typeof(PyStringObject)) - 1); CPyMarshal.WriteIntField(address, typeof(PyTypeObject), "tp_itemsize", 1); CPyMarshal.WriteCStringField(address, typeof(PyTypeObject), "tp_name", "str"); CPyMarshal.WritePtrField(address, typeof(PyTypeObject), "tp_str", this.GetFuncPtr("IC_PyString_Str")); CPyMarshal.WritePtrField(address, typeof(PyTypeObject), "tp_repr", this.GetFuncPtr("PyObject_Repr")); uint sqSize = (uint)Marshal.SizeOf(typeof(PySequenceMethods)); IntPtr sqPtr = this.allocator.Alloc(sqSize); CPyMarshal.Zero(sqPtr, sqSize); CPyMarshal.WritePtrField(sqPtr, typeof(PySequenceMethods), "sq_concat", this.GetFuncPtr("IC_PyString_Concat_Core")); CPyMarshal.WritePtrField(address, typeof(PyTypeObject), "tp_as_sequence", sqPtr); uint bfSize = (uint)Marshal.SizeOf(typeof(PyBufferProcs)); IntPtr bfPtr = this.allocator.Alloc(bfSize); CPyMarshal.Zero(bfPtr, bfSize); CPyMarshal.WritePtrField(bfPtr, typeof(PyBufferProcs), "bf_getreadbuffer", this.GetFuncPtr("IC_str_getreadbuffer")); CPyMarshal.WritePtrField(bfPtr, typeof(PyBufferProcs), "bf_getwritebuffer", this.GetFuncPtr("IC_str_getwritebuffer")); CPyMarshal.WritePtrField(bfPtr, typeof(PyBufferProcs), "bf_getsegcount", this.GetFuncPtr("IC_str_getsegcount")); CPyMarshal.WritePtrField(bfPtr, typeof(PyBufferProcs), "bf_getcharbuffer", this.GetFuncPtr("IC_str_getreadbuffer")); CPyMarshal.WritePtrField(address, typeof(PyTypeObject), "tp_as_buffer", bfPtr); CPyMarshal.WriteIntField(address, typeof(PyTypeObject), "tp_flags", (Int32)Py_TPFLAGS.HAVE_GETCHARBUFFER); this.map.Associate(address, TypeCache.String); }
StoreTyped(BigInteger value) { IntPtr ptr = this.allocator.Alloc((uint)Marshal.SizeOf(typeof(PyObject))); CPyMarshal.WriteIntField(ptr, typeof(PyObject), "ob_refcnt", 1); CPyMarshal.WritePtrField(ptr, typeof(PyObject), "ob_type", this.PyLong_Type); this.map.Associate(ptr, value); return(ptr); }
Register_PyBool_Type(IntPtr address) { // not quite trivial to autogenerate CPyMarshal.Zero(address, Marshal.SizeOf(typeof(PyTypeObject))); CPyMarshal.WriteIntField(address, typeof(PyTypeObject), "ob_refcnt", 1); CPyMarshal.WritePtrField(address, typeof(PyTypeObject), "tp_base", this.PyInt_Type); CPyMarshal.WriteCStringField(address, typeof(PyTypeObject), "tp_name", "bool"); this.map.Associate(address, TypeCache.Boolean); }
StoreObject(object obj) { IntPtr ptr = this.allocator.Alloc((uint)Marshal.SizeOf(typeof(PyObject))); CPyMarshal.WriteIntField(ptr, typeof(PyObject), "ob_refcnt", 1); CPyMarshal.WritePtrField(ptr, typeof(PyObject), "ob_type", this.PyBaseObject_Type); this.map.Associate(ptr, obj); return(ptr); }
Register_PyFile_Type(IntPtr address) { // not worth autogenerating // we're using the cpy file type by default, with methods patched in C // to redirect into C# when ipy files turn up CPyMarshal.WriteIntField(address, typeof(PyTypeObject), "ob_refcnt", 1); CPyMarshal.WriteCStringField(address, typeof(PyTypeObject), "tp_name", "file"); this.map.Associate(address, TypeCache.PythonFile); }
StoreTyped(double value) { IntPtr ptr = this.allocator.Alloc((uint)Marshal.SizeOf(typeof(PyFloatObject))); CPyMarshal.WriteIntField(ptr, typeof(PyFloatObject), "ob_refcnt", 1); CPyMarshal.WritePtrField(ptr, typeof(PyFloatObject), "ob_type", this.PyFloat_Type); CPyMarshal.WriteDoubleField(ptr, typeof(PyFloatObject), "ob_fval", value); this.map.Associate(ptr, value); return(ptr); }
Register_PyEllipsis_Type(IntPtr address) { // not quite trivial to autogenerate // (but surely there's a better way to get the Ellipsis object...) CPyMarshal.Zero(address, Marshal.SizeOf(typeof(PyTypeObject))); CPyMarshal.WriteIntField(address, typeof(PyTypeObject), "ob_refcnt", 1); CPyMarshal.WriteCStringField(address, typeof(PyTypeObject), "tp_name", "ellipsis"); object ellipsisType = PythonCalls.Call(Builtin.type, new object[] { PythonOps.Ellipsis }); this.map.Associate(address, ellipsisType); }
StoreTyped(PythonFunction func) { uint size = (uint)Marshal.SizeOf(typeof(PyFunctionObject)); IntPtr ptr = this.allocator.Alloc(size); CPyMarshal.Zero(ptr, size); CPyMarshal.WriteIntField(ptr, typeof(PyIntObject), "ob_refcnt", 1); CPyMarshal.WritePtrField(ptr, typeof(PyIntObject), "ob_type", this.PyFunction_Type); this.map.Associate(ptr, func); return(ptr); }
StoreTyped(PythonExceptions.BaseException exc) { IntPtr ptr = this.allocator.Alloc((uint)Marshal.SizeOf(typeof(PyObject))); CPyMarshal.WriteIntField(ptr, typeof(PyObject), "ob_refcnt", 1); object type_ = PythonCalls.Call(Builtin.type, new object[] { exc }); CPyMarshal.WritePtrField(ptr, typeof(PyObject), "ob_type", this.Store(type_)); this.map.Associate(ptr, exc); return(ptr); }
IC__PyString_Resize_NoGrow(IntPtr strPtr, int newSize) { CPyMarshal.WriteIntField(strPtr, typeof(PyStringObject), "ob_size", newSize); IntPtr bufPtr = CPyMarshal.Offset( strPtr, Marshal.OffsetOf(typeof(PyStringObject), "ob_sval")); IntPtr terminatorPtr = CPyMarshal.Offset( bufPtr, newSize); CPyMarshal.WriteByte(terminatorPtr, 0); return(0); }
StoreTyped(Slice slice) { IntPtr ptr = this.allocator.Alloc((uint)Marshal.SizeOf(typeof(PySliceObject))); CPyMarshal.WriteIntField(ptr, typeof(PySliceObject), "ob_refcnt", 1); CPyMarshal.WritePtrField(ptr, typeof(PySliceObject), "ob_type", this.PySlice_Type); CPyMarshal.WritePtrField(ptr, typeof(PySliceObject), "start", this.Store(slice.start)); CPyMarshal.WritePtrField(ptr, typeof(PySliceObject), "stop", this.Store(slice.stop)); CPyMarshal.WritePtrField(ptr, typeof(PySliceObject), "step", this.Store(slice.step)); this.map.Associate(ptr, slice); return(ptr); }
AddNumberMethodsWithIndex(IntPtr typePtr) { this.AddNumberMethodsWithoutIndex(typePtr); IntPtr nmPtr = CPyMarshal.ReadPtrField(typePtr, typeof(PyTypeObject), "tp_as_number"); CPyMarshal.WritePtrField(nmPtr, typeof(PyNumberMethods), "nb_index", this.GetFuncPtr("PyNumber_Index")); Py_TPFLAGS flags = (Py_TPFLAGS)CPyMarshal.ReadIntField(typePtr, typeof(PyTypeObject), "tp_flags"); flags |= Py_TPFLAGS.HAVE_INDEX; CPyMarshal.WriteIntField(typePtr, typeof(PyTypeObject), "tp_flags", (Int32)flags); }
StoreTyped(PythonFile obj) { IntPtr ptr = this.allocator.Alloc((uint)Marshal.SizeOf(typeof(PyFileObject))); CPyMarshal.Zero(ptr, Marshal.SizeOf(typeof(PyFileObject))); CPyMarshal.WriteIntField(ptr, typeof(PyObject), "ob_refcnt", 1); CPyMarshal.WritePtrField(ptr, typeof(PyObject), "ob_type", this.PyFile_Type); CPyMarshal.WriteIntField(ptr, typeof(PyFileObject), "f_fp", -2); CPyMarshal.WritePtrField(ptr, typeof(PyFileObject), "f_name", this.Store(obj.name)); CPyMarshal.WritePtrField(ptr, typeof(PyFileObject), "f_mode", this.Store(obj.mode)); this.map.Associate(ptr, obj); return(ptr); }
StoreTyped(Complex value) { IntPtr ptr = this.allocator.Alloc((uint)Marshal.SizeOf(typeof(PyComplexObject))); CPyMarshal.WriteIntField(ptr, typeof(PyComplexObject), "ob_refcnt", 1); CPyMarshal.WritePtrField(ptr, typeof(PyComplexObject), "ob_type", this.PyComplex_Type); IntPtr cpxptr = CPyMarshal.GetField(ptr, typeof(PyComplexObject), "cval"); CPyMarshal.WriteDoubleField(cpxptr, typeof(Py_complex), "real", value.Real); CPyMarshal.WriteDoubleField(cpxptr, typeof(Py_complex), "imag", value.Imaginary); this.map.Associate(ptr, value); return(ptr); }
InheritIntField(IntPtr typePtr, string name) { int fieldVal = CPyMarshal.ReadIntField(typePtr, typeof(PyTypeObject), name); if (fieldVal == 0) { IntPtr basePtr = CPyMarshal.ReadPtrField(typePtr, typeof(PyTypeObject), "tp_base"); if (basePtr != IntPtr.Zero) { CPyMarshal.WriteIntField(typePtr, typeof(PyTypeObject), name, CPyMarshal.ReadIntField(basePtr, typeof(PyTypeObject), name)); } } }
StoreTyped(Method meth) { uint size = (uint)Marshal.SizeOf(typeof(PyMethodObject)); IntPtr methPtr = this.allocator.Alloc(size); CPyMarshal.Zero(methPtr, size); CPyMarshal.WriteIntField(methPtr, typeof(PyMethodObject), "ob_refcnt", 1); CPyMarshal.WritePtrField(methPtr, typeof(PyMethodObject), "ob_type", this.PyMethod_Type); CPyMarshal.WritePtrField(methPtr, typeof(PyMethodObject), "im_func", this.Store(meth.im_func)); CPyMarshal.WritePtrField(methPtr, typeof(PyMethodObject), "im_self", this.Store(meth.im_self)); CPyMarshal.WritePtrField(methPtr, typeof(PyMethodObject), "im_class", this.Store(meth.im_class)); this.map.Associate(methPtr, meth); return(methPtr); }
StoreTyped(OldInstance inst) { uint size = (uint)Marshal.SizeOf(typeof(PyInstanceObject)); IntPtr ptr = this.allocator.Alloc(size); CPyMarshal.Zero(ptr, size); CPyMarshal.WriteIntField(ptr, typeof(PyObject), "ob_refcnt", 1); CPyMarshal.WritePtrField(ptr, typeof(PyObject), "ob_type", this.PyInstance_Type); CPyMarshal.WritePtrField(ptr, typeof(PyInstanceObject), "in_class", this.Store(Builtin.getattr(this.scratchContext, inst, "__class__"))); CPyMarshal.WritePtrField(ptr, typeof(PyInstanceObject), "in_dict", this.Store(Builtin.getattr(this.scratchContext, inst, "__dict__"))); this.map.Associate(ptr, inst); return(ptr); }
DecRef(IntPtr ptr) { this.AttemptToMap(ptr); if (!this.HasPtr(ptr)) { throw new KeyNotFoundException(String.Format( "DecRef: missing key in pointer map: {0}", ptr.ToString("x"))); } int count = CPyMarshal.ReadIntField(ptr, typeof(PyObject), "ob_refcnt"); if (count == 0) { throw new BadRefCountException("Trying to DecRef an object with ref count 0"); } else if (count == 1) { IntPtr typePtr = CPyMarshal.ReadPtrField(ptr, typeof(PyObject), "ob_type"); if (typePtr == IntPtr.Zero) { throw new CannotInterpretException(String.Format( "Cannot destroy object at {0}: null type", ptr.ToString("x"))); } if (CPyMarshal.ReadPtrField(typePtr, typeof(PyTypeObject), "tp_dealloc") == IntPtr.Zero) { throw new CannotInterpretException(String.Format( "Cannot destroy object at {0} with type at {1}: no dealloc function", ptr.ToString("x"), typePtr.ToString("x"))); } dgt_void_ptr deallocDgt = (dgt_void_ptr)CPyMarshal.ReadFunctionPtrField( typePtr, typeof(PyTypeObject), "tp_dealloc", typeof(dgt_void_ptr)); deallocDgt(ptr); } else { CPyMarshal.WriteIntField(ptr, typeof(PyObject), "ob_refcnt", count - 1); if (this.map.HasPtr(ptr)) { this.map.UpdateStrength(ptr); } } }
IncRef(IntPtr ptr) { this.AttemptToMap(ptr); if (!this.HasPtr(ptr)) { throw new KeyNotFoundException(String.Format( "IncRef: missing key in pointer map: {0}", ptr.ToString("x"))); } int count = CPyMarshal.ReadIntField(ptr, typeof(PyObject), "ob_refcnt"); CPyMarshal.WriteIntField(ptr, typeof(PyObject), "ob_refcnt", count + 1); if (this.map.HasPtr(ptr)) { this.map.UpdateStrength(ptr); } }
StoreTyped(OldClass cls) { uint size = (uint)Marshal.SizeOf(typeof(PyClassObject)); IntPtr ptr = this.allocator.Alloc(size); CPyMarshal.Zero(ptr, size); CPyMarshal.WriteIntField(ptr, typeof(PyObject), "ob_refcnt", 2); // leak classes deliberately CPyMarshal.WritePtrField(ptr, typeof(PyObject), "ob_type", this.PyClass_Type); CPyMarshal.WritePtrField(ptr, typeof(PyClassObject), "cl_bases", this.Store(Builtin.getattr(this.scratchContext, cls, "__bases__"))); CPyMarshal.WritePtrField(ptr, typeof(PyClassObject), "cl_dict", this.Store(Builtin.getattr(this.scratchContext, cls, "__dict__"))); CPyMarshal.WritePtrField(ptr, typeof(PyClassObject), "cl_name", this.Store(Builtin.getattr(this.scratchContext, cls, "__name__"))); this.map.Associate(ptr, cls); return(ptr); }
_PyTuple_Resize(IntPtr tuplePtrPtr, int length) { // note: make sure you don't actualise this try { IntPtr tuplePtr = CPyMarshal.ReadPtr(tuplePtrPtr); this.incompleteObjects.Remove(tuplePtr); uint newSize = (uint)Marshal.SizeOf(typeof(PyTupleObject)) + (uint)(CPyMarshal.PtrSize * (length - 1)); tuplePtr = this.allocator.Realloc(tuplePtr, newSize); CPyMarshal.WriteIntField(tuplePtr, typeof(PyTupleObject), "ob_size", length); this.incompleteObjects[tuplePtr] = UnmanagedDataMarker.PyTupleObject; CPyMarshal.WritePtr(tuplePtrPtr, tuplePtr); return(0); } catch (Exception e) { this.LastException = e; CPyMarshal.WritePtr(tuplePtrPtr, IntPtr.Zero); return(-1); } }
PyType_GenericAlloc(IntPtr typePtr, int nItems) { int size = CPyMarshal.ReadIntField(typePtr, typeof(PyTypeObject), "tp_basicsize"); if (nItems > 0) { int itemsize = CPyMarshal.ReadIntField(typePtr, typeof(PyTypeObject), "tp_itemsize"); size += (nItems * itemsize); } IntPtr newInstance = this.allocator.Alloc((uint)size); CPyMarshal.Zero(newInstance, size); CPyMarshal.WriteUIntField(newInstance, typeof(PyObject), "ob_refcnt", 1); CPyMarshal.WritePtrField(newInstance, typeof(PyObject), "ob_type", typePtr); if (nItems > 0) { CPyMarshal.WriteIntField(newInstance, typeof(PyVarObject), "ob_size", nItems); } return(newInstance); }
StoreTyped(PythonType _type) { uint typeSize = (uint)Marshal.SizeOf(typeof(PyTypeObject)); IntPtr typePtr = this.allocator.Alloc(typeSize); CPyMarshal.Zero(typePtr, typeSize); CPyMarshal.WriteIntField(typePtr, typeof(PyTypeObject), "ob_refcnt", 2); object ob_type = PythonCalls.Call(this.scratchContext, Builtin.type, new object[] { _type }); CPyMarshal.WritePtrField(typePtr, typeof(PyTypeObject), "ob_type", this.Store(ob_type)); string tp_name = (string)_type.__getattribute__(this.scratchContext, "__name__"); CPyMarshal.WritePtrField(typePtr, typeof(PyTypeObject), "tp_name", this.Store(tp_name)); PythonTuple tp_bases = (PythonTuple)_type.__getattribute__(this.scratchContext, "__bases__"); object tp_base = tp_bases[0]; CPyMarshal.WritePtrField(typePtr, typeof(PyTypeObject), "tp_base", this.Store(tp_base)); if (tp_bases.__len__() > 1) { CPyMarshal.WritePtrField(typePtr, typeof(PyTypeObject), "tp_bases", this.Store(tp_bases)); } this.scratchModule.Get__dict__()["_ironclad_bases"] = tp_bases; this.scratchModule.Get__dict__()["_ironclad_metaclass"] = ob_type; this.ExecInModule(CodeSnippets.CLASS_STUB_CODE, this.scratchModule); this.classStubs[typePtr] = this.scratchModule.Get__dict__()["_ironclad_class_stub"]; this.actualisableTypes[typePtr] = new ActualiseDelegate(this.ActualiseArbitraryObject); this.map.Associate(typePtr, _type); this.PyType_Ready(typePtr); return(typePtr); }
InheritSubclassFlags(IntPtr typePtr) { Py_TPFLAGS flags = (Py_TPFLAGS)CPyMarshal.ReadIntField(typePtr, typeof(PyTypeObject), "tp_flags"); if (this.PyType_IsSubtype(typePtr, this.PyInt_Type) != 0) { flags |= Py_TPFLAGS.INT_SUBCLASS; } if (this.PyType_IsSubtype(typePtr, this.PyLong_Type) != 0) { flags |= Py_TPFLAGS.LONG_SUBCLASS; } if (this.PyType_IsSubtype(typePtr, this.PyList_Type) != 0) { flags |= Py_TPFLAGS.LIST_SUBCLASS; } if (this.PyType_IsSubtype(typePtr, this.PyTuple_Type) != 0) { flags |= Py_TPFLAGS.TUPLE_SUBCLASS; } if (this.PyType_IsSubtype(typePtr, this.PyString_Type) != 0) { flags |= Py_TPFLAGS.STRING_SUBCLASS; } if (this.PyType_IsSubtype(typePtr, this.PyDict_Type) != 0) { flags |= Py_TPFLAGS.DICT_SUBCLASS; } if (this.PyType_IsSubtype(typePtr, this.PyType_Type) != 0) { flags |= Py_TPFLAGS.TYPE_SUBCLASS; } // TODO: PyExc_BaseException is tedious CPyMarshal.WriteIntField(typePtr, typeof(PyTypeObject), "tp_flags", (Int32)flags); }
PyObject_Init(IntPtr objPtr, IntPtr typePtr) { CPyMarshal.WriteIntField(objPtr, typeof(PyObject), "ob_refcnt", 1); CPyMarshal.WritePtrField(objPtr, typeof(PyObject), "ob_type", typePtr); return(objPtr); }
PyType_Ready(IntPtr typePtr) { if (typePtr == IntPtr.Zero) { return(-1); } Py_TPFLAGS flags = (Py_TPFLAGS)CPyMarshal.ReadIntField(typePtr, typeof(PyTypeObject), "tp_flags"); if ((Int32)(flags & (Py_TPFLAGS.READY | Py_TPFLAGS.READYING)) != 0) { return(0); } flags |= Py_TPFLAGS.READYING; CPyMarshal.WriteIntField(typePtr, typeof(PyTypeObject), "tp_flags", (Int32)flags); IntPtr typeTypePtr = CPyMarshal.ReadPtrField(typePtr, typeof(PyTypeObject), "ob_type"); if ((typeTypePtr == IntPtr.Zero) && (typePtr != this.PyType_Type)) { CPyMarshal.WritePtrField(typePtr, typeof(PyTypeObject), "ob_type", this.PyType_Type); } IntPtr typeBasePtr = CPyMarshal.ReadPtrField(typePtr, typeof(PyTypeObject), "tp_base"); if ((typeBasePtr == IntPtr.Zero) && (typePtr != this.PyBaseObject_Type)) { typeBasePtr = this.PyBaseObject_Type; CPyMarshal.WritePtrField(typePtr, typeof(PyTypeObject), "tp_base", typeBasePtr); } PyType_Ready(typeBasePtr); this.InheritSubclassFlags(typePtr); this.InheritPtrField(typePtr, "tp_alloc"); this.InheritPtrField(typePtr, "tp_new"); this.InheritPtrField(typePtr, "tp_dealloc"); this.InheritPtrField(typePtr, "tp_free"); this.InheritPtrField(typePtr, "tp_doc"); this.InheritPtrField(typePtr, "tp_call"); this.InheritPtrField(typePtr, "tp_as_number"); this.InheritPtrField(typePtr, "tp_as_sequence"); this.InheritPtrField(typePtr, "tp_as_mapping"); this.InheritPtrField(typePtr, "tp_as_buffer"); this.InheritIntField(typePtr, "tp_basicsize"); this.InheritIntField(typePtr, "tp_itemsize"); if (!this.HasPtr(typePtr)) { this.Retrieve(typePtr); } else { object klass = this.Retrieve(typePtr); if (Builtin.hasattr(this.scratchContext, klass, "__dict__")) { object typeDict = Builtin.getattr(this.scratchContext, klass, "__dict__"); CPyMarshal.WritePtrField(typePtr, typeof(PyTypeObject), "tp_dict", this.Store(typeDict)); } } flags = (Py_TPFLAGS)CPyMarshal.ReadIntField(typePtr, typeof(PyTypeObject), "tp_flags"); flags |= Py_TPFLAGS.READY | Py_TPFLAGS.HAVE_CLASS; flags &= ~Py_TPFLAGS.READYING; CPyMarshal.WriteIntField(typePtr, typeof(PyTypeObject), "tp_flags", (Int32)flags); return(0); }