Author: Armin Rigo <[email protected]>
Branch: jit-ordereddict
Changeset: r68553:fa8c58fec72a
Date: 2013-12-26 00:00 +0100
http://bitbucket.org/pypy/pypy/changeset/fa8c58fec72a/
Log: 'getarraysubstruct' support in the JIT
diff --git a/rpython/jit/codewriter/jtransform.py
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -644,6 +644,12 @@
return SpaceOperation('arraylen_gc', [op.args[0], arraydescr],
op.result)
+ def rewrite_op_getarraysubstruct(self, op):
+ ARRAY = op.args[0].concretetype.TO
+ assert ARRAY._gckind == 'raw'
+ assert ARRAY._hints.get('nolength') is True
+ return self.rewrite_op_direct_ptradd(op)
+
def _array_of_voids(self, ARRAY):
return ARRAY.OF == lltype.Void
diff --git a/rpython/jit/metainterp/test/test_rawmem.py
b/rpython/jit/metainterp/test/test_rawmem.py
--- a/rpython/jit/metainterp/test/test_rawmem.py
+++ b/rpython/jit/metainterp/test/test_rawmem.py
@@ -71,5 +71,25 @@
'raw_store': 1, 'raw_load': 1,
'finish': 1})
+ def test_getarraysubstruct(self):
+ A2 = lltype.Array(('a', lltype.Signed), ('b', lltype.Signed),
+ hints={'nolength': True})
+ p = lltype.malloc(A2, 10, flavor='raw', immortal=True, zero=True)
+ p[2].b = 689
+ def f(n, m):
+ p[n].a = 55
+ p[n].b = 44
+ p[4].b = 66
+ return p[m].b
+
+ # run with 'disable_optimizations' to prevent an error
+ # 'Symbolics cannot be compared!' in the optimizer for int_mul
+ res = self.interp_operations(f, [7, 2], disable_optimizations=True)
+ assert res == 689
+ res = self.interp_operations(f, [7, 4], disable_optimizations=True)
+ assert res == 66
+ res = self.interp_operations(f, [2, 2], disable_optimizations=True)
+ assert res == 44
+
class TestRawMem(RawMemTests, LLJitMixin):
pass
diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py
b/rpython/rtyper/lltypesystem/ll2ctypes.py
--- a/rpython/rtyper/lltypesystem/ll2ctypes.py
+++ b/rpython/rtyper/lltypesystem/ll2ctypes.py
@@ -403,7 +403,12 @@
# bigger structure at once
parent, parentindex = lltype.parentlink(container)
if parent is not None:
- convert_struct(parent)
+ if isinstance(parent, lltype._struct):
+ convert_struct(parent)
+ elif isinstance(parent, lltype._array):
+ convert_array(parent)
+ else:
+ raise AssertionError(type(parent))
return
# regular case: allocate a new ctypes Structure of the proper type
cls = get_ctypes_type(STRUCT)
diff --git a/rpython/rtyper/lltypesystem/llmemory.py
b/rpython/rtyper/lltypesystem/llmemory.py
--- a/rpython/rtyper/lltypesystem/llmemory.py
+++ b/rpython/rtyper/lltypesystem/llmemory.py
@@ -553,6 +553,12 @@
if isinstance(ofs, FieldOffset) and ofs.TYPE is self.adr.ptr._TYPE.TO:
fieldadr = getattr(self.adr.ptr, ofs.fldname)
return AddressAsInt(cast_ptr_to_adr(fieldadr))
+ if (isinstance(ofs, ItemOffset) and
+ isinstance(self.adr.ptr._TYPE.TO, lltype.Array) and
+ self.adr.ptr._TYPE.TO._hints.get('nolength') is True and
+ ofs.TYPE is self.adr.ptr._TYPE.TO.OF):
+ itemadr = self.adr.ptr[ofs.repeat]
+ return AddressAsInt(cast_ptr_to_adr(itemadr))
return NotImplemented
def __repr__(self):
try:
diff --git a/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py
b/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py
--- a/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py
+++ b/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py
@@ -1433,3 +1433,14 @@
def test_llgcopaque_eq(self):
assert _llgcopaque(1) != None
assert _llgcopaque(0) == None
+
+ def test_array_of_struct(self):
+ A2 = lltype.Array(('a', lltype.Signed), ('b', lltype.Signed))
+ a = lltype.malloc(A2, 10, flavor='raw')
+ a[3].b = 42
+ ac = lltype2ctypes(a[3])
+ assert ac.contents.b == 42
+ ac.contents.a = 17
+ assert a[3].a == 17
+ #lltype.free(a, flavor='raw')
+ py.test.skip("free() not working correctly here...")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit