[pypy-svn] r64647 - in pypy/branch/pyjitpl5-simplify/pypy: jit/backend/minimal jit/backend/test jit/backend/x86 jit/backend/x86/test jit/metainterp jit/metainterp/test rlib

antocuni at codespeak.net antocuni at codespeak.net
Fri Apr 24 18:31:30 CEST 2009


Author: antocuni
Date: Fri Apr 24 18:31:27 2009
New Revision: 64647

Modified:
   pypy/branch/pyjitpl5-simplify/pypy/jit/backend/minimal/runner.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/conftest.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/runner.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/test_random.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_runner.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_zrpy_exception.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/simple_optimize.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_exception.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_zrpy_virtualizable.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py
   pypy/branch/pyjitpl5-simplify/pypy/rlib/rcoroutine.py
Log:
merge the pyjitpl5 branch back to pyjitpl5-simplify:
  svn merge svn+ssh://codespeak.net/svn/pypy/branch/pyjitpl5/ -r64569:HEAD

    ------------------------------------------------------------------------
    r64569 | fijal | 2009-04-22 16:53:56 +0200 (Wed, 22 Apr 2009) | 2 lines

    Copy this branch in order to stabilize

    ------------------------------------------------------------------------
    r64570 | fijal | 2009-04-22 17:14:22 +0200 (Wed, 22 Apr 2009) | 3 lines

    a fix for the case when there is a longer chain of suboperations, finalized
    by fail. Still trying to find the test which explores that.

    ------------------------------------------------------------------------
    r64571 | fijal | 2009-04-22 17:21:17 +0200 (Wed, 22 Apr 2009) | 2 lines

    a passing test

    ------------------------------------------------------------------------
    r64572 | fijal | 2009-04-22 17:22:33 +0200 (Wed, 22 Apr 2009) | 2 lines

    add a comment what is this doing

    ------------------------------------------------------------------------
    r64574 | fijal | 2009-04-22 18:06:47 +0200 (Wed, 22 Apr 2009) | 3 lines

    kill the hack. Hack assumed that the only list of operations that can
    end up with fail is either suboperations or loop ops. That's not true

    ------------------------------------------------------------------------
    r64575 | fijal | 2009-04-22 18:26:50 +0200 (Wed, 22 Apr 2009) | 2 lines

    unused import

    ------------------------------------------------------------------------
    r64576 | fijal | 2009-04-22 18:27:45 +0200 (Wed, 22 Apr 2009) | 6 lines

    Add a test that showcases a problem that is silently eaten by ll2ctypes
    (not really silently, but one need to look deeper).

    The problem is that exceptions like DoneWithThisFrame travel through
    assembler and they really shouldn't

    ------------------------------------------------------------------------
    r64577 | fijal | 2009-04-22 18:56:00 +0200 (Wed, 22 Apr 2009) | 5 lines

    add some detection logic to get rid of entering can_enter_jit when inside a
    BlackHole. This can only happen when can_enter_jit is somewhere else than
    in the main interpreter loop and it causes jit exceptions to be propagated
    through the whole interpreter without ll_portal catching them.

    ------------------------------------------------------------------------
    r64578 | fijal | 2009-04-22 18:57:54 +0200 (Wed, 22 Apr 2009) | 3 lines

    skip this test for now, we need some support for running passing/failing
    guards

    ------------------------------------------------------------------------
    r64579 | fijal | 2009-04-22 20:02:53 +0200 (Wed, 22 Apr 2009) | 2 lines

    return integer

    ------------------------------------------------------------------------
    r64580 | fijal | 2009-04-22 20:08:45 +0200 (Wed, 22 Apr 2009) | 2 lines

    also remove guard_nonvirtualzied from bridges

    ------------------------------------------------------------------------
    r64599 | arigo | 2009-04-23 17:08:08 +0200 (Thu, 23 Apr 2009) | 2 lines

    Copy from pyjitpl5-simplify.

    ------------------------------------------------------------------------
    r64600 | arigo | 2009-04-23 17:12:51 +0200 (Thu, 23 Apr 2009) | 2 lines

    Porting r64598.

    ------------------------------------------------------------------------
    r64602 | arigo | 2009-04-23 17:27:16 +0200 (Thu, 23 Apr 2009) | 2 lines

    Fix a bug in test_random, and print the loop that is being executed.

    ------------------------------------------------------------------------
    r64604 | arigo | 2009-04-23 17:41:15 +0200 (Thu, 23 Apr 2009) | 2 lines

    Do multiple runs of the test (15 by default).

    ------------------------------------------------------------------------
    r64605 | arigo | 2009-04-23 17:41:33 +0200 (Thu, 23 Apr 2009) | 2 lines

    Fix int_abs().  Sorry, my fault.

    ------------------------------------------------------------------------
    r64606 | arigo | 2009-04-23 17:54:56 +0200 (Thu, 23 Apr 2009) | 3 lines

    Small extension.  For now there are enough bugs in the x86 backend
    that almost not a single test passes.

    ------------------------------------------------------------------------
    r64607 | arigo | 2009-04-23 20:08:17 +0200 (Thu, 23 Apr 2009) | 2 lines

    Bah :-)

    ------------------------------------------------------------------------
    r64609 | arigo | 2009-04-23 22:01:31 +0200 (Thu, 23 Apr 2009) | 3 lines

    Test and fix.  I'm rather unsure about if regalloc.py can easily
    be fixed for all cases or if there is some refactoring ahead...

    ------------------------------------------------------------------------
    r64610 | arigo | 2009-04-23 22:13:32 +0200 (Thu, 23 Apr 2009) | 2 lines

    Fix the output format to be directly copy-pastable as a test.

    ------------------------------------------------------------------------
    r64611 | arigo | 2009-04-23 22:17:39 +0200 (Thu, 23 Apr 2009) | 2 lines

    The next failing test.

    ------------------------------------------------------------------------
    r64613 | fijal | 2009-04-24 01:06:49 +0200 (Fri, 24 Apr 2009) | 2 lines

    unskip this test, passes for me

    ------------------------------------------------------------------------
    r64614 | fijal | 2009-04-24 02:18:38 +0200 (Fri, 24 Apr 2009) | 2 lines

    update svn:externals to the same as on trunk

    ------------------------------------------------------------------------
    r64615 | fijal | 2009-04-24 02:19:05 +0200 (Fri, 24 Apr 2009) | 2 lines

    update greenlet import

    ------------------------------------------------------------------------
    r64616 | fijal | 2009-04-24 02:27:09 +0200 (Fri, 24 Apr 2009) | 2 lines

    Ability to write down output directly to a file

    ------------------------------------------------------------------------
    r64617 | fijal | 2009-04-24 02:33:26 +0200 (Fri, 24 Apr 2009) | 2 lines

    a test and a fix.

    ------------------------------------------------------------------------
    r64618 | fijal | 2009-04-24 02:37:37 +0200 (Fri, 24 Apr 2009) | 2 lines

    a fix to int_is_true.

    ------------------------------------------------------------------------
    r64619 | fijal | 2009-04-24 02:46:14 +0200 (Fri, 24 Apr 2009) | 2 lines

    a test and a fix

    ------------------------------------------------------------------------
    r64621 | fijal | 2009-04-24 02:55:10 +0200 (Fri, 24 Apr 2009) | 2 lines

    bah, that was dumb

    ------------------------------------------------------------------------
    r64622 | benjamin | 2009-04-24 02:57:26 +0200 (Fri, 24 Apr 2009) | 1 line

    remove annotation hint for un-rpython method
    ------------------------------------------------------------------------
    r64623 | fijal | 2009-04-24 02:59:06 +0200 (Fri, 24 Apr 2009) | 2 lines

    ability to loop infinitely

    ------------------------------------------------------------------------
    r64624 | fijal | 2009-04-24 04:17:11 +0200 (Fri, 24 Apr 2009) | 2 lines

    boring. support simple guard_true/guard_false and it still passes

    ------------------------------------------------------------------------
    r64625 | fijal | 2009-04-24 07:29:45 +0200 (Fri, 24 Apr 2009) | 2 lines

    simplify

    ------------------------------------------------------------------------
    r64626 | fijal | 2009-04-24 07:31:22 +0200 (Fri, 24 Apr 2009) | 2 lines

    fix the test

    ------------------------------------------------------------------------
    r64630 | arigo | 2009-04-24 12:05:53 +0200 (Fri, 24 Apr 2009) | 2 lines

    Only introduce INT_AND/INT_OR operations if needed, as shown by v.value.

    ------------------------------------------------------------------------
    r64637 | arigo | 2009-04-24 14:16:22 +0200 (Fri, 24 Apr 2009) | 3 lines

    Fix the minimal backend in GUARD_EXCEPTION.
    Add (commented out) debug prints.

    ------------------------------------------------------------------------
    r64639 | arigo | 2009-04-24 14:53:00 +0200 (Fri, 24 Apr 2009) | 2 lines

    Skip test_zrpy_virtualizable for now (it fails for some reason).

    ------------------------------------------------------------------------
    r64640 | arigo | 2009-04-24 15:01:49 +0200 (Fri, 24 Apr 2009) | 3 lines

    Fix do_new_with_vtable.
    Test: test_zrpy_exception.TestException.test_bridge_from_interpreter_exc

    ------------------------------------------------------------------------
    r64641 | arigo | 2009-04-24 15:58:09 +0200 (Fri, 24 Apr 2009) | 2 lines

    Small fixes found by running pypy.

    ------------------------------------------------------------------------



Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/minimal/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/minimal/runner.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/minimal/runner.py	Fri Apr 24 18:31:27 2009
@@ -1,9 +1,10 @@
 import py
 from pypy.rlib.objectmodel import specialize, we_are_translated
+from pypy.rlib.debug import ll_assert, debug_print
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr, rclass
 from pypy.jit.metainterp.history import AbstractDescr, Box, BoxInt, BoxPtr
 from pypy.jit.metainterp import executor
-from pypy.jit.metainterp.resoperation import rop
+from pypy.jit.metainterp.resoperation import rop, opname
 
 
 class CPU(object):
@@ -38,33 +39,41 @@
         pass
 
     def execute_operations(self, loop, valueboxes):
+        #debug_print("execute_operations: starting", loop)
+        #for box in valueboxes:
+        #    debug_print("\t", box, "\t", box.get_())
         valueboxes = [box.clonebox() for box in valueboxes]
         self.clear_exception()
         self._guard_failed = False
         while True:
             env = {}
-            assert len(valueboxes) == len(loop.inputargs)
+            ll_assert(len(valueboxes) == len(loop.inputargs),
+                      "execute_operations: wrong argument count")
             for i in range(len(valueboxes)):
                 env[loop.inputargs[i]] = valueboxes[i]
             operations = loop.operations
             i = 0
             #
             while True:
-                assert i < len(operations), ("reached the end without "
-                                             "seeing a final op")
+                ll_assert(i < len(operations), "execute_operations: "
+                          "reached the end without seeing a final op")
                 op = operations[i]
                 i += 1
                 argboxes = []
+                #lst = [' %s ' % opname[op.opnum]]
                 for box in op.args:
                     if isinstance(box, Box):
                         box = env[box]
                     argboxes.append(box)
+                    #lst.append(str(box.get_()))
+                #debug_print(' '.join(lst))
                 if op.is_final():
                     break
                 if op.is_guard():
                     try:
                         resbox = self.execute_guard(op.opnum, argboxes)
                     except GuardFailed:
+                        #debug_print("\t*guard failed*")
                         self._guard_failed = True
                         operations = op.suboperations
                         i = 0
@@ -74,10 +83,13 @@
                                                        argboxes,
                                                        op.descr)
                 if op.result is not None:
-                    assert resbox is not None
+                    ll_assert(resbox is not None,
+                              "execute_operations: unexpectedly got None")
+                    #debug_print('\t-->', resbox.get_())
                     env[op.result] = resbox
                 else:
-                    assert resbox is None
+                    ll_assert(resbox is None,
+                              "execute_operations: unexpectedly got non-None")
             #
             if op.opnum == rop.JUMP:
                 loop = op.jump_target
@@ -85,8 +97,9 @@
                 continue
             if op.opnum == rop.FAIL:
                 break
-            assert 0, "bad opnum"
+            ll_assert(False, "execute_operations: bad opnum")
         #
+        #debug_print("execute_operations: leaving", loop)
         for i in range(len(op.args)):
             box = op.args[i]
             if isinstance(box, BoxInt):
@@ -95,6 +108,7 @@
             elif isinstance(box, BoxPtr):
                 value = env[box].getptr_base()
                 box.changevalue_ptr(value)
+            #debug_print("\t", box, "\t", box.get_())
         return op
 
     def execute_guard(self, opnum, argboxes):
@@ -125,12 +139,15 @@
         elif opnum == rop.GUARD_EXCEPTION:
             adr = argboxes[0].getaddr(self)
             expected_class = llmemory.cast_adr_to_ptr(adr, rclass.CLASSTYPE)
-            assert expected_class
+            ll_assert(bool(expected_class),
+                      "execute_guard: expected_class==NULL")
             exc = self.current_exc_inst
             if exc and rclass.ll_isinstance(exc, expected_class):
+                return BoxPtr(self.get_exc_value())
+            else:
                 raise GuardFailed
         else:
-            assert 0, "unknown guard op"
+            ll_assert(False, "execute_guard: unknown guard op")
 
     # ----------
 
@@ -216,10 +233,11 @@
         dict2.update({'rffi': rffi,
                       'FUNC': lltype.Ptr(lltype.FuncType(ARGS, RESULT)),
                       'length': len(ARGS),
+                      'll_assert': ll_assert,
                       })
         exec py.code.Source("""
             def call(cpu, function, args):
-                assert len(args) == length
+                ll_assert(len(args) == length, 'call: wrong arg count')
                 function = rffi.cast(FUNC, function)
                 res = function(%(args)s)
                 return %(result)s
@@ -240,7 +258,14 @@
         p = sizedescr.alloc()
         return BoxPtr(p)
 
-    do_new_with_vtable = do_new
+    def do_new_with_vtable(self, args, sizedescr):
+        assert isinstance(sizedescr, SizeDescr)
+        assert sizedescr.alloc is not None
+        p = sizedescr.alloc()
+        classadr = args[0].getaddr(self)
+        pobj = lltype.cast_opaque_ptr(rclass.OBJECTPTR, p)
+        pobj.typeptr = llmemory.cast_adr_to_ptr(classadr, rclass.CLASSTYPE)
+        return BoxPtr(p)
 
     def do_getfield_gc(self, args, fielddescr):
         assert isinstance(fielddescr, FieldDescr)
@@ -332,15 +357,19 @@
         assert isinstance(calldescr, CallDescr)
         assert calldescr.call is not None
         self.clear_exception()
+        addr_self = args[0].getaddr(self)
         try:
-            return calldescr.call(self, args[0].getaddr(self), args[1:])
+            box = calldescr.call(self, addr_self, args[1:])
         except Exception, e:
             from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
             self.current_exc_inst = cast_instance_to_base_ptr(e)
+            #debug_print('\tcall raised!', self.current_exc_inst)
             box = calldescr.errbox
             if box:
                 box = box.clonebox()
-            return box
+        #else:
+            #debug_print('\tcall did not raise')
+        return box
 
     # ----------
 

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/conftest.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/conftest.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/conftest.py	Fri Apr 24 18:31:27 2009
@@ -5,7 +5,7 @@
 class RandomRunnerPlugin:
     def pytest_addoption(self, parser):
         group = parser.addgroup('random test options')
-        group.addoption('--seed', action="store", type="int",
+        group.addoption('--random-seed', action="store", type="int",
                         default=random.randrange(0, 10000),
                         dest="randomseed",
                         help="choose a fixed random seed")
@@ -23,5 +23,12 @@
                         dest="n_vars",
                         help="supply this many randomly-valued arguments to "
                              "the function")
+        group.addoption('--repeat', action="store", type="int",
+                        default=15,
+                        dest="repeat",
+                        help="run the test this many times"),
+        group.addoption('--output', '-O', action="store", type="str",
+                        default="", dest="output",
+                        help="dump output to a file")
 
 ConftestPlugin = RandomRunnerPlugin

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/runner.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/runner.py	Fri Apr 24 18:31:27 2009
@@ -25,6 +25,10 @@
                                                   valueboxes, descr)
         boxes = [box for box in valueboxes if isinstance(box, Box)]
         res = self.cpu.execute_operations(loop, boxes)
+        if res is loop.operations[-1]:
+            self.guard_failed = False
+        else:
+            self.guard_failed = True
         if result_type != 'void':
             return res.args[0]
 
@@ -231,15 +235,6 @@
 ##                op = self.cpu.execute_operations(loop, [BoxInt(x), BoxInt(y)])
 ##                assert op.args[0].value == z
 
-    def test_uint_xor(self):
-        x = execute(self.cpu, rop.UINT_XOR, [BoxInt(100), ConstInt(4)])
-        assert x.value == 100 ^ 4
-        for a, b in [(ConstInt(1), BoxInt(-15)),
-                     (BoxInt(22), BoxInt(13)),
-                     (BoxInt(-112), ConstInt(11))]:
-            res = self.execute_operation(rop.UINT_XOR, [a, b], 'int')
-            assert res.value == intmask(r_uint(a.value) ^ r_uint(b.value))
-
     def test_ooops_non_gc(self):
         x = lltype.malloc(lltype.Struct('x'), flavor='raw')
         v = self.cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(x))
@@ -265,7 +260,7 @@
                                #(rop.GUARD_VALUE_INVERSE, [BoxInt(42), BoxInt(41)]),
                                ]:
             assert self.execute_operation(opname, args, 'void') == None
-            assert not self.cpu.guard_failed()
+            assert not self.guard_failed
             
         t = lltype.malloc(T)
         t.parent.parent.typeptr = vtable_for_T
@@ -273,7 +268,7 @@
         T_box = ConstInt(cpu.cast_adr_to_int(vtable_for_T_addr))
         null_box = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(T)))
         self.execute_operation(rop.GUARD_CLASS, [t_box, T_box], 'void')
-        assert not self.cpu.guard_failed()
+        assert not self.guard_failed
         #self.execute_operation(rop.GUARD_CLASS_INVERSE, [t_box, null_box],
         #                       'void')
 
@@ -301,6 +296,6 @@
                              #(rop.GUARD_VALUE_INVERSE, [BoxInt(10), BoxInt(10)]),
                              ]:
             assert self.execute_operation(opname, args, 'void') == None
-            assert self.cpu.guard_failed()
+            assert self.guard_failed
 
             

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/test_random.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/test_random.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/test_random.py	Fri Apr 24 18:31:27 2009
@@ -12,6 +12,7 @@
         self.loop = loop
         self.vars = vars
         self.boolvars = []   # subset of self.vars
+        self.should_fail_by = None
 
     def do(self, opnum, argboxes):
         v_result = execute(self.cpu, opnum, argboxes)
@@ -19,6 +20,55 @@
         self.loop.operations.append(ResOperation(opnum, argboxes, v_result))
         return v_result
 
+    def get_bool_var(self, r):
+        if self.boolvars:
+            v = r.choice(self.boolvars)
+        else:
+            v = r.choice(self.vars)
+            v = self.do(rop.INT_IS_TRUE, [v])
+        return v
+
+    def print_loop(self):
+        if demo_conftest.option.output:
+            s = open(demo_conftest.option.output, "w")
+        else:
+            s = sys.stdout
+        names = {None: 'None'}
+        for v in self.vars:
+            names[v] = 'v%d' % len(names)
+            print >>s, '    %s = BoxInt()' % (names[v],)
+        for op in self.loop.operations:
+            v = op.result
+            if v not in names:
+                names[v] = 'tmp%d' % len(names)
+                print >>s, '    %s = BoxInt()' % (names[v],)
+        print >>s, "    loop = TreeLoop('test')"
+        print >>s, '    loop.inputargs = [%s]' % (
+            ', '.join([names[v] for v in self.loop.inputargs]))
+        from pypy.jit.metainterp.resoperation import opname
+        print >>s, '    loop.operations = ['
+        for op in self.loop.operations:
+            print >>s, '        ResOperation(rop.%s, [%s], %s),' % (
+                opname[op.opnum],
+                ', '.join([names.get(v, 'ConstInt(%d)' % v.value)
+                           for v in op.args]),
+                names[op.result])
+        print >>s, '            ]'
+        print >>s, '    cpu = CPU(None, None)'
+        print >>s, '    cpu.compile_operations(loop)'
+        print >>s, '    op = cpu.execute_operations(loop, [%s])' % (
+            ', '.join(['BoxInt(%d)' % v.value for v in self.loop.inputargs]))
+        if self.should_fail_by is None:
+            for v in self.loop.operations[-1].args:
+                print >>s, '    assert %s.value == %d' % (names[v], v.value)
+        else:
+            print >>s, '    assert op is loop.operations[%d].suboperations[0]' % self.should_fail_by_num
+            for v in self.should_fail_by.args:
+                print >>s, '    assert %s.value == %d' % (names[v], v.value)
+        self.names = names
+        if demo_conftest.option.output:
+            s.close()
+
 class AbstractOperation:
     def __init__(self, opnum, boolres=False):
         self.opnum = opnum
@@ -35,11 +85,7 @@
 
 class BooleanUnaryOperation(UnaryOperation):
     def produce_into(self, builder, r):
-        if builder.boolvars:
-            v = r.choice(builder.boolvars)
-        else:
-            v = r.choice(builder.vars)
-            v = builder.do(rop.INT_IS_TRUE, [v])
+        v = builder.get_bool_var(r)
         self.put(builder, [v])
 
 class BinaryOperation(AbstractOperation):
@@ -58,13 +104,31 @@
             v_second = ConstInt((value & self.and_mask) | self.or_mask)
         else:
             v = r.choice(builder.vars)
-            if self.and_mask != 1:
+            if (v.value & self.and_mask) != v.value:
                 v = builder.do(rop.INT_AND, [v, ConstInt(self.and_mask)])
-            if self.or_mask != 0:
+            if (v.value | self.or_mask) != v.value:
                 v = builder.do(rop.INT_OR, [v, ConstInt(self.or_mask)])
             v_second = v
         self.put(builder, [v_first, v_second])
 
+class GuardBinaryOperation(AbstractOperation):
+
+    def produce_into(self, builder, r):
+        v = builder.get_bool_var(r)
+        op = ResOperation(self.opnum, [v], None)
+        builder.loop.operations.append(op)
+        k = r.random()
+        subset = []
+        num = int(k * len(builder.vars))
+        for i in range(num):
+            subset.append(r.choice(builder.vars))
+        r.shuffle(subset)
+        op.suboperations = [ResOperation(rop.FAIL, subset, None)]
+        if ((self.opnum == rop.GUARD_TRUE and not v.value) or
+            (self.opnum == rop.GUARD_FALSE and v.value)):
+            builder.should_fail_by = op.suboperations[0]
+            builder.should_fail_by_num = len(builder.loop.operations) - 1
+
 OPERATIONS = []
 
 for _op in [rop.INT_ADD,
@@ -89,11 +153,13 @@
             ]:
     OPERATIONS.append(BinaryOperation(_op, boolres=True))
 
-OPERATIONS.append(BinaryOperation(rop.INT_FLOORDIV, ~3, 1))
-OPERATIONS.append(BinaryOperation(rop.INT_MOD, ~3, 1))
+OPERATIONS.append(BinaryOperation(rop.INT_FLOORDIV, ~3, 2))
+OPERATIONS.append(BinaryOperation(rop.INT_MOD, ~3, 2))
 OPERATIONS.append(BinaryOperation(rop.INT_RSHIFT, LONG_BIT-1))
 OPERATIONS.append(BinaryOperation(rop.INT_LSHIFT, LONG_BIT-1))
 OPERATIONS.append(BinaryOperation(rop.UINT_RSHIFT, LONG_BIT-1))
+OPERATIONS.append(GuardBinaryOperation(rop.GUARD_TRUE))
+OPERATIONS.append(GuardBinaryOperation(rop.GUARD_FALSE))
 
 for _op in [rop.INT_NEG,
             rop.INT_INVERT,
@@ -115,10 +181,10 @@
     r = random.Random(seed)
     def get_random_integer():
         while True:
-            result = int(random.expovariate(0.05))
+            result = int(r.expovariate(0.05))
             if result <= sys.maxint:
                 break
-        if random.randrange(0, 5) <= 1:
+        if r.randrange(0, 5) <= 1:
             result = -result
         return result
     r.random_integer = get_random_integer
@@ -139,8 +205,7 @@
 
 # ____________________________________________________________
 
-def test_random_function():
-    r = Random()
+def check_random_function(r):
     block_length = demo_conftest.option.block_length
     vars = [BoxInt(r.random_integer())
             for i in range(demo_conftest.option.n_vars)]
@@ -155,6 +220,8 @@
 
     for i in range(block_length):
         r.choice(OPERATIONS).produce_into(builder, r)
+        if builder.should_fail_by is not None:
+            break
 
     endvars = []
     for v in vars:
@@ -165,15 +232,37 @@
             endvars.append(v)
     r.shuffle(endvars)
     loop.operations.append(ResOperation(rop.FAIL, endvars, None))
+    builder.print_loop()
 
     cpu.compile_operations(loop)
 
+    if builder.should_fail_by is not None:
+        endvars = builder.should_fail_by.args
     expected = {}
     for v in endvars:
         expected[v] = v.value
+    for v in endvars:
         v.changevalue_int(-sys.maxint-1)
 
-    cpu.execute_operations(loop, valueboxes)
+    op = cpu.execute_operations(loop, valueboxes)
+    assert op.args == endvars
 
     for v in endvars:
-        assert v.value == expected[v]
+        assert v.value == expected[v], (
+            "Got %d, expected %d, in the variable %s" % (v.value,
+                                                         expected[v],
+                                                         builder.names[v])
+            )
+
+    print '    # passed.'
+    print
+
+
+def test_random_function():
+    r = Random()
+    if demo_conftest.option.repeat == -1:
+        while 1: 
+            check_random_function(r)
+    else:
+        for i in range(demo_conftest.option.repeat):
+            check_random_function(r)

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py	Fri Apr 24 18:31:27 2009
@@ -241,7 +241,7 @@
         self.mc2.done()
         tree._x86_stack_depth = regalloc.max_stack_depth
         for place in self.places_to_patch_framesize:
-            mc = codebuf.InMemoryCodeBuilder(place, 128)
+            mc = codebuf.InMemoryCodeBuilder(place, place + 128)
             mc.ADD(esp, imm32(tree._x86_stack_depth * WORD))
             mc.done()
         for op, pos in self.jumps_to_look_at:
@@ -391,6 +391,7 @@
     def call(self, addr, args, res):
         for i in range(len(args)):
             arg = args[i]
+            assert not isinstance(arg, MODRM)
             self.mc.PUSH(arg)
         self.mc.CALL(rel32(addr))
         self.mc.ADD(esp, imm(len(args) * WORD))
@@ -405,12 +406,6 @@
     genop_int_or  = _binaryop("OR", True)
     genop_int_xor = _binaryop("XOR", True)
 
-    genop_uint_add = genop_int_add
-    genop_uint_sub = genop_int_sub
-    genop_uint_mul = genop_int_mul
-    genop_uint_xor = genop_int_xor
-    genop_uint_and = genop_int_and
-
     genop_guard_int_mul_ovf = _binaryop_ovf("IMUL", True)
     genop_guard_int_sub_ovf = _binaryop_ovf("SUB")
     genop_guard_int_add_ovf = _binaryop_ovf("ADD", True)
@@ -421,9 +416,9 @@
 
     genop_int_lt = _cmpop("L", "G")
     genop_int_le = _cmpop("LE", "GE")
-    genop_int_eq = _cmpop("E", "NE")
+    genop_int_eq = _cmpop("E", "E")
     genop_oois = genop_int_eq
-    genop_int_ne = _cmpop("NE", "E")
+    genop_int_ne = _cmpop("NE", "NE")
     genop_ooisnot = genop_int_ne
     genop_int_gt = _cmpop("G", "L")
     genop_int_ge = _cmpop("GE", "LE")
@@ -453,30 +448,34 @@
         self.mc.XOR(arglocs[0], imm8(1))
 
     def genop_int_lshift(self, op, arglocs, resloc):
-        loc = arglocs[0]
-        assert arglocs[1] is ecx
-        self.mc.SHL(loc, cl)
+        loc, loc2 = arglocs
+        if loc2 is ecx:
+            loc2 = cl
+        self.mc.SHL(loc, loc2)
 
     def genop_int_rshift(self, op, arglocs, resloc):
-        loc = arglocs[0]
-        assert arglocs[1] is ecx
-        self.mc.SAR(loc, cl)
+        loc, loc2 = arglocs
+        if loc2 is ecx:
+            loc2 = cl
+        self.mc.SAR(loc, loc2)
 
     def genop_uint_rshift(self, op, arglocs, resloc):
-        loc = arglocs[0]
-        assert arglocs[1] is ecx
-        self.mc.SHR(loc, cl)
+        loc, loc2 = arglocs
+        if loc2 is ecx:
+            loc2 = cl
+        self.mc.SHR(loc, loc2)
 
     def genop_guard_int_lshift_ovf(self, op, guard_op, addr, arglocs, resloc):
-        loc = arglocs[0]
-        tmploc = arglocs[2]
+        loc, loc2, tmploc = arglocs
+        if loc2 is ecx:
+            loc2 = cl
         # xxx a bit inefficient
         self.mc.MOV(tmploc, loc)
-        self.mc.SHL(tmploc, cl)
-        self.mc.SAR(tmploc, cl)
+        self.mc.SHL(tmploc, loc2)
+        self.mc.SAR(tmploc, loc2)
         self.mc.CMP(tmploc, loc)
         self.mc.JNE(rel32(addr))
-        self.mc.SHL(loc, cl)
+        self.mc.SHL(loc, loc2)
 
     def genop_int_is_true(self, op, arglocs, resloc):
         argloc = arglocs[0]
@@ -712,7 +711,8 @@
             self.mcstack.give_mc_back(mc2)
         else:
             pos = new_pos
-        mc = codebuf.InMemoryCodeBuilder(old_pos, MachineCodeBlockWrapper.MC_SIZE)
+        mc = codebuf.InMemoryCodeBuilder(old_pos, old_pos +
+                                         MachineCodeBlockWrapper.MC_SIZE)
         mc.JMP(rel32(pos))
         mc.done()
 
@@ -795,6 +795,12 @@
         if (guard_op.opnum == rop.GUARD_EXCEPTION or
             guard_op.opnum == rop.GUARD_NO_EXCEPTION):
             exc = True
+        # XXX this is a heuristics to detect whether we're handling this
+        # exception or not. We should have a bit better interface to deal
+        # with that I fear
+        if (exc and (guard_op.suboperations[0].opnum == rop.GUARD_EXCEPTION or
+                    guard_op.suboperations[0].opnum == rop.GUARD_NO_EXCEPTION)):
+            exc = False
         regalloc.walk_guard_ops(guard_op.inputargs, guard_op.suboperations, exc)
         self.mcstack.give_mc_back(self.mc2)
         self.mc2 = self.mc

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py	Fri Apr 24 18:31:27 2009
@@ -44,7 +44,6 @@
         raise ValueError("convert_to_imm: got a %s" % c)
 
 class RegAlloc(object):
-    guard_index = -1
     max_stack_depth = 0
     exc = False
     
@@ -267,6 +266,9 @@
         self._walk_operations(operations)
 
     def _walk_operations(self, operations):
+        fop = operations[-1]
+        if fop.opnum == rop.FAIL:
+            self.guard_index = self.assembler.cpu.make_guard_index(fop)
         i = 0
         while i < len(operations):
             op = operations[i]
@@ -616,11 +618,7 @@
         self.eventually_free_vars(inputargs)
 
     def regalloc_for_guard(self, guard_op):
-        regalloc = self.copy(guard_op)
-        fop = guard_op.suboperations[-1]
-        if fop.opnum == rop.FAIL:
-            regalloc.guard_index = self.assembler.cpu.make_guard_index(fop)
-        return regalloc
+        return self.copy(guard_op)
 
     def _consider_guard(self, op, ignored):
         loc = self.make_sure_var_in_reg(op.args[0], [])
@@ -708,8 +706,8 @@
             self.eventually_free_var(op.args[1])
             self.Load(x, self.loc(x), res)
             return res, argloc
-        loc = self.force_result_in_reg(op.result, x, op.args)
         argloc = self.loc(op.args[1])
+        loc = self.force_result_in_reg(op.result, x, op.args)
         self.eventually_free_var(op.args[1])
         return loc, argloc
 
@@ -723,11 +721,6 @@
     consider_int_and = _consider_binop
     consider_int_or  = _consider_binop
     consider_int_xor = _consider_binop
-    consider_uint_xor = _consider_binop
-    consider_uint_add = _consider_binop
-    consider_uint_mul = _consider_binop
-    consider_uint_sub = _consider_binop
-    consider_uint_and = _consider_binop
     
     def _consider_binop_ovf(self, op, guard_op):
         loc, argloc = self._consider_binop_part(op, None)
@@ -759,7 +752,10 @@
         self.eventually_free_var(guard_op.result)
 
     def consider_int_lshift(self, op, ignored):
-        loc2 = self.make_sure_var_in_reg(op.args[1], [], ecx)
+        if isinstance(op.args[1], Const):
+            loc2 = convert_to_imm(op.args[1])
+        else:
+            loc2 = self.make_sure_var_in_reg(op.args[1], [], ecx)
         loc1 = self.force_result_in_reg(op.result, op.args[0], op.args)
         self.Perform(op, [loc1, loc2], loc1)
         self.eventually_free_vars(op.args)
@@ -768,7 +764,10 @@
     consider_uint_rshift = consider_int_lshift
 
     def consider_int_lshift_ovf(self, op, guard_op):
-        loc2 = self.make_sure_var_in_reg(op.args[1], [], ecx)
+        if isinstance(op.args[1], Const):
+            loc2 = convert_to_imm(op.args[1])
+        else:
+            loc2 = self.make_sure_var_in_reg(op.args[1], [], ecx)
         loc1 = self.force_result_in_reg(op.result, op.args[0], op.args)
         tmpvar = TempBox()
         tmploc = self.force_allocate_reg(tmpvar, [])
@@ -1023,16 +1022,16 @@
     consider_cast_ptr_to_int = _same_as
 
     def consider_int_is_true(self, op, ignored):
-        argloc = self.force_allocate_reg(op.args[0], [])
+        argloc = self.make_sure_var_in_reg(op.args[0], [])
+        resloc = self.force_allocate_reg(op.result, op.args)
         self.eventually_free_var(op.args[0])
-        resloc = self.force_allocate_reg(op.result, [])
         self.Perform(op, [argloc], resloc)
 
     def consider_int_abs(self, op, ignored):
-        argloc = self.force_allocate_reg(op.args[0], [])
+        argloc = self.make_sure_var_in_reg(op.args[0], [])
         tmpvar = TempBox()
-        tmploc = self.force_allocate_reg(tmpvar, [])
-        resloc = self.force_allocate_reg(op.result, [])
+        tmploc = self.force_allocate_reg(tmpvar, [op.args[0]])
+        resloc = self.force_allocate_reg(op.result, [op.args[0], tmpvar])
         self.Perform(op, [argloc, tmploc], resloc)
         self.eventually_free_var(op.args[0])
         self.eventually_free_var(tmpvar)
@@ -1040,8 +1039,8 @@
     def consider_int_abs_ovf(self, op, guard_op):
         argloc = self.force_allocate_reg(op.args[0], [])
         tmpvar = TempBox()
-        tmploc = self.force_allocate_reg(tmpvar, [])
-        resloc = self.force_allocate_reg(op.result, [])
+        tmploc = self.force_allocate_reg(tmpvar, [op.args[0]])
+        resloc = self.force_allocate_reg(op.result, [op.args[0], tmpvar])
         self.position += 1
         regalloc = self.regalloc_for_guard(guard_op)
         self.perform_with_guard(op, guard_op, regalloc, [argloc, tmploc],

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py	Fri Apr 24 18:31:27 2009
@@ -2,7 +2,7 @@
 import ctypes
 import py
 from pypy.rpython.lltypesystem import lltype, llmemory, ll2ctypes, rffi, rstr
-from pypy.rpython.llinterp import LLInterpreter, LLException
+from pypy.rpython.llinterp import LLInterpreter
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rlib.objectmodel import CDefinedIntSymbolic, specialize, Symbolic
 from pypy.rlib.objectmodel import we_are_translated, keepalive_until_here
@@ -304,11 +304,7 @@
         keepalive_until_here(valueboxes)
         self.keepalives_index = oldindex
         del self.keepalives[oldindex:]
-        if guard_index == -1:
-            # special case for calls
-            op = loop.operations[-1]
-        else:
-            op = self._guard_list[guard_index]
+        op = self._guard_list[guard_index]
         #print "Leaving at: %d" % self.assembler.fail_boxes[len(op.args)]
         for i in range(len(op.args)):
             box = op.args[i]
@@ -660,10 +656,6 @@
         assert x == 0 or x > (1<<20) or x < (-1<<20)
         return rffi.cast(llmemory.GCREF, x)
 
-    # ---------------------------- tests ------------------------
-    def guard_failed(self):
-        return self._guard_index != -1
-
 def uhex(x):
     if we_are_translated():
         return hex(x)

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_runner.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_runner.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_runner.py	Fri Apr 24 18:31:27 2009
@@ -306,16 +306,6 @@
 
         arg0 = BoxInt(intmask(r_uint(sys.maxint + 3)))
         arg1 = BoxInt(intmask(r_uint(4)))
-        res = self.execute_operation(rop.UINT_ADD, [arg0, arg1], 'int')
-        assert res.value == intmask(r_uint(sys.maxint + 3) + r_uint(4))
-
-        arg0 = BoxInt(intmask(sys.maxint + 10))
-        arg1 = BoxInt(10)
-        res = self.execute_operation(rop.UINT_MUL, [arg0, arg1], 'int')
-        assert res.value == intmask((sys.maxint + 10) * 10)
-
-        arg0 = BoxInt(intmask(r_uint(sys.maxint + 3)))
-        arg1 = BoxInt(intmask(r_uint(4)))
 
         res = self.execute_operation(rop.UINT_GT, [arg0, arg1], 'int')
         assert res.value == 1

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_zrpy_exception.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_zrpy_exception.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_zrpy_exception.py	Fri Apr 24 18:31:27 2009
@@ -2,7 +2,6 @@
 import py
 from pypy.jit.metainterp.test import test_zrpy_exception
 from pypy.jit.backend.x86.test.test_zrpy_slist import Jit386Mixin
-from pypy.jit.backend.x86.support import c_meta_interp
 
 class TestException(Jit386Mixin, test_zrpy_exception.TestLLExceptions):
     # for the individual tests see

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py	Fri Apr 24 18:31:27 2009
@@ -338,10 +338,13 @@
 
     def __str__(self):
         if not hasattr(self, '_str'):
-            if self.type == INT:
-                t = 'i'
-            else:
-                t = 'p'
+            try:
+                if self.type == INT:
+                    t = 'i'
+                else:
+                    t = 'p'
+            except AttributeError:
+                t = 'b'
             self._str = '%s%d' % (t, Box._counter)
             Box._counter += 1
         return self._str
@@ -367,6 +370,9 @@
     def getint(self):
         return self.value
 
+    def getaddr(self, cpu):
+        return cpu.cast_int_to_adr(self.value)
+
     def get_(self):
         return self.value
 
@@ -392,6 +398,9 @@
     def getptr_base(self):
         return self.value
 
+    def getaddr(self, cpu):
+        return llmemory.cast_ptr_to_adr(self.value)
+
     def get_(self):
         return lltype.cast_ptr_to_int(self.value)
 

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py	Fri Apr 24 18:31:27 2009
@@ -861,6 +861,9 @@
 # ____________________________________________________________
 
 class MetaInterpGlobalData(object):
+
+    blackhole = False
+    
     def __init__(self):
         self.metainterp_doing_call = None
         self._debug_history = []
@@ -1280,6 +1283,7 @@
                 self.history.operations.append(suboperations[i])
             self.extra_rebuild_operations = extra
         else:
+            self.staticdata.globaldata.blackhole = True
             self.history = history.BlackHole(self.cpu)
             # the BlackHole is invalid because it doesn't start with
             # guard_failure.key.guard_op.suboperations, but that's fine

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/simple_optimize.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/simple_optimize.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/simple_optimize.py	Fri Apr 24 18:31:27 2009
@@ -16,6 +16,7 @@
         return None
 
 def optimize_bridge(options, old_loops, loop, cpu=None):
+    optimize_loop(options, [], loop, cpu)
     return old_loops[0]
 
 class Optimizer:

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_exception.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_exception.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_exception.py	Fri Apr 24 18:31:27 2009
@@ -430,6 +430,42 @@
         #    ENTER             - compile the leaving path (raising MyError)
         self.check_enter_count(4)
 
+
+    def test_bridge_from_interpreter_exc_2(self):
+        from pypy.jit.metainterp.simple_optimize import Optimizer
+        
+        mydriver = JitDriver(reds = ['n'], greens = [])
+
+        def x(n):
+            if n == 1:
+                raise MyError(n)
+        
+        def f(n):
+            try:
+                while n > 0:
+                    mydriver.can_enter_jit(n=n)
+                    mydriver.jit_merge_point(n=n)
+                    x(n)
+                    n -= 1
+            except MyError:
+                z()
+        
+        def z():
+            raise ValueError
+
+        def main(n):
+            try:
+                f(n)
+                return 3
+            except MyError, e:
+                return e.n
+            except ValueError:
+                return 8
+
+        res = self.meta_interp(main, [41], repeat=7, policy=StopAtXPolicy(x),
+                               optimizer=Optimizer)
+        assert res == 8
+
 class MyError(Exception):
     def __init__(self, n):
         self.n = n

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py	Fri Apr 24 18:31:27 2009
@@ -538,6 +538,7 @@
                         z = 0
                 n -= 1
                 some_fn(Stuff(n), k, z)
+            return 0
 
         res = self.meta_interp(f, [200])
 

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_zrpy_virtualizable.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_zrpy_virtualizable.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_zrpy_virtualizable.py	Fri Apr 24 18:31:27 2009
@@ -1,4 +1,5 @@
 import py
+py.test.skip("later")
 from pypy.jit.metainterp.test import test_virtualizable
 from pypy.jit.metainterp.test.test_zrpy_basic import LLInterpJitMixin
 

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py	Fri Apr 24 18:31:27 2009
@@ -189,6 +189,8 @@
 
         def maybe_enter_jit(*args):
             try:
+                if self.metainterp_sd.globaldata.blackhole:
+                    return
                 state.maybe_compile_and_run(*args)
             except JitException:
                 raise     # go through
@@ -322,25 +324,29 @@
         def ll_portal_runner(*args):
             while 1:
                 try:
-                    return support.maybe_on_top_of_llinterp(rtyper,
-                                                      portal_ptr)(*args)
-                except ContinueRunningNormally, e:
-                    args = ()
-                    for i, ARG in portalfunc_ARGS:
-                        v = unwrap(ARG, e.args[i])
-                        args = args + (v,)
-                except DoneWithThisFrame, e:
-                    return unwrap(RESULT, e.resultbox)
-                except ExitFrameWithException, e:
-                    value = unwrap_exc_value_box(e.valuebox)
-                    if not we_are_translated():
-                        if hasattr(value, 'typeptr'):
-                            raise LLException(value.typeptr, value)
+                    try:
+                        return support.maybe_on_top_of_llinterp(rtyper,
+                                                          portal_ptr)(*args)
+                    except ContinueRunningNormally, e:
+                        args = ()
+                        for i, ARG in portalfunc_ARGS:
+                            v = unwrap(ARG, e.args[i])
+                            args = args + (v,)
+                    except DoneWithThisFrame, e:
+                        return unwrap(RESULT, e.resultbox)
+                    except ExitFrameWithException, e:
+                        value = unwrap_exc_value_box(e.valuebox)
+                        if not we_are_translated():
+                            if hasattr(value, 'typeptr'):
+                                raise LLException(value.typeptr, value)
+                            else:
+                                raise LLException(ootype.classof(value), value)
                         else:
-                            raise LLException(ootype.classof(value), value)
-                    else:
-                        value = cast_base_ptr_to_instance(Exception, value)
-                        raise Exception, value
+                            value = cast_base_ptr_to_instance(Exception, value)
+                            raise Exception, value
+                finally:
+                    self.metainterp_sd.globaldata.blackhole = False
+
         ll_portal_runner._recursive_portal_call_ = True
 
         portal_runner_ptr = self.helper_func(self.PTR_PORTAL_FUNCTYPE,

Modified: pypy/branch/pyjitpl5-simplify/pypy/rlib/rcoroutine.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/rlib/rcoroutine.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/rlib/rcoroutine.py	Fri Apr 24 18:31:27 2009
@@ -34,7 +34,7 @@
 from pypy.rlib.objectmodel import we_are_translated
 
 try:
-    from py.magic import greenlet
+    from greenlet import greenlet
     main_greenlet = greenlet.getcurrent()
 except (ImportError, ValueError):
     def greenlet(*args, **kwargs):



More information about the Pypy-commit mailing list