[pypy-svn] r66807 - in pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Thu Aug 13 20:40:48 CEST 2009


Author: arigo
Date: Thu Aug 13 20:40:47 2009
New Revision: 66807

Modified:
   pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/executor.py
   pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/resoperation.py
   pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/test/test_exception.py
Log:
Add the GUARD_(NO)_OVERFLOW operations in the frontend.


Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/executor.py
==============================================================================
--- pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/executor.py	(original)
+++ pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/executor.py	Thu Aug 13 20:40:47 2009
@@ -189,10 +189,11 @@
     try:
         z = ovfcheck(x + y)
     except OverflowError:
-        cpu.set_overflow_error()
+        ovf = True
         z = 0
     else:
-        cpu.clear_exception()
+        ovf = False
+    cpu.set_overflow_flag(ovf)
     return BoxInt(z)
 
 def do_int_sub_ovf(cpu, args, descr=None):
@@ -201,10 +202,11 @@
     try:
         z = ovfcheck(x - y)
     except OverflowError:
-        cpu.set_overflow_error()
+        ovf = True
         z = 0
     else:
-        cpu.clear_exception()
+        ovf = False
+    cpu.set_overflow_flag(ovf)
     return BoxInt(z)
 
 def do_int_mul_ovf(cpu, args, descr=None):
@@ -213,10 +215,11 @@
     try:
         z = ovfcheck(x * y)
     except OverflowError:
-        cpu.set_overflow_error()
+        ovf = True
         z = 0
     else:
-        cpu.clear_exception()
+        ovf = False
+    cpu.set_overflow_flag(ovf)
     return BoxInt(z)
 
 # ____________________________________________________________

Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/pyjitpl.py	Thu Aug 13 20:40:47 2009
@@ -232,7 +232,8 @@
         exec py.code.Source('''
             @arguments("box", "box")
             def opimpl_%s(self, b1, b2):
-                return self.execute_with_exc(rop.%s, [b1, b2])
+                self.execute(rop.%s, [b1, b2])
+                return self.metainterp.handle_overflow_error()
         ''' % (_opimpl, _opimpl.upper())).compile()
 
     for _opimpl in ['int_is_true', 'int_neg', 'int_invert', 'bool_not',
@@ -1330,6 +1331,9 @@
             self.framestack[-1].dont_follow_jump()
         elif opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION:
             self.handle_exception()
+        elif opnum == rop.GUARD_NO_OVERFLOW:   # an overflow now detected
+            self.cpu.set_overflow_error()
+            self.raise_this_error()
 
     def compile(self, original_boxes, live_arg_boxes, start):
         num_green_args = self.staticdata.num_green_args
@@ -1523,6 +1527,17 @@
             frame.generate_guard(frame.pc, rop.GUARD_NO_EXCEPTION, None, [])
             return False
 
+    def handle_overflow_error(self):
+        frame = self.framestack[-1]
+        if self.cpu.get_overflow_flag():
+            self.cpu.set_overflow_flag(False)
+            frame.generate_guard(frame.pc, rop.GUARD_OVERFLOW, None, [])
+            self.cpu.set_overflow_error()
+            return self.raise_this_error()
+        else:
+            frame.generate_guard(frame.pc, rop.GUARD_NO_OVERFLOW, None, [])
+            return False
+
     def rebuild_state_after_failure(self, resumedescr, newboxes):
         if not we_are_translated():
             self._debug_history.append(['guard_failure', None, None])

Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/resoperation.py	Thu Aug 13 20:40:47 2009
@@ -73,6 +73,10 @@
         return (self.opnum == rop.GUARD_EXCEPTION or
                 self.opnum == rop.GUARD_NO_EXCEPTION)
 
+    def is_guard_overflow(self):
+        return (self.opnum == rop.GUARD_OVERFLOW or
+                self.opnum == rop.GUARD_NO_OVERFLOW)
+
     def is_always_pure(self):
         return rop._ALWAYS_PURE_FIRST <= self.opnum <= rop._ALWAYS_PURE_LAST
 
@@ -108,6 +112,8 @@
     '_GUARD_FOLDABLE_LAST',
     'GUARD_NO_EXCEPTION',
     'GUARD_EXCEPTION',
+    'GUARD_NO_OVERFLOW',
+    'GUARD_OVERFLOW',
     '_GUARD_LAST', # ----- end of guard operations -----
 
     '_NOSIDEEFFECT_FIRST', # ----- start of no_side_effect operations -----
@@ -190,13 +196,13 @@
     '_CANRAISE_FIRST', # ----- start of can_raise operations -----
     'CALL',
     'OOSEND',                     # ootype operation
-    #
-    '_OVF_FIRST',
+    '_CANRAISE_LAST', # ----- end of can_raise operations -----
+
+    '_OVF_FIRST', # ----- start of is_ovf operations -----
     'INT_ADD_OVF',
     'INT_SUB_OVF',
     'INT_MUL_OVF',
-    '_OVF_LAST',
-    '_CANRAISE_LAST', # ----- end of can_raise operations -----
+    '_OVF_LAST', # ----- end of is_ovf operations -----
     '_LAST',     # for the backend to add more internal operations
 ]
 

Modified: pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/test/test_exception.py
==============================================================================
--- pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/test/test_exception.py	(original)
+++ pypy/branch/pyjitpl5-guardovf/pypy/jit/metainterp/test/test_exception.py	Thu Aug 13 20:40:47 2009
@@ -385,6 +385,22 @@
         res = self.meta_interp(f, [1])
         assert res == expected
 
+    def test_int_ovf_common(self):
+        import sys
+        myjitdriver = JitDriver(greens = [], reds = ['n'])
+        def f(n):
+            while 1:
+                myjitdriver.can_enter_jit(n=n)
+                myjitdriver.jit_merge_point(n=n)
+                try:
+                    n = ovfcheck(n + sys.maxint)
+                except OverflowError:
+                    n -= 1
+                else:
+                    return n - 2000
+        res = self.meta_interp(f, [10], repeat=7)
+        assert res == sys.maxint - 2000
+
     def test_int_mod_ovf_zer(self):
         def f(x, y):
             try:



More information about the Pypy-commit mailing list