[pypy-commit] pypy canraise-assertionerror: branch to experiment with canraise not raising for assertion error

fijal pypy.commits at gmail.com
Thu Nov 2 06:38:38 EDT 2017


Author: fijal
Branch: canraise-assertionerror
Changeset: r92903:904915e5425e
Date: 2017-11-02 11:37 +0100
http://bitbucket.org/pypy/pypy/changeset/904915e5425e/

Log:	branch to experiment with canraise not raising for assertion error

diff --git a/rpython/translator/backendopt/canraise.py b/rpython/translator/backendopt/canraise.py
--- a/rpython/translator/backendopt/canraise.py
+++ b/rpython/translator/backendopt/canraise.py
@@ -1,6 +1,9 @@
 from rpython.rtyper.lltypesystem.lloperation import LL_OPERATIONS
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rtyper import rclass
 from rpython.tool.ansi_print import AnsiLogger
 from rpython.translator.backendopt import graphanalyze
+from rpython.flowspace import model as flowmodel
 
 log = AnsiLogger("canraise")
 
@@ -8,6 +11,14 @@
 class RaiseAnalyzer(graphanalyze.BoolGraphAnalyzer):
     ignore_exact_class = None
 
+    def __init__(self, translator):
+        graphanalyze.BoolGraphAnalyzer.__init__(self, translator)
+        ed = translator.rtyper.exceptiondata
+        self.ll_assert_error = ed.get_standard_ll_exc_instance_by_class(
+            AssertionError)
+        self.ll_not_impl_error = ed.get_standard_ll_exc_instance_by_class(
+            NotImplementedError)
+
     def do_ignore_memory_error(self):
         self.ignore_exact_class = MemoryError
 
@@ -25,6 +36,12 @@
     analyze_exceptblock = None    # don't call this
 
     def analyze_exceptblock_in_graph(self, graph, block, seen=None):
+        def producer(block, v):
+            for op in block.operations:
+                if op.result is v:
+                    return op
+            assert False
+
         if self.ignore_exact_class is not None:
             from rpython.translator.backendopt.ssa import DataFlowFamilyBuilder
             dff = DataFlowFamilyBuilder(graph)
@@ -38,7 +55,34 @@
                         # it doesn't count.  We'll see the place that really
                         # raises the exception in the first place.
                         return False
-        return True
+        # find all the blocks leading to the raise block
+        blocks = []
+        for candidate in graph.iterblocks():
+            if len(candidate.exits) != 1:
+                continue
+            if candidate.exits[0].target is block:
+                blocks.append(candidate)
+        ignored = 0
+        import pdb
+        pdb.set_trace()
+        for preblock in blocks:
+            exc_val = preblock.exits[0].args[1]
+            if isinstance(exc_val, flowmodel.Constant):
+                exc = exc_val.value
+            else:
+                # find the producer
+                op = producer(preblock, exc_val)
+                if op.opname == 'cast_pointer':
+                    exc_val = op.args[0]
+                    op = producer(preblock, exc_val)
+                if op.opname != 'same_as':
+                    # something strange, return True
+                    return True
+                exc = op.args[0].value
+            p = lltype.cast_pointer(rclass.OBJECTPTR, exc)
+            if p == self.ll_assert_error or p == self.ll_not_impl_error:
+                ignored += 1
+        return ignored < len(blocks)
 
     # backward compatible interface
     def can_raise(self, op, seen=None):
diff --git a/rpython/translator/backendopt/test/test_canraise.py b/rpython/translator/backendopt/test/test_canraise.py
--- a/rpython/translator/backendopt/test/test_canraise.py
+++ b/rpython/translator/backendopt/test/test_canraise.py
@@ -1,7 +1,8 @@
+from rpython.conftest import option
+from rpython.rtyper.lltypesystem import rffi
 from rpython.translator.translator import TranslationContext, graphof
 from rpython.translator.backendopt.canraise import RaiseAnalyzer
 from rpython.translator.backendopt.all import backend_optimizations
-from rpython.conftest import option
 
 class TestCanRaise(object):
     def translate(self, func, sig):
@@ -253,3 +254,48 @@
         ra.do_ignore_memory_error()     # but it's potentially a KeyError
         result = ra.analyze_direct_call(graphof(t, h))
         assert result
+
+    def test_charp2str(self):
+        def f(a):
+            return len(rffi.charp2str(a))
+
+        t, ra = self.translate(f, [rffi.CCHARP])
+        ra.do_ignore_memory_error()
+        result = ra.analyze_direct_call(graphof(t, f))
+        assert not result # ignore AssertionError
+
+    def test_calls_raise_not_impl(self):
+        def raising():
+            raise NotImplementedError
+
+        def not_raising():
+            pass
+
+        def f(a):
+            if a == 15:
+                raising()
+            else:
+                not_raising()
+
+        t, ra = self.translate(f, [int])
+        ra.do_ignore_memory_error()
+        result = ra.analyze_direct_call(graphof(t, f))
+        assert not result # ignore AssertionError
+
+    def test_calls_raise_assertion_error(self):
+        def raising():
+            assert False
+
+        def not_raising():
+            pass
+
+        def f(a):
+            if a == 15:
+                raising()
+            else:
+                not_raising()
+
+        t, ra = self.translate(f, [int])
+        ra.do_ignore_memory_error()
+        result = ra.analyze_direct_call(graphof(t, f))
+        assert not result # ignore AssertionError


More information about the pypy-commit mailing list