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

Reply via email to