[pypy-svn] r62687 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test

fijal at codespeak.net fijal at codespeak.net
Sat Mar 7 11:14:18 CET 2009


Author: fijal
Date: Sat Mar  7 11:14:17 2009
New Revision: 62687

Modified:
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py
Log:
make exception work (not yet translated). I'm not sure about the solution,
but it seems we have to copy exception on side when we encounter it
(since handling exception is just more rpython code)


Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	Sat Mar  7 11:14:17 2009
@@ -30,24 +30,23 @@
         self.mc2 = None
         self.rtyper = cpu.rtyper
         self.malloc_func_addr = 0
-        if translate_support_code:
-            self._exception_data = lltype.nullptr(rffi.CArray(lltype.Signed))
-            self._exception_addr = 0
-            # patched later, after exc transform
-        else:
-            self._exception_data = lltype.malloc(rffi.CArray(lltype.Signed), 2,
-                                                 zero=True, flavor='raw')
-            self._exception_addr = cpu.cast_ptr_to_int(self._exception_data)
+        self._exception_data = lltype.nullptr(rffi.CArray(lltype.Signed))
+        self._exception_addr = 0
 
     def make_sure_mc_exists(self):
         if self.mc is None:
             # we generate the loop body in 'mc'
             # 'mc2' is for guard recovery code
-            # XXX we should catch the real one, somehow
             self._exception_data = lltype.malloc(rffi.CArray(lltype.Signed), 2,
                                                  zero=True, flavor='raw')
             self._exception_addr = self.cpu.cast_ptr_to_int(
                 self._exception_data)
+            # a backup, in case our exception can be somehow mangled,
+            # by a handling code
+            self._exception_bck = lltype.malloc(rffi.CArray(lltype.Signed), 2,
+                                                 zero=True, flavor='raw')
+            self._exception_bck_addr = self.cpu.cast_ptr_to_int(
+                self._exception_bck)
             self.mc = codebuf.MachineCodeBlock(self.MC_SIZE)
             self.mc2 = codebuf.MachineCodeBlock(self.MC_SIZE)
             self.generic_return_addr = self.assemble_generic_return()
@@ -221,10 +220,10 @@
                     self.mc2.MOV(stack_pos(stacklocs[i]), loc)
             ovf_error_vtable = self.cpu.cast_adr_to_int(self._ovf_error_vtable)
             self.mc2.MOV(eax, imm(ovf_error_vtable))
-            self.mc2.MOV(addr_add(imm(self._exception_addr), imm(0)), eax)
+            self.mc2.MOV(addr_add(imm(self._exception_bck_addr), imm(0)), eax)
             ovf_error_instance = self.cpu.cast_adr_to_int(self._ovf_error_inst)
             self.mc2.MOV(eax, imm(ovf_error_instance))
-            self.mc2.MOV(addr_add(imm(self._exception_addr), imm(WORD)), eax)
+            self.mc2.MOV(addr_add(imm(self._exception_bck_addr), imm(WORD)),eax)
             self.mc2.PUSH(esp)           # frame address
             self.mc2.PUSH(imm(index))    # index of guard that failed
             self.mc2.CALL(rel32(self.cpu.get_failure_recovery_func_addr()))
@@ -501,6 +500,16 @@
             loc = locs[i]
             if isinstance(loc, REG):
                 self.mc2.MOV(stack_pos(stacklocs[i]), loc)
+        if (guard_op.opnum == rop.GUARD_EXCEPTION or
+            guard_op.opnum == rop.GUARD_NO_EXCEPTION):
+            self.mc2.MOV(eax, heap(self._exception_addr))
+            self.mc2.MOV(heap(self._exception_bck_addr), eax)
+            self.mc2.MOV(eax, addr_add(imm(self._exception_addr), imm(WORD)))
+            self.mc2.MOV(addr_add(imm(self._exception_bck_addr), imm(WORD)),
+                         eax)
+            # clean up the original exception, we don't want
+            # to enter more rpython code with exc set
+            self.mc2.MOV(heap(self._exception_addr), imm(0))
         self.mc2.PUSH(esp)           # frame address
         self.mc2.PUSH(imm(index))    # index of guard that failed
         self.mc2.CALL(rel32(self.cpu.get_failure_recovery_func_addr()))

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py	Sat Mar  7 11:14:17 2009
@@ -136,12 +136,20 @@
         self.metainterp = metainterp
 
     def get_exception(self):
-        res = self.assembler._exception_data[0]
-        self.assembler._exception_data[0] = 0
-        return res
+        self.assembler.make_sure_mc_exists()
+        return self.assembler._exception_bck[0]
 
     def get_exc_value(self):
-        return self.cast_int_to_gcref(self.assembler._exception_data[1])
+        return self.cast_int_to_gcref(self.assembler._exception_bck[1])
+
+    def clear_exception(self):
+        self.assembler._exception_bck[0] = 0
+
+    def set_overflow_error(self):
+        ovf_vtable = self.cast_adr_to_int(self.assembler._ovf_error_vtable)
+        ovf_inst = self.cast_adr_to_int(self.assembler._ovf_error_inst)
+        self.assembler._exception_bck[0] = ovf_vtable
+        self.assembler._exception_bck[1] = ovf_inst
 
 #     def execute_operation(self, opnum, valueboxes, result_type):
 #         xxx
@@ -543,16 +551,10 @@
         else:
             self.return_value_type = INT
         result = self.execute_operations_in_new_frame('call', mp, args)
-        if not we_are_translated():
-            exc = self.get_exception()
-            if exc:
-                 TP = lltype.Ptr(rclass.OBJECT_VTABLE)
-                 TP_V = lltype.Ptr(rclass.OBJECT)
-                 exc_t_a = self.cast_int_to_adr(exc)
-                 exc_type = llmemory.cast_adr_to_ptr(exc_t_a, TP)
-                 exc_v_a = self.get_exc_value()
-                 exc_val = lltype.cast_opaque_ptr(TP_V, exc_v_a)
-                 raise LLException(exc_type, exc_val)
+        # XXX I'm not sure if we're supposed to do that here, probably only
+        #     in assembler
+        self.assembler._exception_bck[0] = self.assembler._exception_data[0]
+        self.assembler._exception_bck[1] = self.assembler._exception_data[1]
         return result
 
     # ------------------- helpers and descriptions --------------------

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py	Sat Mar  7 11:14:17 2009
@@ -537,3 +537,6 @@
         assert x.value == 142
         s = execute(cpu, rop.NEWSTR, [BoxInt(8)])
         assert len(s.getptr(lltype.Ptr(rstr.STR)).chars) == 8
+        # XXX cannot work without rtyper
+        #s = execute(cpu, rop.INT_MUL_OVF, [BoxInt(sys.maxint/2), BoxInt(10)])
+        #assert cpu.get_exception()



More information about the Pypy-commit mailing list