Author: Armin Rigo <[email protected]>
Branch: remove-globals-in-jit
Changeset: r58929:dc6380fc4033
Date: 2012-11-15 17:30 +0100
http://bitbucket.org/pypy/pypy/changeset/dc6380fc4033/

Log:    Fix exceptions.

diff --git a/pypy/jit/backend/llsupport/jitframe.py 
b/pypy/jit/backend/llsupport/jitframe.py
--- a/pypy/jit/backend/llsupport/jitframe.py
+++ b/pypy/jit/backend/llsupport/jitframe.py
@@ -20,6 +20,12 @@
     # For the front-end: a GCREF for the savedata
     ('jf_savedata', llmemory.GCREF),
 
+    # For GUARD_(NO)_EXCEPTION and GUARD_NOT_FORCED: the exception we
+    # got.  (Note that in case of a regular FINISH generated from
+    # RPython code that finishes the function with an exception, the
+    # exception is not stored there, but in jf_values[0].ref.)
+    ('jf_guard_exc', llmemory.GCREF),
+
     # All values are stored in the following array, for now not very
     # compactly on 32-bit machines.
     ('jf_values', lltype.Array(VALUEUNION)))
diff --git a/pypy/jit/backend/llsupport/llmodel.py 
b/pypy/jit/backend/llsupport/llmodel.py
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -39,8 +39,6 @@
             self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT,
                                                              'typeptr',
                                                         translate_support_code)
-        self._setup_prebuilt_error('ovf', OverflowError)
-        self._setup_prebuilt_error('zer', ZeroDivisionError)
         if translate_support_code:
             self._setup_exception_handling_translated()
         else:
@@ -55,21 +53,6 @@
     def setup(self):
         pass
 
-    def _setup_prebuilt_error(self, prefix, Class):
-        if self.rtyper is not None:   # normal case
-            bk = self.rtyper.annotator.bookkeeper
-            clsdef = bk.getuniqueclassdef(Class)
-            ll_inst = self.rtyper.exceptiondata.get_standard_ll_exc_instance(
-                self.rtyper, clsdef)
-        else:
-            # for tests, a random emulated ll_inst will do
-            ll_inst = lltype.malloc(rclass.OBJECT)
-            ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE,
-                                            immortal=True)
-        setattr(self, '_%s_error_vtable' % prefix,
-                llmemory.cast_ptr_to_adr(ll_inst.typeptr))
-        setattr(self, '_%s_error_inst' % prefix, ll_inst)
-
 
     def _setup_exception_handling_untranslated(self):
         # for running un-translated only, all exceptions occurring in the
@@ -208,10 +191,8 @@
         return rffi.cast(lltype.Signed, f)
 
     def grab_exc_value(self, deadframe):
-        xxx
-        exc = self.saved_exc_value
-        self.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO)
-        return exc
+        deadframe = lltype.cast_opaque_ptr(jitframe.DEADFRAMEPTR, deadframe)
+        return deadframe.jf_guard_exc
 
     def free_loop_and_bridges(self, compiled_loop_token):
         AbstractCPU.free_loop_and_bridges(self, compiled_loop_token)
@@ -295,18 +276,6 @@
         return ffisupport.calldescr_dynamic_for_tests(self, atypes, rtype,
                                                       abiname)
 
-    def get_overflow_error(self):
-        ovf_vtable = self.cast_adr_to_int(self._ovf_error_vtable)
-        ovf_inst = lltype.cast_opaque_ptr(llmemory.GCREF,
-                                          self._ovf_error_inst)
-        return ovf_vtable, ovf_inst
-
-    def get_zero_division_error(self):
-        zer_vtable = self.cast_adr_to_int(self._zer_error_vtable)
-        zer_inst = lltype.cast_opaque_ptr(llmemory.GCREF,
-                                          self._zer_error_inst)
-        return zer_vtable, zer_inst
-
     def get_latest_descr(self, deadframe):
         deadframe = lltype.cast_opaque_ptr(jitframe.DEADFRAMEPTR, deadframe)
         descr = deadframe.jf_descr
diff --git a/pypy/jit/backend/x86/assembler.py 
b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -2093,8 +2093,16 @@
         for gpr in range(self.cpu.NUM_REGS-1, -1, -1):
             mc.PUSH_r(gpr)
 
-        # ebx/rbx is callee-save in both i386 and x86-64
-        mc.MOV_rr(ebx.value, esp.value)
+        if exc:
+            # We might have an exception pending.  Load it into ebx
+            # (this is a register saved across calls, both if 32 or 64)
+            mc.MOV(ebx, heap(self.cpu.pos_exc_value()))
+            mc.MOV(heap(self.cpu.pos_exception()), imm0)
+            mc.MOV(heap(self.cpu.pos_exc_value()), imm0)
+
+        # Load the current esp value into edi.  On 64-bit, this is the
+        # argument.  On 32-bit, it will be pushed as argument below.
+        mc.MOV_rr(edi.value, esp.value)
 
         if withfloats:
             # Push all float registers
@@ -2102,9 +2110,6 @@
             for i in range(self.cpu.NUM_REGS):
                 mc.MOVSD_sx(8*i, i)
 
-        if exc:
-            mc.UD2()     # XXX
-
         # the following call saves all values from the stack and from
         # registers to a fresh new deadframe object.
         # Note that the registers are saved so far in esi[0] to esi[7],
@@ -2113,18 +2118,20 @@
         # bytecode, pushed just before by the CALL instruction written by
         # generate_quick_failure().
 
-        # XXX
         if IS_X86_32:
             mc.SUB_ri(esp.value, 3*WORD)    # for stack alignment
-            mc.PUSH_r(ebx.value)
-        elif IS_X86_64:
-            mc.MOV_rr(edi.value, ebx.value)
-        else:
-            raise AssertionError("Shouldn't happen")
+            mc.PUSH_r(edi.value)
 
         mc.CALL(imm(failure_recovery_func))
         # returns in eax the deadframe object
 
+        if exc:
+            # save ebx into 'jf_guard_exc'
+            offset, size = symbolic.get_field_token(
+                jitframe.DEADFRAME, 'jf_guard_exc',
+                self.cpu.translate_support_code)
+            mc.MOV_mr((eax.value, offset), ebx.value)
+
         # now we return from the complete frame, which starts from
         # _call_header_with_stack_check().  The LEA in _call_footer below
         # throws away most of the frame, including all the PUSHes that we
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to