Armin Rigo avatar Armin Rigo committed fa8c58f

'getarraysubstruct' support in the JIT

Comments (0)

Files changed (5)

rpython/jit/codewriter/jtransform.py

         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
 

rpython/jit/metainterp/test/test_rawmem.py

                                        '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

rpython/rtyper/lltypesystem/ll2ctypes.py

         # 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)

rpython/rtyper/lltypesystem/llmemory.py

         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:

rpython/rtyper/lltypesystem/test/test_ll2ctypes.py

     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...")
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.