示例#1
0
        def do():
            # see NOTE
            map, ptr1, obj1, ref1 = self.getVars()
            _, ptr2, obj2, ref2 = self.getVars()
            map.BridgeAssociate(ptr1, obj1)
            map.BridgeAssociate(ptr2, obj2)

            # make both ptrs 'ready to weaken'
            CPyMarshal.WriteIntField(ptr1, PyObject, 'ob_refcnt', 1)
            CPyMarshal.WriteIntField(ptr2, PyObject, 'ob_refcnt', 1)

            map.CheckBridgePtrs(True)
            del obj1
            del obj2
            return map, ref1, ref2
示例#2
0
 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()
示例#3
0
 def testFields(self, mapper, CallLater):
     basePtr, deallocBase = MakeTypePtr(mapper, {})
     typePtr, deallocType = MakeTypePtr(mapper, {})
     CallLater(deallocBase)
     CallLater(deallocType)
     
     # The purpose of this rigmarole is to enable me to use SOME_VALUE
     # for every field, rather than creating 'proper' values for every 
     # field -- once I've Retrieved the types, I won't actualise them 
     # again, so I can put any old non-zero nonsense in any field to 
     # check that it gets inherited (or not)
     mapper.Retrieve(basePtr)
     mapper.Retrieve(typePtr)
     CPyMarshal.WriteIntField(typePtr, PyTypeObject, "tp_flags", int(Py_TPFLAGS.HAVE_CLASS))
     # end rigmarole
     
     CPyMarshal.WritePtrField(typePtr, PyTypeObject, "tp_base", basePtr)
     for field in INHERIT_FIELDS + DONT_INHERIT_FIELDS:
         CPyMarshal.WritePtrField(typePtr, PyTypeObject, field, NO_VALUE)
         CPyMarshal.WritePtrField(basePtr, PyTypeObject, field, SOME_VALUE)
     
     mapper.PyType_Ready(typePtr)
     for field in INHERIT_FIELDS:
         self.assertEquals(CPyMarshal.ReadPtrField(typePtr, PyTypeObject, field), SOME_VALUE)
     for field in DONT_INHERIT_FIELDS:
         self.assertEquals(CPyMarshal.ReadPtrField(typePtr, PyTypeObject, field), NO_VALUE)
    def testIgnoresBridgeObjectsNotAllocatedByAllocator(self):
        obj = object()
        ptr = Marshal.AllocHGlobal(Marshal.SizeOf(PyObject))
        CPyMarshal.WriteIntField(ptr, PyObject, 'ob_refcnt', 2)

        mapper = PythonMapper()
        mapper.StoreBridge(ptr, obj)
        mapper.Dispose()
示例#5
0
 def testActualiseFloat(self, mapper, call_later):
     fptr = Marshal.AllocHGlobal(Marshal.SizeOf(PyFloatObject))
     call_later(lambda: Marshal.FreeHGlobal(fptr))
     CPyMarshal.WritePtrField(fptr, PyFloatObject, "ob_type",
                              mapper.PyFloat_Type)
     CPyMarshal.WriteIntField(fptr, PyFloatObject, "ob_refcnt", 1)
     CPyMarshal.WriteDoubleField(fptr, PyFloatObject, "ob_fval", 1.234)
     self.assertEquals(mapper.Retrieve(fptr), 1.234)
示例#6
0
            def do():
                # see NOTE in interestingptrmaptest
                obj = object()
                ref = WeakReference(obj)
                CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1)
                CPyMarshal.WritePtrField(ptr, PyObject, "ob_type", mapper.PyBaseObject_Type)
                mapper.StoreBridge(ptr, obj)

                self.assertEquals(mapper.Retrieve(ptr), obj, "object not stored")
                self.assertEquals(mapper.Store(obj), ptr, "object not reverse-mapped")

                mapper.Weaken(obj)
                CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1)

                mapper.IncRef(ptr)
                del obj
                return ref
示例#7
0
 def do1():
     # see NOTE in interestingptrmaptest
     obj = object()
     ref = WeakReference(obj)
     CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1)
     CPyMarshal.WritePtrField(ptr, PyObject, "ob_type", mapper.PyBaseObject_Type)
     mapper.StoreBridge(ptr, obj)
     del obj
     return ref
示例#8
0
 def testNotAutoActualisableTypes(self, mapper, _):
     safeTypes = "PyString_Type PyList_Type PyTuple_Type PyType_Type PyFile_Type PyFloat_Type".split()
     discoveryModes = ("IncRef", "Retrieve", "DecRef", "RefCount")
     for _type in filter(lambda s: s not in safeTypes, BUILTIN_TYPES):
         for mode in discoveryModes:
             objPtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyObject))
             CPyMarshal.WriteIntField(objPtr, PyObject, "ob_refcnt", 2)
             CPyMarshal.WritePtrField(objPtr, PyObject, "ob_type", getattr(mapper, _type))
             self.assertRaises(CannotInterpretException, getattr(mapper, mode), objPtr)
             Marshal.FreeHGlobal(objPtr)
    def testCanFreeWithRefCount0(self):
        frees = []
        mapper = PythonMapper(GetAllocatingTestAllocator([], frees))

        objPtr = mapper.Store(object())
        CPyMarshal.WriteIntField(objPtr, PyObject, "ob_refcnt", 0)

        mapper.PyObject_Free(objPtr)
        self.assertEquals(frees, [objPtr], "didn't actually release memory")
        mapper.Dispose()
示例#10
0
    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)
示例#11
0
    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)
示例#12
0
 def test_PyObject_NewVar(self):
     allocs = []
     allocator = GetAllocatingTestAllocator(allocs, [])
     mapper = PythonMapper(allocator)
     deallocTypes = CreateTypes(mapper)
     
     typeObjSize = Marshal.SizeOf(PyTypeObject())
     typePtr = Marshal.AllocHGlobal(typeObjSize)
     CPyMarshal.Zero(typePtr, typeObjSize)
     CPyMarshal.WriteIntField(typePtr, PyTypeObject, "tp_basicsize", 31337)
     CPyMarshal.WriteIntField(typePtr, PyTypeObject, "tp_itemsize", 1337)
     
     del allocs[:]
     objPtr = mapper._PyObject_NewVar(typePtr, 123)
     self.assertEquals(allocs, [(objPtr, 31337 + (1337 * 123))])
     self.assertEquals(CPyMarshal.ReadPtrField(objPtr, PyObject, 'ob_type'), typePtr)
     self.assertEquals(CPyMarshal.ReadIntField(objPtr, PyObject, 'ob_refcnt'), 1)
     self.assertEquals(mapper.HasPtr(objPtr), False)
     
     mapper.Dispose()
     deallocTypes()
示例#13
0
        def do1():
            obj = object()
            ref = WeakReference(obj)
            # need to use same allocator as mapper, otherwise it gets upset on shutdown
            ptr = allocator.Alloc(Marshal.SizeOf(PyObject()))
            CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 2)
            CPyMarshal.WritePtrField(ptr, PyObject, "ob_type", mapper.PyBaseObject_Type)
            mapper.StoreBridge(ptr, obj)

            # refcount > 1 means ref should have been strengthened
            del obj
            return ref, ptr
示例#14
0
    def testDecRefObjectWithZeroRefCountFails(self):
        allocator = HGlobalAllocator()
        mapper = PythonMapper(allocator)
        deallocTypes = CreateTypes(mapper)

        # need to use same allocator as mapper, otherwise it gets upset on shutdown
        objPtr = allocator.Alloc(Marshal.SizeOf(PyObject()))
        CPyMarshal.WriteIntField(objPtr, PyObject, "ob_refcnt", 0)
        CPyMarshal.WritePtrField(objPtr, PyObject, "ob_type", mapper.PyBaseObject_Type)
        mapper.StoreBridge(objPtr, object())

        self.assertRaisesClr(BadRefCountException, lambda: mapper.DecRef(objPtr))
        mapper.Dispose()
        deallocTypes()
示例#15
0
        def do():
            # see NOTE
            map, ptr, obj, ref = self.getVars()
            self.keepalive = map
            map.BridgeAssociate(ptr, obj)
            map.UpdateStrength(ptr)

            # ref should now be weak, but obj is still referenced in this scope
            CPyMarshal.WriteIntField(ptr, PyObject, 'ob_refcnt', 2)
            map.UpdateStrength(ptr)

            # should now be strong; safe to del obj
            del obj
            return ref
    def testReleaseGILChecksBridgePtrs(self):
        frees = []
        allocator = GetAllocatingTestAllocator([], frees)
        mapper = PythonMapper(allocator)
        deallocTypes = CreateTypes(mapper)

        # force no throttling of cleanup
        mapper.GCThreshold = 0

        def do1():
            obj = object()
            ref = WeakReference(obj)
            # need to use same allocator as mapper, otherwise it gets upset on shutdown
            ptr = allocator.Alloc(Marshal.SizeOf(PyObject))
            CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 2)
            CPyMarshal.WritePtrField(ptr, PyObject, "ob_type",
                                     mapper.PyBaseObject_Type)
            mapper.StoreBridge(ptr, obj)

            # refcount > 1 means ref should have been strengthened
            del obj
            return ref, ptr

        ref, ptr = do1()
        gcwait()
        self.assertEquals(ref.IsAlive, True,
                          "was reaped unexpectedly (refcount was 2)")

        CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1)
        mapper.EnsureGIL()
        mapper.ReleaseGIL()

        # refcount < 2 should have been weakened
        gcwait()
        self.assertRaises(NullReferenceException, mapper.Retrieve, ptr)

        # need to dealloc ptr ourselves, it doesn't hapen automatically
        # except for objects with Dispatchers
        mapper.IC_PyBaseObject_Dealloc(ptr)
        mapper.Dispose()
        deallocTypes()
示例#17
0
def WriteTypeField(typePtr, name, value):
    if name in PTR_ARGS:
        CPyMarshal.WritePtrField(typePtr, PyTypeObject, name, value)
        return lambda: None
    if name in INT_ARGS:
        CPyMarshal.WriteIntField(typePtr, PyTypeObject, name, int(value))
        return lambda: None
    if name in STRING_ARGS:
        ptr = Marshal.StringToHGlobalAnsi(value)
        CPyMarshal.WritePtrField(typePtr, PyTypeObject, name, ptr)
        return lambda: Marshal.FreeHGlobal(ptr)
    if name in TABLE_ARGS:
        ptr, dealloc = MakeItemsTablePtr(value)
        CPyMarshal.WritePtrField(typePtr, PyTypeObject, name, ptr)
        return dealloc
    if name in FUNC_ARGS:
        if value is not None:
            dgt = FUNC_ARGS[name](value)
            CPyMarshal.WriteFunctionPtrField(typePtr, PyTypeObject, name, dgt)
            return GC_NotYet(dgt)
        return lambda: None
    raise KeyError("WriteTypeField can't handle %s, %s" % (name, value))
示例#18
0
    def testStoreUnknownType(self, mapper, _):
        class C(object):
            __name__ = "cantankerous.cochineal"
        cPtr = mapper.Store(C)
        self.assertEquals(CPyMarshal.ReadIntField(cPtr, PyTypeObject, "ob_refcnt"), 2, "seems easiest to 'leak' types, and ensure they live forever")
        self.assertEquals(CPyMarshal.ReadPtrField(cPtr, PyTypeObject, "ob_type"), mapper.PyType_Type)
        self.assertEquals(CPyMarshal.ReadPtrField(cPtr, PyTypeObject, "tp_base"), mapper.PyBaseObject_Type)
        self.assertEquals(CPyMarshal.ReadPtrField(cPtr, PyTypeObject, "tp_bases"), IntPtr.Zero)
        self.assertEquals(CPyMarshal.ReadPtrField(cPtr, PyTypeObject, "tp_as_number"), IntPtr.Zero)

        namePtr = CPyMarshal.ReadPtrField(cPtr, PyTypeObject, "tp_name")
        self.assertEquals(mapper.Retrieve(namePtr), "cantankerous.cochineal")

        baseFlags = CPyMarshal.ReadIntField(cPtr, PyTypeObject, "tp_flags")
        self.assertEquals(baseFlags & UInt32(Py_TPFLAGS.READY), UInt32(Py_TPFLAGS.READY), "did not ready newly-stored type")
        
        instancePtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyObject))
        CPyMarshal.WritePtrField(instancePtr, PyObject, "ob_type", cPtr)
        CPyMarshal.WriteIntField(instancePtr, PyObject, "ob_refcnt", 2)
        
        instance = mapper.Retrieve(instancePtr)
        self.assertEquals(isinstance(instance, C), True)
        self.assertEquals(mapper.Store(instance), instancePtr)
示例#19
0
 def getVars(self):
     obj = object()
     ptr = Marshal.AllocHGlobal(Marshal.SizeOf(PyObject()))
     CPyMarshal.WriteIntField(ptr, PyObject, 'ob_refcnt', 1)
     self.ptrs.append(ptr)
     return InterestingPtrMap(), ptr, obj, WeakReference(obj)