[pypy-svn] r77197 - in pypy/trunk/pypy: rlib rpython/lltypesystem rpython/lltypesystem/test
afa at codespeak.net
afa at codespeak.net
Mon Sep 20 13:09:35 CEST 2010
Author: afa
Date: Mon Sep 20 13:09:34 2010
New Revision: 77197
Modified:
pypy/trunk/pypy/rlib/rwin32.py
pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py
pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
Log:
Change the _storage attribute:
instead of a ctypes object (struct or array), it now stores a ctypes.pointer to the allocated structure.
This makes it possible to directly cast a number to a lltype.Ptr, and perform comparisons.
Modified: pypy/trunk/pypy/rlib/rwin32.py
==============================================================================
--- pypy/trunk/pypy/rlib/rwin32.py (original)
+++ pypy/trunk/pypy/rlib/rwin32.py Mon Sep 20 13:09:34 2010
@@ -82,6 +82,8 @@
if WIN32:
HANDLE = rffi.COpaquePtr(typedef='HANDLE')
+ assert rffi.cast(HANDLE, -1) == rffi.cast(HANDLE, -1)
+
LPHANDLE = rffi.CArrayPtr(HANDLE)
HMODULE = HANDLE
NULL_HANDLE = rffi.cast(HANDLE, 0)
Modified: pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py (original)
+++ pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py Mon Sep 20 13:09:34 2010
@@ -26,9 +26,6 @@
from pypy.translator.platform import platform
from array import array
-def uaddressof(obj):
- return fixid(ctypes.addressof(obj))
-
_ctypes_cache = {}
_eci_cache = {}
@@ -251,7 +248,7 @@
else:
n = None
cstruct = cls._malloc(n)
- add_storage(container, _struct_mixin, cstruct)
+ add_storage(container, _struct_mixin, ctypes.pointer(cstruct))
for field_name in STRUCT._names:
FIELDTYPE = getattr(STRUCT, field_name)
field_value = getattr(container, field_name)
@@ -264,8 +261,6 @@
if isinstance(FIELDTYPE, lltype.Struct):
csubstruct = getattr(cstruct, field_name)
convert_struct(field_value, csubstruct)
- subcontainer = getattr(container, field_name)
- substorage = subcontainer._storage
elif field_name == STRUCT._arrayfld: # inlined var-sized part
csubarray = getattr(cstruct, field_name)
convert_array(field_value, csubarray)
@@ -292,7 +287,7 @@
# regular case: allocate a new ctypes array of the proper type
cls = get_ctypes_type(ARRAY)
carray = cls._malloc(container.getlength())
- add_storage(container, _array_mixin, carray)
+ add_storage(container, _array_mixin, ctypes.pointer(carray))
if not isinstance(ARRAY.OF, lltype.ContainerType):
# fish that we have enough space
ctypes_array = ctypes.cast(carray.items,
@@ -321,13 +316,15 @@
if isinstance(FIELDTYPE, lltype.ContainerType):
if isinstance(FIELDTYPE, lltype.Struct):
struct_container = getattr(container, field_name)
- struct_storage = getattr(ctypes_storage, field_name)
+ struct_storage = ctypes.pointer(
+ getattr(ctypes_storage.contents, field_name))
struct_use_ctypes_storage(struct_container, struct_storage)
struct_container._setparentstructure(container, field_name)
elif isinstance(FIELDTYPE, lltype.Array):
assert FIELDTYPE._hints.get('nolength', False) == False
arraycontainer = _array_of_known_length(FIELDTYPE)
- arraycontainer._storage = getattr(ctypes_storage, field_name)
+ arraycontainer._storage = ctypes.pointer(
+ getattr(ctypes_storage.contents, field_name))
arraycontainer._setparentstructure(container, field_name)
object.__setattr__(container, field_name, arraycontainer)
else:
@@ -352,6 +349,8 @@
def add_storage(instance, mixin_cls, ctypes_storage):
"""Put ctypes_storage on the instance, changing its __class__ so that it
sees the methods of the given mixin class."""
+ # _storage is a ctypes pointer to a structure
+ # except for Opaque objects which use a c_void_p.
assert not isinstance(instance, _parentable_mixin) # not yet
subcls = get_common_subclass(mixin_cls, instance.__class__)
instance.__class__ = subcls
@@ -365,17 +364,23 @@
__slots__ = ()
def _ctypes_storage_was_allocated(self):
- addr = ctypes.addressof(self._storage)
+ addr = ctypes.cast(self._storage, ctypes.c_void_p).value
if addr in ALLOCATED:
raise Exception("internal ll2ctypes error - "
"double conversion from lltype to ctypes?")
# XXX don't store here immortal structures
ALLOCATED[addr] = self
+ def _addressof_storage(self):
+ "Returns the storage address as an int"
+ if self._storage is None or self._storage is True:
+ raise ValueError("Not a ctypes allocated structure")
+ return ctypes.cast(self._storage, ctypes.c_void_p).value
+
def _free(self):
self._check() # no double-frees
# allow the ctypes object to go away now
- addr = ctypes.addressof(self._storage)
+ addr = ctypes.cast(self._storage, ctypes.c_void_p).value
try:
del ALLOCATED[addr]
except KeyError:
@@ -393,16 +398,16 @@
raise RuntimeError("pointer comparison with a freed structure")
if other._storage is True:
return False # the other container is not ctypes-based
- addressof_other = ctypes.addressof(other._storage)
- # both containers are ctypes-based, compare by address
- return (ctypes.addressof(self._storage) == addressof_other)
+ addressof_other = other._addressof_storage()
+ # both containers are ctypes-based, compare the addresses
+ return self._addressof_storage() == addressof_other
def __ne__(self, other):
return not (self == other)
def __hash__(self):
if self._storage is not None:
- return ctypes.addressof(self._storage)
+ return self._addressof_storage()
else:
return object.__hash__(self)
@@ -411,7 +416,7 @@
return '<freed C object %s>' % (self._TYPE,)
else:
return '<C object %s at 0x%x>' % (self._TYPE,
- uaddressof(self._storage),)
+ fixid(self._addressof_storage()))
def __str__(self):
return repr(self)
@@ -422,7 +427,7 @@
def __getattr__(self, field_name):
T = getattr(self._TYPE, field_name)
- cobj = getattr(self._storage, field_name)
+ cobj = getattr(self._storage.contents, field_name)
return ctypes2lltype(T, cobj)
def __setattr__(self, field_name, value):
@@ -430,17 +435,17 @@
object.__setattr__(self, field_name, value) # '_xxx' attributes
else:
cobj = lltype2ctypes(value)
- setattr(self._storage, field_name, cobj)
+ setattr(self._storage.contents, field_name, cobj)
class _array_mixin(_parentable_mixin):
"""Mixin added to _array containers when they become ctypes-based."""
__slots__ = ()
def getitem(self, index, uninitialized_ok=False):
- return self._storage._getitem(index)
+ return self._storage.contents._getitem(index)
def setitem(self, index, value):
- self._storage._setitem(index, value)
+ self._storage.contents._setitem(index, value)
class _array_of_unknown_length(_parentable_mixin, lltype._parentable):
_kind = "array"
@@ -451,10 +456,10 @@
return 0, sys.maxint
def getitem(self, index, uninitialized_ok=False):
- return self._storage._getitem(index, boundscheck=False)
+ return self._storage.contents._getitem(index, boundscheck=False)
def setitem(self, index, value):
- self._storage._setitem(index, value, boundscheck=False)
+ self._storage.contents._setitem(index, value, boundscheck=False)
def getitems(self):
if self._TYPE.OF != lltype.Char:
@@ -476,7 +481,7 @@
__slots__ = ()
def getlength(self):
- return self._storage.length
+ return self._storage.contents.length
def getbounds(self):
return 0, self.getlength()
@@ -653,17 +658,18 @@
container._ctypes_storage_was_allocated()
if isinstance(T.TO, lltype.OpaqueType):
- return container._storage
+ return container._storage.value
storage = container._storage
- p = ctypes.pointer(storage)
+ p = storage
if index:
p = ctypes.cast(p, ctypes.c_void_p)
p = ctypes.c_void_p(p.value + index)
c_tp = get_ctypes_type(T.TO)
- storage._normalized_ctype = c_tp
- if normalize and hasattr(storage, '_normalized_ctype'):
- p = ctypes.cast(p, ctypes.POINTER(storage._normalized_ctype))
+ storage.contents._normalized_ctype = c_tp
+ if normalize and hasattr(storage.contents, '_normalized_ctype'):
+ normalized_ctype = storage.contents._normalized_ctype
+ p = ctypes.cast(p, ctypes.POINTER(normalized_ctype))
if lltype.typeOf(llobj) == llmemory.GCREF:
p = ctypes.cast(p, ctypes.c_void_p)
return p
@@ -707,13 +713,13 @@
cobjheader = ctypes.cast(cobj,
get_ctypes_type(lltype.Ptr(OBJECT)))
struct_use_ctypes_storage(containerheader,
- cobjheader.contents)
+ cobjheader)
REAL_TYPE = get_rtyper().get_type_for_typeptr(
containerheader.typeptr)
REAL_T = lltype.Ptr(REAL_TYPE)
cobj = ctypes.cast(cobj, get_ctypes_type(REAL_T))
container = lltype._struct(REAL_TYPE)
- struct_use_ctypes_storage(container, cobj.contents)
+ struct_use_ctypes_storage(container, cobj)
if REAL_TYPE != T.TO:
p = container._as_ptr()
container = lltype.cast_pointer(T, p)._as_obj()
@@ -728,10 +734,10 @@
elif isinstance(T.TO, lltype.Array):
if T.TO._hints.get('nolength', False):
container = _array_of_unknown_length(T.TO)
- container._storage = cobj.contents
+ container._storage = cobj
else:
container = _array_of_known_length(T.TO)
- container._storage = cobj.contents
+ container._storage = cobj
elif isinstance(T.TO, lltype.FuncType):
cobjkey = intmask(ctypes.cast(cobj, ctypes.c_void_p).value)
if cobjkey in _int2obj:
@@ -745,7 +751,8 @@
container = _llgcopaque(cobj)
else:
container = lltype._opaque(T.TO)
- container._storage = ctypes.cast(cobj, ctypes.c_void_p)
+ cbuf = ctypes.cast(cobj, ctypes.c_void_p)
+ add_storage(container, _parentable_mixin, cbuf)
else:
raise NotImplementedError(T)
llobj = lltype._ptr(T, container, solid=True)
Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py (original)
+++ pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Mon Sep 20 13:09:34 2010
@@ -353,6 +353,8 @@
assert tmppath.check(file=1)
assert not ALLOCATED # detects memory leaks in the test
+ assert rffi.cast(FILEP, -1) == rffi.cast(FILEP, -1)
+
def test_simple_cast(self):
assert rffi.cast(rffi.SIGNEDCHAR, 0x123456) == 0x56
assert rffi.cast(rffi.SIGNEDCHAR, 0x123481) == -127
More information about the Pypy-commit
mailing list