Commits

Armin Rigo  committed a0bf9b1

A hint that crashes if a variable is not proven local. Use it to check
that propagation of localness of the PyFrame works (which doesn't seem
to be the case right now).

  • Participants
  • Parent commits c7d3b90
  • Branches stm-gc

Comments (0)

Files changed (5)

File pypy/interpreter/pyframe.py

 
     # stack manipulation helpers
     def pushvalue(self, w_object):
+        hint(self, stm_assert_local=True)
         depth = self.valuestackdepth
         self.locals_stack_w[depth] = w_object
         self.valuestackdepth = depth + 1
 
     def popvalue(self):
+        hint(self, stm_assert_local=True)
         depth = self.valuestackdepth - 1
         assert depth >= self.pycode.co_nlocals, "pop from empty value stack"
         w_object = self.locals_stack_w[depth]

File pypy/translator/stm/localtracker.py

             # XXX we shouldn't get here, but we do translating the whole
             # pypy.  We should investigate at some point.  In the meantime
             # returning False is always safe.
+            self.reason = 'variable not in gsrc!'
             return False
         for src in srcs:
             if isinstance(src, SpaceOperation):
                     continue
                 if src.opname == 'hint' and 'stm_write' in src.args[1].value:
                     continue
+                self.reason = src
                 return False
             elif isinstance(src, Constant):
                 if src.value:     # a NULL pointer is still valid as local
+                    self.reason = src
                     return False
             elif src is None:
+                self.reason = 'found a None'
                 return False
             elif src == 'instantiate':
                 pass
             else:
                 raise AssertionError(repr(src))
         return True
+
+    def assert_local(self, variable, graph='?'):
+        if self.is_local(variable):
+            return   # fine
+        else:
+            raise AssertionError(
+                "assert_local() failed (%s, %s):\n%r" % (variable, graph,
+                                                         self.reason))

File pypy/translator/stm/test/test_localtracker.py

         for name, v in self.translator._seen_locals.items():
             if self.localtracker.is_local(v):
                 got_local_names.add(name)
+                self.localtracker.assert_local(v, 'foo')
         assert got_local_names == set(expected_names)
 
 

File pypy/translator/stm/test/test_transform.py

     pre_insert_stm_writebarrier(graph)
     if option.view:
         graph.show()
-    # weak test: check that there are exactly two stm_writebarrier inserted.
+    # weak test: check that there are exactly 3 stm_writebarrier inserted.
     # one should be for 'x.n = n', one should cover both field assignments
     # to the Z instance, and the 3rd one is in the block 'x.n *= 2'.
     sum = summary(graph)

File pypy/translator/stm/transform.py

         self.current_block = None
 
     def transform_graph(self, graph):
+        self.graph = graph
         for block in graph.iterblocks():
             self.transform_block(block)
+        del self.graph
 
     # ----------
 
             op = SpaceOperation('stm_writebarrier', [op.args[0]], op.result)
             self.stt_stm_writebarrier(newoperations, op)
             return
+        if 'stm_assert_local' in op.args[1].value:
+            self.localtracker.assert_local(op.args[0],
+                                           getattr(self, 'graph', None))
+            return
         newoperations.append(op)