[pypy-svn] r69933 - in pypy/branch/virtual-forcing/pypy/rpython: . lltypesystem lltypesystem/test
arigo at codespeak.net
arigo at codespeak.net
Sun Dec 6 20:04:30 CET 2009
Author: arigo
Date: Sun Dec 6 20:04:30 2009
New Revision: 69933
Modified:
pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/ll2ctypes.py
pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
pypy/branch/virtual-forcing/pypy/rpython/rtyper.py
Log:
Tentative test and fix: remove ll2ctypes._parent_cache.
Instead, recontruct all the information about the real
type of an instance of OBJECT, purely in ctypes2lltype().
This is possible to do, as a small extension of code that
is already there.
Modified: pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/ll2ctypes.py (original)
+++ pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/ll2ctypes.py Sun Dec 6 20:04:30 2009
@@ -30,7 +30,6 @@
_ctypes_cache = {}
_eci_cache = {}
-_parent_cache = {}
def _setup_ctypes_cache():
from pypy.rpython.lltypesystem import rffi
@@ -254,7 +253,6 @@
convert_struct(field_value, csubstruct)
subcontainer = getattr(container, field_name)
substorage = subcontainer._storage
- update_parent_cache(substorage, subcontainer)
elif field_name == STRUCT._arrayfld: # inlined var-sized part
csubarray = getattr(cstruct, field_name)
convert_array(field_value, csubarray)
@@ -313,7 +311,6 @@
struct_storage = getattr(ctypes_storage, field_name)
struct_use_ctypes_storage(struct_container, struct_storage)
struct_container._setparentstructure(container, field_name)
- update_parent_cache(ctypes_storage, struct_container)
elif isinstance(FIELDTYPE, lltype.Array):
assert FIELDTYPE._hints.get('nolength', False) == False
arraycontainer = _array_of_known_length(FIELDTYPE)
@@ -633,8 +630,6 @@
raise NotImplementedError(T)
container._ctypes_storage_was_allocated()
storage = container._storage
- if lltype.parentlink(container)[0] is not None:
- update_parent_cache(storage, container)
p = ctypes.pointer(storage)
if index:
p = ctypes.cast(p, ctypes.c_void_p)
@@ -673,26 +668,25 @@
if not cobj: # NULL pointer
return lltype.nullptr(T.TO)
if isinstance(T.TO, lltype.Struct):
+ REAL_TYPE = T.TO
if T.TO._arrayfld is not None:
carray = getattr(cobj.contents, T.TO._arrayfld)
container = lltype._struct(T.TO, carray.length)
else:
# special treatment of 'OBJECT' subclasses
- if get_rtyper() and lltype._castdepth(T.TO, OBJECT) > 0:
- ctypes_object = get_ctypes_type(lltype.Ptr(OBJECT))
- as_obj = ctypes2lltype(lltype.Ptr(OBJECT),
- ctypes.cast(cobj, ctypes_object))
- TObj = get_rtyper().get_type_for_typeptr(as_obj.typeptr)
- if TObj != T.TO:
- ctypes_instance = get_ctypes_type(lltype.Ptr(TObj))
- return lltype.cast_pointer(T,
- ctypes2lltype(lltype.Ptr(TObj),
- ctypes.cast(cobj, ctypes_instance)))
- container = lltype._struct(T.TO)
+ if get_rtyper() and lltype._castdepth(REAL_TYPE, OBJECT) >= 0:
+ # figure out the real type of the object
+ containerheader = lltype._struct(OBJECT)
+ struct_use_ctypes_storage(containerheader, cobj.contents)
+ 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)
- addr = ctypes.addressof(cobj.contents)
- if addr in _parent_cache:
- setparentstructure(container, _parent_cache[addr])
+ if REAL_TYPE != T.TO:
+ p = container._as_ptr()
+ container = lltype.cast_pointer(T, p)._as_obj()
elif isinstance(T.TO, lltype.Array):
if T.TO._hints.get('nolength', False):
container = _array_of_unknown_length(T.TO)
@@ -1139,46 +1133,6 @@
return hop.genop('cast_adr_to_int', [adr],
resulttype = lltype.Signed)
-# ------------------------------------------------------------
-
-def parentchain(container):
- current = container
- links = []
- while True:
- link = lltype.parentlink(current)
- if link[0] is None:
- try:
- addr = ctypes.addressof(container._storage)
- actual = _parent_cache[addr]
- if len(links) < len(actual):
- return actual
- except KeyError:
- pass
- return links
- links.append(link)
- current = link[0]
-
-def update_parent_cache(storage, container):
- chain = parentchain(container)
- addr = ctypes.addressof(storage)
- try:
- current = _parent_cache[addr]
- if len(chain) > len(current):
- _parent_cache[addr] = chain
- except KeyError:
- _parent_cache[addr] = chain
-
-def setparentstructure(container, chain):
- TP = lltype.typeOf(container)
- current = container
- for i, elem in enumerate(chain):
- if lltype.typeOf(elem[0]) == TP:
- chain = chain[i + 1:]
- break
- for elem in chain:
- current._setparentstructure(*elem)
- current = elem[0]
-
# ____________________________________________________________
# errno
Modified: pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/test/test_ll2ctypes.py (original)
+++ pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Sun Dec 6 20:04:30 2009
@@ -1109,17 +1109,18 @@
def test_object_subclass(self):
from pypy.rpython.lltypesystem import rclass
- SCLASS = lltype.GcStruct('SCLASS',
- ('parent', rclass.OBJECT),
- ('x', lltype.Signed))
+ from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
+ from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
+ class S:
+ pass
def f(n):
- s = lltype.malloc(SCLASS)
+ s = S()
s.x = n
- gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s)
- as_num = rffi.cast(lltype.Signed, gcref)
- gcref2 = rffi.cast(llmemory.GCREF, as_num)
- t = lltype.cast_opaque_ptr(rclass.OBJECTPTR, gcref2)
- u = lltype.cast_pointer(lltype.Ptr(SCLASS), t)
+ ls = cast_instance_to_base_ptr(s)
+ as_num = rffi.cast(lltype.Signed, ls)
+ # --- around this point, only 'as_num' is passed
+ t = rffi.cast(rclass.OBJECTPTR, as_num)
+ u = cast_base_ptr_to_instance(S, t)
return u.x
res = interpret(f, [123])
assert res == 123
Modified: pypy/branch/virtual-forcing/pypy/rpython/rtyper.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/rpython/rtyper.py (original)
+++ pypy/branch/virtual-forcing/pypy/rpython/rtyper.py Sun Dec 6 20:04:30 2009
@@ -133,15 +133,22 @@
return result
def get_type_for_typeptr(self, typeptr):
+ search = typeptr._obj
try:
- return self.type_for_typeptr[typeptr._obj]
+ return self.type_for_typeptr[search]
except KeyError:
- # rehash the dictionary
+ # rehash the dictionary, and perform a non-dictionary scan
+ # for the case of ll2ctypes typeptr
+ found = None
type_for_typeptr = {}
for key, value in self.type_for_typeptr.items():
type_for_typeptr[key] = value
+ if key == search:
+ found = value
self.type_for_typeptr = type_for_typeptr
- return self.type_for_typeptr[typeptr._obj]
+ if found is None:
+ raise KeyError(search)
+ return found
def makekey(self, s_obj):
return pair(self.type_system, s_obj).rtyper_makekey(self)
More information about the Pypy-commit
mailing list