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