ActualiseTuple(IntPtr ptr) { int itemCount = CPyMarshal.ReadIntField(ptr, typeof(PyTupleObject), "ob_size"); IntPtr itemAddressPtr = CPyMarshal.Offset(ptr, Marshal.OffsetOf(typeof(PyTupleObject), "ob_item")); object[] items = new object[itemCount]; for (int i = 0; i < itemCount; i++) { IntPtr itemPtr = CPyMarshal.ReadPtr(itemAddressPtr); items[i] = this.Retrieve(itemPtr); itemAddressPtr = CPyMarshal.Offset(itemAddressPtr, CPyMarshal.PtrSize); } this.incompleteObjects.Remove(ptr); this.map.Associate(ptr, new PythonTuple(items)); }
ReadPyString(IntPtr ptr) { IntPtr typePtr = CPyMarshal.ReadPtrField(ptr, typeof(PyObject), "ob_type"); if (PyType_IsSubtype(typePtr, this.PyString_Type) == 0) { throw new ArgumentTypeException("ReadPyString: Expected a str, or subclass thereof"); } IntPtr buffer = CPyMarshal.Offset(ptr, Marshal.OffsetOf(typeof(PyStringObject), "ob_sval")); int length = CPyMarshal.ReadIntField(ptr, typeof(PyStringObject), "ob_size"); byte[] bytes = new byte[length]; Marshal.Copy(buffer, bytes, 0, length); char[] chars = Array.ConvertAll <byte, char>( bytes, new Converter <byte, char>(CharFromByte)); return(new string(chars)); }
RefCount(IntPtr ptr) { this.AttemptToMap(ptr); if (!this.HasPtr(ptr)) { throw new KeyNotFoundException(String.Format( "RefCount: missing key in pointer map: {0}", ptr.ToString("x"))); } if (this.map.HasPtr(ptr)) { this.map.UpdateStrength(ptr); } return(CPyMarshal.ReadIntField(ptr, typeof(PyObject), "ob_refcnt")); }
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); } }
ActualiseList(IntPtr ptr) { if (this.listsBeingActualised.ContainsKey(ptr)) { throw new Exception("Fatal error: PythonMapper.listsBeingActualised is somehow corrupt"); } List newList = new List(); this.listsBeingActualised[ptr] = newList; int length = CPyMarshal.ReadIntField(ptr, typeof(PyListObject), "ob_size"); if (length != 0) { IntPtr itemPtrPtr = CPyMarshal.ReadPtrField(ptr, typeof(PyListObject), "ob_item"); for (int i = 0; i < length; i++) { IntPtr itemPtr = CPyMarshal.ReadPtr(itemPtrPtr); if (itemPtr == IntPtr.Zero) { // We have *no* idea what to do here. throw new ArgumentException("Attempted to Retrieve uninitialised PyListObject -- expect strange bugs"); } if (this.listsBeingActualised.ContainsKey(itemPtr)) { newList.append(this.listsBeingActualised[itemPtr]); } else { newList.append(this.Retrieve(itemPtr)); } itemPtrPtr = CPyMarshal.Offset(itemPtrPtr, CPyMarshal.PtrSize); } } this.listsBeingActualised.Remove(ptr); this.incompleteObjects.Remove(ptr); this.map.Associate(ptr, newList); }
IC_PyTuple_Dealloc(IntPtr tuplePtr) { int length = CPyMarshal.ReadIntField(tuplePtr, typeof(PyTupleObject), "ob_size"); IntPtr itemsPtr = CPyMarshal.Offset( tuplePtr, Marshal.OffsetOf(typeof(PyTupleObject), "ob_item")); for (int i = 0; i < length; i++) { IntPtr itemPtr = CPyMarshal.ReadPtr( CPyMarshal.Offset( itemsPtr, i * CPyMarshal.PtrSize)); if (itemPtr != IntPtr.Zero) { this.DecRef(itemPtr); } } dgt_void_ptr freeDgt = (dgt_void_ptr) CPyMarshal.ReadFunctionPtrField( this.PyTuple_Type, typeof(PyTypeObject), "tp_free", typeof(dgt_void_ptr)); freeDgt(tuplePtr); }
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); }
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); }
PySequence_SetItem(IntPtr objPtr, int idx, IntPtr valuePtr) { try { IntPtr typePtr = CPyMarshal.ReadPtrField(objPtr, typeof(PyObject), "ob_type"); if (typePtr == this.PyList_Type) { int newIdx = idx; int length = CPyMarshal.ReadIntField(objPtr, typeof(PyListObject), "ob_size"); if (newIdx < 0) { newIdx += length; } if (newIdx >= 0 && newIdx < length) { this.IncRef(valuePtr); return(this.PyList_SetItem(objPtr, newIdx, valuePtr)); } // otherwise, fall through and allow normal exception to occur } object sequence = this.Retrieve(objPtr); object setitem; if (PythonOps.TryGetBoundAttr(sequence, "__setitem__", out setitem)) { PythonCalls.Call(setitem, idx, this.Retrieve(valuePtr)); return(0); } throw PythonOps.TypeError("PySequence_SetItem: failed to convert {0} to sequence", sequence); } catch (Exception e) { this.LastException = e; return(-1); } }
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); }
PyTuple_Size(IntPtr tuplePtr) { return(CPyMarshal.ReadIntField(tuplePtr, typeof(PyTupleObject), "ob_size")); }
PyString_Size(IntPtr strPtr) { return(CPyMarshal.ReadIntField(strPtr, typeof(PyStringObject), "ob_size")); }