[pypy-svn] r45589 - in pypy/dist/pypy/translator: cli cli/test js jvm oosupport

antocuni at codespeak.net antocuni at codespeak.net
Fri Aug 10 21:10:54 CEST 2007


Author: antocuni
Date: Fri Aug 10 21:10:52 2007
New Revision: 45589

Modified:
   pypy/dist/pypy/translator/cli/function.py
   pypy/dist/pypy/translator/cli/test/runtest.py
   pypy/dist/pypy/translator/cli/test/test_exception.py
   pypy/dist/pypy/translator/js/function.py
   pypy/dist/pypy/translator/jvm/node.py
   pypy/dist/pypy/translator/oosupport/function.py
Log:
let .NET to propagate automatically not catched exceptions. Probably
this should be enabled also for genjvm.



Modified: pypy/dist/pypy/translator/cli/function.py
==============================================================================
--- pypy/dist/pypy/translator/cli/function.py	(original)
+++ pypy/dist/pypy/translator/cli/function.py	Fri Aug 10 21:10:52 2007
@@ -20,10 +20,15 @@
 
 class Function(OOFunction, Node, CLIBaseGenerator):
 
+    auto_propagate_exceptions = True
+
     def __init__(self, *args, **kwargs):
         OOFunction.__init__(self, *args, **kwargs)
+
+        if hasattr(self.db.genoo, 'exceptiontransformer'):
+            self.auto_propagate_exceptions = False
+        
         namespace = getattr(self.graph.func, '_namespace_', None)
-        str
         if namespace:
             if '.' in namespace:
                 self.namespace, self.classname = namespace.rsplit('.', 1)
@@ -94,12 +99,16 @@
             self.load(return_var)
         self.ilasm.opcode('ret')
 
-    def begin_try(self):
-        self.ilasm.begin_try()
-
-    def end_try(self, target_label):
-        self.ilasm.leave(target_label)
-        self.ilasm.end_try()
+    def begin_try(self, cond):
+        if cond:
+            self.ilasm.begin_try()
+
+    def end_try(self, target_label, cond):
+        if cond:
+            self.ilasm.leave(target_label)
+            self.ilasm.end_try()
+        else:
+            self.ilasm.branch(target_label)
 
     def begin_catch(self, llexitcase):
         ll_meta_exc = llexitcase

Modified: pypy/dist/pypy/translator/cli/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/runtest.py	(original)
+++ pypy/dist/pypy/translator/cli/test/runtest.py	Fri Aug 10 21:10:52 2007
@@ -274,10 +274,10 @@
             raise res
         return res
 
-    def interpret_raises(self, exception, fn, args, exctrans=False):
+    def interpret_raises(self, exception, fn, args, backendopt=True, exctrans=False):
         import exceptions # needed by eval
         try:
-            self.interpret(fn, args, exctrans=exctrans)
+            self.interpret(fn, args, backendopt=backendopt, exctrans=exctrans)
         except ExceptionWrapper, ex:
             assert issubclass(eval(ex.class_name), exception)
         else:

Modified: pypy/dist/pypy/translator/cli/test/test_exception.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_exception.py	(original)
+++ pypy/dist/pypy/translator/cli/test/test_exception.py	Fri Aug 10 21:10:52 2007
@@ -62,5 +62,20 @@
             return obj.foo()
         assert self.interpret(fn, [0]) == 42
 
+    def test_missing_handler(self):
+        def foo(x):
+            if x:
+                raise ValueError
+        
+        def fn(x):
+            try:
+                foo(x)
+            except ValueError:
+                raise
+            return 42
+        assert self.interpret(fn, [0], backendopt=False) == 42
+        self.interpret_raises(ValueError, fn, [1], backendopt=False)
+
+
 class TestCliExceptionTransformer(TestCliException):
     use_exception_transformer = True

Modified: pypy/dist/pypy/translator/js/function.py
==============================================================================
--- pypy/dist/pypy/translator/js/function.py	(original)
+++ pypy/dist/pypy/translator/js/function.py	Fri Aug 10 21:10:52 2007
@@ -195,9 +195,10 @@
     def render_raise_block(self, block):
         self.ilasm.throw(block.inputargs[1])
 
-    def end_try(self, target_label):
+    def end_try(self, target_label, cond):
         self.ilasm.jump_block(self.block_map[target_label])
-        self.ilasm.catch()
+        if cond:
+            self.ilasm.catch()
         #self.ilasm.close_branch()
 
     def record_ll_meta_exc(self, ll_meta_exc):
@@ -226,8 +227,9 @@
         self.ilasm.write_case(self.block_map[label])
         #self.ilasm.label(label)
 
-    def begin_try(self):
-        self.ilasm.begin_try()
+    def begin_try(self, cond):
+        if cond:
+            self.ilasm.begin_try()
 
     def clean_stack(self):
         self.ilasm.clean_stack()

Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py	(original)
+++ pypy/dist/pypy/translator/jvm/node.py	Fri Aug 10 21:10:52 2007
@@ -280,12 +280,14 @@
     def set_label(self, blocklbl):
         self.ilasm.mark(blocklbl)
 
-    def begin_try(self):
-        self.ilasm.begin_try()
+    def begin_try(self, cond):
+        if cond:
+            self.ilasm.begin_try()
 
-    def end_try(self, exit_label):
+    def end_try(self, exit_label, cond):
         self.ilasm.branch_unconditionally(exit_label)
-        self.ilasm.end_try()
+        if cond:
+            self.ilasm.end_try()
 
     def begin_catch(self, llexitcase):
         ll_meta_exc = llexitcase

Modified: pypy/dist/pypy/translator/oosupport/function.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/function.py	(original)
+++ pypy/dist/pypy/translator/oosupport/function.py	Fri Aug 10 21:10:52 2007
@@ -11,6 +11,8 @@
 
 
 class Function(object):
+    
+    auto_propagate_exceptions = False
 
     def __init__(self, db, graph, name = None, is_method = False, is_entrypoint = False):
         self.db = db
@@ -140,9 +142,17 @@
         for op in block.operations[:-1]:
             self._render_op(op)
 
+        anyHandler = False
+        for link in block.exits:
+            if link.exitcase is None:
+                continue
+            if not self._is_raise_block(link.target):
+                anyHandler = True
+        anyHandler = anyHandler or not self.auto_propagate_exceptions
+        
         # render the last one (if any!) and prepend a .try
         if block.operations:
-            self.begin_try()
+            self.begin_try(anyHandler)
             self._render_op(block.operations[-1])
 
         # search for the "default" block to be executed when no
@@ -150,7 +160,7 @@
         for link in block.exits:
             if link.exitcase is None:
                 self._setup_link(link)
-                self.end_try(self._get_block_name(link.target))
+                self.end_try(self._get_block_name(link.target), anyHandler)
                 break
         else:
             assert False, "No non-exceptional case from exc_handling block"
@@ -160,6 +170,8 @@
             if link.exitcase is None:
                 continue # see above
             assert issubclass(link.exitcase, py.builtin.BaseException)
+            if self._is_raise_block(link.target) and self.auto_propagate_exceptions:
+                continue # let the exception propagate
             ll_meta_exc = link.llexitcase
             self.record_ll_meta_exc(ll_meta_exc)
             self.begin_catch(link.llexitcase)



More information about the Pypy-commit mailing list