def testTrueFalse(self, mapper, _): truePtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyIntObject)) mapper.RegisterData("_Py_TrueStruct", truePtr) self.assertTrue(mapper.Retrieve(truePtr) is True) self.assertEquals( CPyMarshal.ReadPtrField(truePtr, PyIntObject, 'ob_type'), mapper.PyBool_Type) self.assertEquals( CPyMarshal.ReadIntField(truePtr, PyIntObject, 'ob_refcnt'), 1) self.assertEquals( CPyMarshal.ReadIntField(truePtr, PyIntObject, 'ob_ival'), 1) truePtr2 = mapper.Store(True) self.assertEquals(truePtr2, truePtr) self.assertEquals(mapper.RefCount(truePtr), 2) falsePtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyIntObject)) mapper.RegisterData("_Py_ZeroStruct", falsePtr) self.assertTrue(mapper.Retrieve(falsePtr) is False) self.assertEquals( CPyMarshal.ReadPtrField(falsePtr, PyIntObject, 'ob_type'), mapper.PyBool_Type) self.assertEquals( CPyMarshal.ReadIntField(falsePtr, PyIntObject, 'ob_refcnt'), 1) self.assertEquals( CPyMarshal.ReadIntField(falsePtr, PyIntObject, 'ob_ival'), 0) falsePtr2 = mapper.Store(False) self.assertEquals(falsePtr2, falsePtr) self.assertEquals(mapper.RefCount(falsePtr), 2)
def assertPyTuple_New_Works(self, length): allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, [])) typeBlock = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject)) mapper.RegisterData("PyTuple_Type", typeBlock) tuplePtr = mapper.PyTuple_New(length) expectedSize = Marshal.SizeOf(PyTupleObject) + (CPyMarshal.PtrSize * (length - 1)) self.assertEquals(allocs, [(tuplePtr, expectedSize)], "bad alloc") tupleStruct = Marshal.PtrToStructure(tuplePtr, PyTupleObject) self.assertEquals(tupleStruct.ob_refcnt, 1, "bad refcount") self.assertEquals(tupleStruct.ob_type, mapper.PyTuple_Type, "bad type") self.assertEquals(tupleStruct.ob_size, length, "bad size") self.assertEquals(mapper.PyTuple_Size(tuplePtr), length, "should still work with uninitialised tuple imo") dataPtr = OffsetPtr(tuplePtr, Marshal.OffsetOf(PyTupleObject, "ob_item")) itemPtrs = [] for i in range(length): self.assertEquals(CPyMarshal.ReadPtr(dataPtr), IntPtr.Zero, "item memory not zeroed") itemPtr = mapper.Store(i + 100) CPyMarshal.WritePtr(dataPtr, itemPtr) itemPtrs.append(itemPtr) dataPtr = OffsetPtr(dataPtr, CPyMarshal.PtrSize) immutableTuple = mapper.Retrieve(tuplePtr) self.assertEquals(immutableTuple, tuple(i + 100 for i in range(length)), "broken") tuplePtr2 = mapper.Store(immutableTuple) self.assertEquals(tuplePtr2, tuplePtr, "didn't realise already had this object stored") self.assertEquals(mapper.RefCount(tuplePtr), 2, "didn't incref") mapper.Dispose() Marshal.FreeHGlobal(typeBlock)
def testPyType_Ready(self, mapper, addToCleanUp): typePtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject())) CPyMarshal.Zero(typePtr, Marshal.SizeOf(PyTypeObject())) addToCleanUp(lambda: Marshal.FreeHGlobal(typePtr)) self.assertEquals(mapper.PyType_Ready(typePtr), 0, "wrong") self.assertEquals( CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "ob_type"), mapper.PyType_Type, "failed to fill in missing ob_type") self.assertEquals( CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "tp_base"), mapper.PyBaseObject_Type, "failed to fill in missing tp_base") tp_dict = mapper.Retrieve( CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "tp_dict")) self.assertEquals(mapper.Retrieve(typePtr).__dict__, tp_dict) typeFlags = CPyMarshal.ReadIntField(typePtr, PyTypeObject, "tp_flags") self.assertEquals(typeFlags & UInt32(Py_TPFLAGS.READY), UInt32(Py_TPFLAGS.READY), "did not ready type") self.assertEquals( typeFlags & UInt32(Py_TPFLAGS.HAVE_CLASS), UInt32(Py_TPFLAGS.HAVE_CLASS), "we always set this flag, for no better reason than 'it makes ctypes kinda work'" ) CPyMarshal.WritePtrField(typePtr, PyTypeObject, "ob_type", IntPtr.Zero) self.assertEquals(mapper.PyType_Ready(typePtr), 0, "wrong") self.assertEquals( CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "ob_type"), IntPtr.Zero, "unexpectedly and unnecessarily rereadied type")
def testShrink(self): allocs = [] frees = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, frees)) deallocTypes = CreateTypes(mapper) del allocs[:] oldLength = 365 newLength = 20 ptrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(IntPtr)) try: strPtr = mapper.PyString_FromStringAndSize(IntPtr.Zero, oldLength) Marshal.WriteIntPtr(ptrPtr, strPtr) baseSize = Marshal.SizeOf(PyStringObject) self.assertEquals(allocs, [(strPtr, oldLength + baseSize)], "allocated wrong") self.assertEquals(mapper._PyString_Resize(ptrPtr, newLength), 0, "bad return on success") self.assertHasStringType(strPtr, mapper) self.assertStringObjectHasLength(strPtr, newLength) self.assertEquals(allocs, [(strPtr, oldLength + baseSize)], "unexpected extra alloc") self.assertEquals(frees, [], "unexpected frees") finally: mapper.Dispose() Marshal.FreeHGlobal(ptrPtr) deallocTypes()
def testStoreSameObjectIncRefsOriginal(self): frees = [] allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, frees)) deallocTypes = CreateTypes(mapper) del allocs[:] obj1 = object() result1 = mapper.Store(obj1) result2 = mapper.Store(obj1) self.assertEquals(allocs, [(result1, Marshal.SizeOf(PyObject))], "unexpected result") self.assertEquals(result1, result2, "did not return same ptr") self.assertEquals(mapper.RefCount(result1), 2, "did not incref") mapper.DecRef(result1) del frees[:] mapper.DecRef(result1) self.assertEquals(frees, [result1], "did not free memory") result3 = mapper.Store(obj1) self.assertEquals( allocs, [(result1, Marshal.SizeOf(PyObject)), (result3, Marshal.SizeOf(PyObject))], "unexpected result -- failed to clear reverse mapping?") mapper.Dispose() deallocTypes()
def testWritePtrField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyObject())) CPyMarshal.WritePtrField(data, PyObject, "ob_type", IntPtr(12345)) dataStruct = PtrToStructure(data, PyObject) self.assertEquals(dataStruct.ob_type, IntPtr(12345), "failed to write") Marshal.FreeHGlobal(data)
def testWriteDoubleField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyFloatObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyFloatObject())) CPyMarshal.WriteDoubleField(data, PyFloatObject, "ob_fval", 7.6e-5) dataStruct = PtrToStructure(data, PyFloatObject) self.assertEquals(dataStruct.ob_fval, 7.6e-5) Marshal.FreeHGlobal(data)
def testReadDoubleField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyFloatObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyFloatObject())) CPyMarshal.WriteDoubleField(data, PyFloatObject, "ob_fval", -1.2e34) self.assertEquals( CPyMarshal.ReadDoubleField(data, PyFloatObject, "ob_fval"), -1.2e34) Marshal.FreeHGlobal(data)
def testReadPtrField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyTypeObject())) CPyMarshal.WritePtrField(data, PyTypeObject, "tp_doc", IntPtr(12345)) self.assertEquals( CPyMarshal.ReadPtrField(data, PyTypeObject, "tp_doc"), IntPtr(12345), "failed to read") Marshal.FreeHGlobal(data)
def testWriteIntField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyIntObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyIntObject())) for value in (Int32.MaxValue, Int32.MinValue): CPyMarshal.WriteIntField(data, PyIntObject, "ob_ival", value) dataStruct = PtrToStructure(data, PyIntObject) self.assertEquals(dataStruct.ob_ival, value, "failed to write") Marshal.FreeHGlobal(data)
def testReadCStringFieldEmpty(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyTypeObject())) CPyMarshal.WritePtrField(data, PyTypeObject, "tp_doc", IntPtr.Zero) self.assertEquals( CPyMarshal.ReadCStringField(data, PyTypeObject, "tp_doc"), "", "failed to read correctly") Marshal.FreeHGlobal(data)
def testReadIntField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyIntObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyIntObject())) for value in (Int32.MaxValue, Int32.MinValue): CPyMarshal.WriteIntField(data, PyIntObject, "ob_ival", value) self.assertEquals( CPyMarshal.ReadIntField(data, PyIntObject, "ob_ival"), value, "failed to read") Marshal.FreeHGlobal(data)
def testReadUIntField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyTypeObject())) for value in (UInt32.MaxValue, UInt32.MinValue): CPyMarshal.WriteUIntField(data, PyTypeObject, "tp_version_tag", value) self.assertEquals( CPyMarshal.ReadUIntField(data, PyTypeObject, "tp_version_tag"), value, "failed to read") Marshal.FreeHGlobal(data)
def testWriteUIntField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyTypeObject())) for value in (UInt32.MaxValue, UInt32.MinValue): CPyMarshal.WriteUIntField(data, PyTypeObject, "tp_version_tag", value) dataStruct = PtrToStructure(data, PyTypeObject) self.assertEquals(dataStruct.tp_version_tag, value, "failed to write") Marshal.FreeHGlobal(data)
def testWriteCStringField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyTypeObject())) string = "Hey, I am a string. I have tricksy \\escapes\\." CPyMarshal.WriteCStringField(data, PyTypeObject, "tp_doc", string) self.assertEquals( CPyMarshal.ReadCStringField(data, PyTypeObject, "tp_doc"), string, "failed to read correctly") Marshal.FreeHGlobal( CPyMarshal.ReadPtrField(data, PyTypeObject, "tp_doc")) Marshal.FreeHGlobal(data)
def testSomeItems(self): allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, [])) deallocTypes = CreateTypes(mapper) typeSpec = { "tp_basicsize": 32, "tp_itemsize": 64, } typePtr, deallocType = MakeTypePtr(mapper, typeSpec) del allocs[:] result = mapper.PyType_GenericAlloc(typePtr, 3) self.assertEquals(allocs, [(result, 224)], "allocated wrong") refcount = CPyMarshal.ReadIntField(result, PyObject, "ob_refcnt") self.assertEquals(refcount, 1, "bad initialisation") instanceType = CPyMarshal.ReadPtrField(result, PyObject, "ob_type") self.assertEquals(instanceType, typePtr, "bad type ptr") size = CPyMarshal.ReadIntField(result, PyVarObject, "ob_size") self.assertEquals(size, 3, "bad ob_size") headerSize = Marshal.SizeOf(PyVarObject) zerosPtr = OffsetPtr(result, headerSize) for i in range(224 - headerSize): self.assertEquals(CPyMarshal.ReadByte(zerosPtr), 0, "not zeroed") zerosPtr = OffsetPtr(zerosPtr, 1) mapper.Dispose() deallocTypes() deallocType()
def testExtensionTypesAutoActualisable(self): discoveryModes = { "IncRef": lambda f, o: self.assertMaps(mapper, f, o, 5), "Retrieve": lambda f, o: self.assertMaps(mapper, f, o, 4), "DecRef": lambda f, o: self.assertMaps(mapper, f, o, 3), "RefCount": lambda f, o: self.assertMaps(mapper, f, o, 4), } allocator = HGlobalAllocator() mapper = PythonMapper(allocator) deallocTypes = CreateTypes(mapper) # delay deallocs to avoid types with the same addresses causing confusion userTypeDeallocs = [] try: for (mode, TestFunc) in discoveryModes.items(): typePtr, deallocType = MakeTypePtr(mapper, {"tp_name": mode + "Class"}) userTypeDeallocs.append(deallocType) objPtr = allocator.Alloc(Marshal.SizeOf(PyObject)) CPyMarshal.WriteIntField(objPtr, PyObject, "ob_refcnt", 2) CPyMarshal.WritePtrField(objPtr, PyObject, "ob_type", typePtr) discoveryFunc = getattr(mapper, mode) TestFunc(discoveryFunc, objPtr) finally: mapper.Dispose() for deallocFunc in userTypeDeallocs: deallocFunc() deallocTypes()
def testStoreStringCreatesStringType(self): allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, [])) deallocTypes = CreateTypes(mapper) del allocs[:] testString = "fnord" + self.getStringWithValues(1, 256) testBytes = self.byteArrayFromString(testString) testData = self.ptrFromByteArray(testBytes) testLength = len(testString) try: strPtr = mapper.Store(testString) baseSize = Marshal.SizeOf(PyStringObject) self.assertEquals(allocs, [(strPtr, testLength + baseSize)], "allocated wrong") self.assertHasStringType(strPtr, mapper) self.assertStringObjectHasLength(strPtr, testLength) self.assertStringObjectHasDataBytes(strPtr, testBytes) self.assertEquals(mapper.Retrieve(strPtr), testString, "failed to read string data") strPtr2 = mapper.Store(testString) self.assertEquals(strPtr2, strPtr, "did not remember already had this string") self.assertEquals(mapper.RefCount(strPtr), 2, "did not incref on store") finally: mapper.Dispose() deallocTypes()
def testPyList_New_NonZeroLength(self): allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, [])) deallocTypes = CreateTypes(mapper) del allocs[:] SIZE = 27 listPtr = mapper.PyList_New(SIZE) listStruct = Marshal.PtrToStructure(listPtr, PyListObject) self.assertEquals(listStruct.ob_refcnt, 1, "bad refcount") self.assertEquals(listStruct.ob_type, mapper.PyList_Type, "bad type") self.assertEquals(listStruct.ob_size, SIZE, "bad ob_size") self.assertEquals(listStruct.allocated, SIZE, "bad allocated") dataPtr = listStruct.ob_item self.assertNotEquals(dataPtr, IntPtr.Zero, "failed to allocate space for data") expectedAllocs = [(dataPtr, (SIZE * CPyMarshal.PtrSize)), (listPtr, Marshal.SizeOf(PyListObject))] self.assertEquals(set(allocs), set(expectedAllocs), "allocated wrong") for _ in range(SIZE): self.assertEquals(CPyMarshal.ReadPtr(dataPtr), IntPtr.Zero, "failed to zero memory") dataPtr = OffsetPtr(dataPtr, CPyMarshal.PtrSize) mapper.Dispose() deallocTypes()
def testCreateStringWithData(self): allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, [])) deallocTypes = CreateTypes(mapper) del allocs[:] try: testString = "we also run the shovel racket" + self.getStringWithValues( 0, 256) testBytes = self.byteArrayFromString(testString) testData = self.ptrFromByteArray(testBytes) testLength = len(testString) strPtr = mapper.PyString_FromStringAndSize(testData, testLength) baseSize = Marshal.SizeOf(PyStringObject) self.assertEquals(allocs, [(strPtr, testLength + baseSize)], "allocated wrong") self.assertHasStringType(strPtr, mapper) self.assertStringObjectHasLength(strPtr, testLength) self.assertStringObjectHasDataBytes(strPtr, testBytes) self.assertEquals(mapper.Retrieve(strPtr), testString, "failed to read string data") finally: mapper.Dispose() deallocTypes()
def testCreateEmptyString(self): allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, [])) deallocTypes = CreateTypes(mapper) del allocs[:] try: testString = "we run the grease racket in this town" + self.getStringWithValues( 0, 256) testLength = len(testString) strPtr = mapper.PyString_FromStringAndSize(IntPtr.Zero, testLength) baseSize = Marshal.SizeOf(PyStringObject) self.assertEquals(allocs, [(strPtr, testLength + baseSize)], "allocated wrong") self.assertStringObjectHasLength(strPtr, testLength) self.assertHasStringType(strPtr, mapper) testBytes = self.byteArrayFromString(testString) self.fillStringDataWithBytes(strPtr, testBytes) resultStr = mapper.Retrieve(strPtr) self.assertEquals(resultStr, testString, "failed to read string data") strPtr2 = mapper.Store(resultStr) self.assertEquals(strPtr2, strPtr, "did not remember already had this string") self.assertEquals(mapper.RefCount(strPtr), 2, "did not incref on store") finally: mapper.Dispose() deallocTypes()
def testBufferProtocol(self, mapper, later): # should all be implemented in C really, but weaving cpy string type into # our code feels too much like hard work for now strPtr = mapper.PyString_Type bufPtr = CPyMarshal.ReadPtrField(strPtr, PyTypeObject, 'tp_as_buffer') self.assertNotEquals(bufPtr, IntPtr.Zero) getreadbuffer = CPyMarshal.ReadFunctionPtrField( bufPtr, PyBufferProcs, 'bf_getreadbuffer', dgt_int_ptrintptr) getwritebuffer = CPyMarshal.ReadFunctionPtrField( bufPtr, PyBufferProcs, 'bf_getwritebuffer', dgt_int_ptrintptr) getcharbuffer = CPyMarshal.ReadFunctionPtrField( bufPtr, PyBufferProcs, 'bf_getcharbuffer', dgt_int_ptrintptr) getsegcount = CPyMarshal.ReadFunctionPtrField(bufPtr, PyBufferProcs, 'bf_getsegcount', dgt_int_ptrptr) ptrptr = Marshal.AllocHGlobal(Marshal.SizeOf(IntPtr)) later(lambda: Marshal.FreeHGlobal(ptrptr)) strptr = mapper.Store("hullo") for getter in (getreadbuffer, getcharbuffer): self.assertEquals(getter(strptr, 0, ptrptr), 5) self.assertEquals( CPyMarshal.ReadPtr(ptrptr), CPyMarshal.GetField(strptr, PyStringObject, 'ob_sval')) self.assertEquals(getter(strptr, 1, ptrptr), -1) self.assertMapperHasError(mapper, SystemError) self.assertEquals(getwritebuffer(strptr, 0, ptrptr), -1) self.assertMapperHasError(mapper, SystemError) self.assertEquals(getsegcount(strptr, ptrptr), 1) self.assertEquals(CPyMarshal.ReadInt(ptrptr), 5) self.assertEquals(getsegcount(strptr, IntPtr.Zero), 1)
def dis(p, EntryPoint, len=128): bytes = p.GetVirtualByteLen(EntryPoint, len) #setup Capstone to find instruction to patch insnHandle = clr.Reference[IntPtr]() disHandle = clr.Reference[IntPtr]() csopen = Capstone.cs_open(Capstone.cs_arch.CS_ARCH_X86, Capstone.cs_mode.CS_MODE_64, disHandle) # intel diss csopt = Capstone.cs_option(disHandle.Value, 1, 1) # detail mode csopt = Capstone.cs_option(disHandle.Value, 2, 3) count = Capstone.cs_disasm(disHandle.Value, bytes, len, EntryPoint, 0, insnHandle) #print "capstone count = " + count.ToString() curr = 0 insn = Capstone.cs_insn() detail = Capstone.cs_detail() BuffOffset = insnHandle.ToInt64() insn_size = Marshal.SizeOf(insn) PatchAddr = 0 NopCnt = 0 Console.ForegroundColor = ConsoleColor.Green #find the last jne while curr < count: InsnPointer = IntPtr(BuffOffset) cs = PtrToStructure(InsnPointer, Capstone.cs_insn) print "[" + cs.address.ToString("x") + "] (" + p.GetSymName( cs.address) + ") [" + cs.bytes[0].ToString( "x") + "] " + cs.mnemonic + " " + cs.operands curr += 1 BuffOffset += insn_size # clean up Capstone Capstone.cs_close(disHandle) Capstone.cs_free(insnHandle.Value, count) Console.ForegroundColor = ConsoleColor.Yellow
def testStoreType(self, mapper, _): self.assertEquals(mapper.Retrieve(mapper.PyFunction_Type), FunctionType) self.assertEquals( CPyMarshal.ReadIntField(mapper.PyFunction_Type, PyTypeObject, 'tp_basicsize'), Marshal.SizeOf(PyFunctionObject()))
def testStoreTypeDictCreatesDictTypeWhichWorks(self, mapper, addToCleanUp): typeBlock = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject)) addToCleanUp(lambda: Marshal.FreeHGlobal(typeBlock)) mapper.RegisterData("PyDict_Type", typeBlock) class klass(object): pass dictPtr = mapper.Store(klass.__dict__) self.assertEquals( CPyMarshal.ReadPtrField(dictPtr, PyObject, "ob_type"), typeBlock, "wrong type") self.assertEquals( mapper.PyDict_SetItemString(dictPtr, 'foo', mapper.Store('bar')), 0) self.assertEquals( mapper.PyDict_SetItem(dictPtr, mapper.Store('baz'), mapper.Store('qux')), 0) self.assertEquals( mapper.Retrieve(mapper.PyDict_GetItemString(dictPtr, 'foo')), 'bar') self.assertEquals( mapper.Retrieve(mapper.PyDict_GetItem(dictPtr, mapper.Store('baz'))), 'qux') self.assertEquals(klass.foo, 'bar') self.assertEquals(klass.baz, 'qux') self.assertEquals(mapper.PyDict_Size(dictPtr), len(klass.__dict__))
def testStoreTupleCreatesTupleType(self): allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, [])) typeBlock = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject())) mapper.RegisterData("PyTuple_Type", typeBlock) theTuple = (0, 1, 2) tuplePtr = mapper.Store(theTuple) self.assertEquals( CPyMarshal.ReadPtrField(tuplePtr, PyTupleObject, "ob_type"), typeBlock, "wrong type") dataPtr = OffsetPtr(tuplePtr, Marshal.OffsetOf(PyTupleObject, "ob_item")) for i in range(3): item = mapper.Retrieve(CPyMarshal.ReadPtr(dataPtr)) self.assertEquals(item, i, "did not store data") dataPtr = OffsetPtr(dataPtr, CPyMarshal.PtrSize) tuplePtr2 = mapper.Store(theTuple) self.assertEquals(tuplePtr2, tuplePtr, "didn't realise already had this tuple") self.assertEquals(mapper.RefCount(tuplePtr), 2, "didn't incref") mapper.Dispose() Marshal.FreeHGlobal(typeBlock)
def CreateTypes(mapper, readyTypes=True): blocks = [] def create(name, size): block = Marshal.AllocHGlobal(size) if name == 'PyFile_Type': CPyMarshal.Zero(block, size) CPyMarshal.WritePtrField(block, PyTypeObject, 'tp_dealloc', mapper.GetFuncPtr('IC_file_dealloc')) mapper.RegisterData(name, block) blocks.append(block) for _type in _types: create(_type, Marshal.SizeOf(PyTypeObject())) for (_other, size) in _others.items(): create(_other, size) if readyTypes: mapper.ReadyBuiltinTypes() def DestroyTypes(): for block in blocks: Marshal.FreeHGlobal(block) return DestroyTypes
def testBasicStoreRetrieveFree(self): frees = [] allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, frees)) deallocTypes = CreateTypes(mapper) del allocs[:] obj1 = object() ptr = mapper.Store(obj1) self.assertEquals(len(allocs), 1, "unexpected number of allocations") self.assertEquals(allocs[0], (ptr, Marshal.SizeOf(PyObject)), "unexpected result") self.assertNotEquals(ptr, IntPtr.Zero, "did not store reference") self.assertEquals(mapper.RefCount(ptr), 1, "unexpected refcount") self.assertEquals(CPyMarshal.ReadPtrField(ptr, PyObject, "ob_type"), mapper.PyBaseObject_Type, "nearly-opaque pointer had wrong type") obj2 = mapper.Retrieve(ptr) self.assertTrue(obj1 is obj2, "retrieved wrong object") self.assertEquals(frees, [], "unexpected deallocations") mapper.PyObject_Free(ptr) self.assertEquals(frees, [ptr], "unexpected deallocations") self.assertRaises(KeyError, lambda: mapper.PyObject_Free(ptr)) mapper.Dispose() deallocTypes()
def testPyFile_Type(self, mapper, addToCleanUp): typeBlock = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject)) addToCleanUp(lambda: Marshal.FreeHGlobal(typeBlock)) mapper.RegisterData("PyFile_Type", typeBlock) self.assertEquals(mapper.PyFile_Type, typeBlock, "type address not stored") self.assertEquals(mapper.Retrieve(typeBlock), file, "type not mapped")
def testInternExisting(self, mapper, addToCleanUp): testString = "mars needs women" + self.getStringWithValues(1, 256) bytes = self.byteArrayFromString(testString) testData = self.ptrFromByteArray(bytes) sp1 = mapper.PyString_FromString(testData) addToCleanUp(lambda: Marshal.FreeHGlobal(sp1p)) sp2 = mapper.PyString_InternFromString(testData) addToCleanUp(lambda: Marshal.FreeHGlobal(testData)) self.assertNotEquals(sp1, sp2) self.assertFalse(mapper.Retrieve(sp1) is mapper.Retrieve(sp2)) self.assertEquals(mapper.RefCount(sp1), 1) self.assertEquals( mapper.RefCount(sp2), 2, 'failed to grab extra reference to induce immortality') mapper.IncRef(sp1) sp1p = Marshal.AllocHGlobal(Marshal.SizeOf(IntPtr)) CPyMarshal.WritePtr(sp1p, sp1) mapper.PyString_InternInPlace(sp1p) sp1i = CPyMarshal.ReadPtr(sp1p) self.assertEquals(sp1i, sp2, 'failed to intern') self.assertTrue(mapper.Retrieve(sp1i) is mapper.Retrieve(sp2)) self.assertEquals(mapper.RefCount(sp1), 1, 'failed to decref old string') self.assertEquals(mapper.RefCount(sp2), 3, 'failed to incref interned string')