Commits

Antonio Cuni committed 27446ea

force the raw buffer if we detect an invalid write

Comments (0)

Files changed (4)

pypy/jit/backend/llgraph/runner.py

 """
 
 from pypy.rlib.unroll import unrolling_iterable
-from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.objectmodel import we_are_translated, Symbolic
 from pypy.rlib.jit_hooks import LOOP_RUN_CONTAINER
-from pypy.rpython.lltypesystem import lltype, llmemory, rclass
+from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rffi
 from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.llinterp import LLInterpreter
 from pypy.jit.metainterp import history
             token = 's'
         else:
             token = '?'
-        return self.getdescr(size, token)
+        # so that unpack_arraydescr_size returns something sensible
+        width = rffi.sizeof(A.OF)
+        if isinstance(width, Symbolic):
+            # we cannot compute anything reasonable, so we just make up a size
+            width = 8 * len(A.OF._flds)
+        return self.getdescr(size, token, width=width)
 
     def unpack_arraydescr_size(self, arraydescr):
         # so far this is used only by optimizeopt.virtualize for
-        # {GET,SET}ARRAYITEM_RAW: it's hard (if not impossible) to compute
-        # precise values, so we just return dummy ones for now
-        return 0, 8, True
+        # {GET,SET}ARRAYITEM_RAW: for now we just return dummy values for
+        # basesize and is_signed
+        return 0, arraydescr.width, True
 
     # ---------- the backend-dependent operations ----------
 

pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py

         """
         self.optimize_loop(ops, expected)
 
+    def test_virtual_raw_malloc_invalid_write_force(self):
+        ops = """
+        [i1]
+        i2 = call('malloc', 10, descr=raw_malloc_descr)
+        setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
+        label('foo') # we expect the buffer to be forced *after* the label
+        setarrayitem_raw(i2, 2, 456, descr=rawarraydescr_char) # overlap!
+        call('free', i2, descr=raw_free_descr)
+        jump(i1)
+        """
+        expected = """
+        [i1]
+        label('foo')
+        i2 = call('malloc', 10, descr=raw_malloc_descr)
+        setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
+        setarrayitem_raw(i2, 2, 456, descr=rawarraydescr_char)
+        call('free', i2, descr=raw_free_descr)
+        jump(i1)
+        """
+        self.optimize_loop(ops, expected)
+
     def test_duplicate_getfield_1(self):
         ops = """
         [p1, p2]

pypy/jit/metainterp/optimizeopt/test/test_util.py

 
     rawarraydescr = cpu.arraydescrof(lltype.Array(lltype.Signed,
                                                   hints={'nolength': True}))
+    rawarraydescr_char = cpu.arraydescrof(lltype.Array(lltype.Char,
+                                                       hints={'nolength': True}))
+
 
     for _name, _os in [
         ('strconcatdescr',               'OS_STR_CONCAT'),

pypy/jit/metainterp/optimizeopt/virtualize.py

             optforce.emit_operation(op)
 
     def setitem_raw(self, offset, length, descr, value):
-        try:
-            self.buffer.write_value(offset, length, descr, value)
-        except InvalidRawOperation:
-            XXX
+        self.buffer.write_value(offset, length, descr, value)
 
     def getitem_raw(self, offset, length, descr):
         try:
             if indexbox is not None:
                 offset, itemsize, descr = self._unpack_arrayitem_raw_op(op, indexbox)
                 itemvalue = self.getvalue(op.getarg(2))
-                value.setitem_raw(offset, itemsize, descr, itemvalue)
+                try:
+                    value.setitem_raw(offset, itemsize, descr, itemvalue)
+                except InvalidRawOperation:
+                    box = value.force_box(self)
+                    op.setarg(0, box)
+                    self.emit_operation(op)
                 return
         value.ensure_nonnull()
         self.emit_operation(op)
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.