Armin Rigo avatar Armin Rigo committed dc6380f

Fix exceptions.

Comments (0)

Files changed (3)

pypy/jit/backend/llsupport/jitframe.py

     # 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)))

pypy/jit/backend/llsupport/llmodel.py

             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:
     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
         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)
         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

pypy/jit/backend/x86/assembler.py

         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
             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],
         # 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
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.