[pypy-svn] r26958 - in pypy/dist/pypy: annotation rpython rpython/lltypesystem rpython/lltypesystem/test translator/c/src translator/c/test translator/stackless translator/stackless/test

arigo at codespeak.net arigo at codespeak.net
Sun May 7 23:59:06 CEST 2006


Author: arigo
Date: Sun May  7 23:59:02 2006
New Revision: 26958

Modified:
   pypy/dist/pypy/annotation/builtin.py
   pypy/dist/pypy/annotation/unaryop.py
   pypy/dist/pypy/rpython/lltypesystem/llmemory.py
   pypy/dist/pypy/rpython/lltypesystem/lltype.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
   pypy/dist/pypy/rpython/rbuiltin.py
   pypy/dist/pypy/rpython/rexternalobj.py
   pypy/dist/pypy/rpython/rmodel.py
   pypy/dist/pypy/translator/c/src/exception.h
   pypy/dist/pypy/translator/c/test/test_stackless.py
   pypy/dist/pypy/translator/c/test/test_tasklets.py
   pypy/dist/pypy/translator/stackless/code.py
   pypy/dist/pypy/translator/stackless/test/test_depth.py
   pypy/dist/pypy/translator/stackless/test/test_transform.py
   pypy/dist/pypy/translator/stackless/test/test_yield_current_frame_to_caller.py
   pypy/dist/pypy/translator/stackless/transform.py
Log:
(pedronis, arigo)
Good progress on the stackless transformer front.
The big change is that the old stackless no longer work
with reference counting!  They still pass with boehm.
The big result is that the old test pass with the new
stackless transform.

Lots of pushing and pulling:
    * details of cast_opaque_ptr()
    * bool(external object)
    * bool(address)
    * bug fix in yield_curr_etc()
    * added stack_unwind()
    * always put an explicit Exception link after direct_call
    * etc.



Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py	(original)
+++ pypy/dist/pypy/annotation/builtin.py	Sun May  7 23:59:02 2006
@@ -426,11 +426,8 @@
 def cast_opaque_ptr(PtrT, s_p):
     assert isinstance(s_p, SomePtr), "casting of non-pointer: %r" % s_p
     assert PtrT.is_constant()
-    try:
-        lltype.cast_opaque_ptr(PtrT.const, s_p.ll_ptrtype._defl())
-    except RuntimeError:
-        pass    # the type checks passed, but the _defl opaque cannot be cast
-    return SomePtr(ll_ptrtype=PtrT.const)
+    cast_p = lltype.cast_opaque_ptr(PtrT.const, s_p.ll_ptrtype._defl())
+    return SomePtr(ll_ptrtype=lltype.typeOf(cast_p))
 
 def direct_fieldptr(s_p, s_fieldname):
     assert isinstance(s_p, SomePtr), "direct_* of non-pointer: %r" % s_p

Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py	(original)
+++ pypy/dist/pypy/annotation/unaryop.py	Sun May  7 23:59:02 2006
@@ -667,3 +667,6 @@
         return SomeTypedAddressAccess(
             lladdress.supported_access_types[s_attr.const])
     getattr.can_only_throw = []
+
+    def is_true(s_addr):
+        return SomeBool()

Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/llmemory.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py	Sun May  7 23:59:02 2006
@@ -187,6 +187,9 @@
             return fakeaddress(self.ob, offset)
         return NotImplemented
 
+    def __nonzero__(self):
+        return self.ob is not None
+
     def __eq__(self, other):
         if not isinstance(other, fakeaddress):
             return False
@@ -215,6 +218,8 @@
         self.ref().set(value)
 
     def _cast_to_ptr(self, EXPECTED_TYPE):
+        if not self:
+            return lltype.nullptr(EXPECTED_TYPE.TO)
         ref = self.ref()
         if (isinstance(ref, _arrayitemref) and
             isinstance(EXPECTED_TYPE.TO, lltype.FixedSizeArray) and

Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py	Sun May  7 23:59:02 2006
@@ -632,6 +632,8 @@
                         "%s to %s" % (CURTYPE, PTRTYPE))
     if (isinstance(CURTYPE.TO, OpaqueType)
         and not isinstance(PTRTYPE.TO, OpaqueType)):
+        if not ptr:
+            return nullptr(PTRTYPE.TO)
         try:
             container = ptr._obj.container
         except AttributeError:
@@ -644,10 +646,14 @@
         return _ptr(PTRTYPE, container, solid)
     elif (not isinstance(CURTYPE.TO, OpaqueType)
           and isinstance(PTRTYPE.TO, OpaqueType)):
+        if not ptr:
+            return nullptr(PTRTYPE.TO)
         return opaqueptr(PTRTYPE.TO, 'hidden', container = ptr._obj,
                                                solid     = ptr._solid)
     elif (isinstance(CURTYPE.TO, OpaqueType)
           and isinstance(PTRTYPE.TO, OpaqueType)):
+        if not ptr:
+            return nullptr(PTRTYPE.TO)
         try:
             container = ptr._obj.container
         except AttributeError:

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py	Sun May  7 23:59:02 2006
@@ -299,7 +299,19 @@
     p10 = cast_pointer(Ptr(S1), p0)
     assert typeOf(p10) == Ptr(S1)
     assert not p10
-    
+
+def test_nullptr_opaque_cast():
+    S = Struct('S')
+    p0 = nullptr(S)
+    O1 = OpaqueType('O1')
+    O2 = OpaqueType('O2')
+    p1 = cast_opaque_ptr(Ptr(O1), p0)
+    assert not p1
+    p2 = cast_opaque_ptr(Ptr(O2), p1)
+    assert not p2
+    p3 = cast_opaque_ptr(Ptr(S), p2)
+    assert not p3
+
 
 def test_hash():
     S = ForwardReference()

Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/rbuiltin.py	Sun May  7 23:59:02 2006
@@ -378,7 +378,7 @@
     }
 _cast_from_Signed = {
     lltype.Signed:   None,
-    lltype.Bool:     'cast_int_to_bool',
+    lltype.Bool:     'int_is_true',
     lltype.Char:     'cast_int_to_char',
     lltype.UniChar:  'cast_int_to_unichar',
     lltype.Float:    'cast_int_to_float',

Modified: pypy/dist/pypy/rpython/rexternalobj.py
==============================================================================
--- pypy/dist/pypy/rpython/rexternalobj.py	(original)
+++ pypy/dist/pypy/rpython/rexternalobj.py	Sun May  7 23:59:02 2006
@@ -44,3 +44,7 @@
             init_opaque_object(p.obj, value)
             self.instance_cache[key] = p
         return p
+
+    def rtype_is_true(self, hop):
+        vlist = hop.inputargs(self)
+        return hop.genop('ptr_nonzero', vlist, resulttype=lltype.Bool)

Modified: pypy/dist/pypy/rpython/rmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/rmodel.py	(original)
+++ pypy/dist/pypy/rpython/rmodel.py	Sun May  7 23:59:02 2006
@@ -202,7 +202,9 @@
         try:
             vlen = self.rtype_len(hop)
         except MissingRTypeOperation:
-            return hop.inputconst(Bool, True)
+            if not hop.s_result.is_constant():
+                raise TyperError("rtype_is_true(%r) not implemented" % (self,))
+            return hop.inputconst(Bool, hop.s_result.const)
         else:
             return hop.genop('int_is_true', [vlen], resulttype=Bool)
 

Modified: pypy/dist/pypy/translator/c/src/exception.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/exception.h	(original)
+++ pypy/dist/pypy/translator/c/src/exception.h	Sun May  7 23:59:02 2006
@@ -10,6 +10,9 @@
 #ifdef HAVE_RTYPER               /* RPython version of exceptions */
 /******************************************************************/
 
+/* Hint: functions and macros not defined here, like RPyRaiseException,
+   come from exctransformer via the table in extfunc.py. */
+
 #define RPyFetchException(etypevar, evaluevar, type_of_evaluevar) do {  \
 		etypevar = RPyFetchExceptionType();			\
 		evaluevar = (type_of_evaluevar)RPyFetchExceptionValue(); \

Modified: pypy/dist/pypy/translator/c/test/test_stackless.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_stackless.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_stackless.py	Sun May  7 23:59:02 2006
@@ -40,7 +40,8 @@
         #cbuilder.use_stackless_transformation = True
         cbuilder.generate_source()
         cbuilder.compile()
-        return cbuilder.cmdexec('')
+        res = cbuilder.cmdexec('')
+        return int(res.strip())
 
 
     def test_stack_depth(self):
@@ -62,8 +63,8 @@
             count10 = f(10)
             return count10 - count0
 
-        data = self.wrap_stackless_function(fn)
-        assert data.strip() == '10'
+        res = self.wrap_stackless_function(fn)
+        assert res == 10
 
     def test_stack_withptr(self):
         def f(n):
@@ -78,8 +79,8 @@
             count10, _ = f(10)
             return count10 - count0
 
-        data = self.wrap_stackless_function(fn)
-        assert data.strip() == '10'
+        res = self.wrap_stackless_function(fn)
+        assert res == 10
 
     def test_stackless_manytimes(self):
         def f(n):
@@ -95,8 +96,8 @@
             count10, _ = f(100)
             return count10 - count0
 
-        data = self.wrap_stackless_function(fn)
-        assert data.strip() == '100'
+        res = self.wrap_stackless_function(fn)
+        assert res == 100
 
     def test_stackless_arguments(self):
         def f(n, d, t):
@@ -109,10 +110,14 @@
         def fn():
             count0, d, t = f(0, 5.5, (1, 2))
             count10, d, t = f(10, 5.5, (1, 2))
-            return "[" + str(count10 - count0) + ", " + str(d) + ", " + str(t[0]) + ", " + str(t[1]) + "]"
+            result = (count10 - count0) * 1000000
+            result += t[0]              * 10000
+            result += t[1]              * 100
+            result += int(d*10)
+            return result
 
-        data = self.wrap_stackless_function(fn)
-        assert eval(data) == [10, 5.5, 1, 2]
+        res = self.wrap_stackless_function(fn)
+        assert res == 10010255
 
 
     def test_stack_too_big(self):
@@ -135,8 +140,8 @@
 
         def fn():
             return f(0)
-        data = self.wrap_stackless_function(fn)
-        assert int(data.strip()) > 500
+        res = self.wrap_stackless_function(fn)
+        assert res > 500
 
 
     def test_stack_unwind(self):
@@ -144,8 +149,8 @@
             stack_unwind()
             return 42
 
-        data = self.wrap_stackless_function(f)
-        assert int(data.strip()) == 42
+        res = self.wrap_stackless_function(f)
+        assert res == 42
 
     def test_auto_stack_unwind(self):
         def f(n):
@@ -155,8 +160,8 @@
 
         def fn():
             return f(10**6)
-        data = self.wrap_stackless_function(fn)
-        assert int(data.strip()) == 704
+        res = self.wrap_stackless_function(fn)
+        assert res == 704
 
     def test_yield_frame(self):
 
@@ -182,8 +187,8 @@
                 n = n*10 + i
             return n
 
-        data = self.wrap_stackless_function(f)
-        assert int(data.strip()) == 1234567
+        res = self.wrap_stackless_function(f)
+        assert res == 1234567
 
     def test_foo(self):
         def f():
@@ -193,8 +198,8 @@
         def g():
             d = yield_current_frame_to_caller()
             return d
-        data = self.wrap_stackless_function(f)
-        assert data.strip() == '1'
+        res = self.wrap_stackless_function(f)
+        assert res == 1
         
 
     def test_yield_noswitch_frame(self):
@@ -219,8 +224,8 @@
                 n = n*10 + i
             return n
 
-        data = self.wrap_stackless_function(f)
-        assert int(data.strip()) == 12345
+        res = self.wrap_stackless_function(f)
+        assert res == 12345
 
     # tested with refcounting too for sanity checking
     def test_yield_frame_mem_pressure(self):
@@ -261,8 +266,8 @@
                 n = n*10 + i
             return n
 
-        data = self.wrap_stackless_function(f)
-        assert int(data.strip()) == 1234567
+        res = self.wrap_stackless_function(f)
+        assert res == 1234567
 
 
 # ____________________________________________________________
@@ -291,3 +296,12 @@
         if not check_boehm_presence():
             py.test.skip("Boehm GC not present")
 
+# ____________________________________________________________
+
+class TestStacklessTransformBoehm(TestStacklessBoehm):
+
+    def wrap_stackless_function(self, fn):
+        # temporary way of doing this
+        #import py; py.test.skip("in-progress")
+        from pypy.translator.stackless.test import test_transform
+        return test_transform.run_stackless_function(fn)

Modified: pypy/dist/pypy/translator/c/test/test_tasklets.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_tasklets.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_tasklets.py	Sun May  7 23:59:02 2006
@@ -13,6 +13,11 @@
 gcpolicy = None
 if cbuild.check_boehm_presence():
     gcpolicy = BoehmGcPolicy
+else:
+    # to re-enable this, remove the two characters 'gc' in the
+    # declaregcptrtype(rstack.frame_stack_top,...) call in
+    # rpython/extfunctable.  Doing so breaks translator/stackless/.
+    py.test.skip("stackless + refcounting doesn't work any more for now")
 
 # count of loops in tests (set lower to speed up)
 loops = 1

Modified: pypy/dist/pypy/translator/stackless/code.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/code.py	(original)
+++ pypy/dist/pypy/translator/stackless/code.py	Sun May  7 23:59:02 2006
@@ -99,6 +99,7 @@
         next_state = llmemory.cast_adr_to_ptr(fetch_retval_void_p(),
                                               lltype.Ptr(STATE_HEADER))
         global_state.top = next_state
+        global_state.retval_void_p = llmemory.NULL
         raise UnwindException()
 
 yield_current_frame_to_caller.stackless_explicit = True
@@ -126,6 +127,23 @@
         return depth
 stack_frames_depth.stackless_explicit = True
 
+def ll_stack_unwind():
+    if not global_state.restart_substate:
+        u = UnwindException()
+        s = lltype.malloc(STATE_HEADER)
+        s.restartstate = 1
+        # the next three lines are pure rtyper-pleasing hacks
+        f = ll_stack_unwind
+        if global_state.restart_substate:
+            f = None
+        s.function = llmemory.cast_ptr_to_adr(f)
+        s.retval_type = RETVAL_VOID
+        add_frame_state(u, s)
+        raise u
+    else:
+        global_state.restart_substate = 0
+ll_stack_unwind.stackless_explicit = True
+
 class StacklessData:
     def __init__(self):
         self.top = null_state

Modified: pypy/dist/pypy/translator/stackless/test/test_depth.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/test/test_depth.py	(original)
+++ pypy/dist/pypy/translator/stackless/test/test_depth.py	Sun May  7 23:59:02 2006
@@ -27,7 +27,7 @@
             g2(g1)
             return res
 
-        def fn(ignored):
+        def fn():
             count0 = f(0)
             count10 = f(10)
             return count10 - count0
@@ -36,7 +36,7 @@
         assert res == 10
 
         res = run_stackless_function(fn)
-        assert res.strip() == "10"
+        assert res == 10
 
     def test_with_ptr(self):
         def f(n):
@@ -46,7 +46,7 @@
                 res = self.stack_frames_depth(), 1
             return res
 
-        def fn(ignored):
+        def fn():
             count0, _ = f(0)
             count10, _ = f(10)
             return count10 - count0
@@ -55,7 +55,7 @@
         assert res == 10
 
         res = run_stackless_function(fn)
-        assert res.strip() == "10"
+        assert res == 10
 
     def test_manytimes(self):
         def f(n):
@@ -65,7 +65,7 @@
                 res = self.stack_frames_depth(), 1
             return res
 
-        def fn(ignored):
+        def fn():
             count0, _ = f(0)
             count10, _ = f(100)
             return count10 - count0
@@ -74,7 +74,7 @@
         assert res == 100
 
         res = run_stackless_function(fn)
-        assert res.strip() == "100"
+        assert res == 100
 
     def test_arguments(self):
         def f(n, d, t):
@@ -84,7 +84,7 @@
                 res = self.stack_frames_depth(), d, t
             return res
 
-        def fn(ignored):
+        def fn():
             count0, d, t = f(0, 5.5, (1, 2))
             count10, d, t = f(10, 5.5, (1, 2))
             return count10 - count0 + int(d)
@@ -93,7 +93,7 @@
         assert res == 15
 
         res = run_stackless_function(fn)
-        assert res.strip() == "15"
+        assert res == 15
 
 
 class TestFromRStack(TestFromCode):

Modified: pypy/dist/pypy/translator/stackless/test/test_transform.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/test/test_transform.py	(original)
+++ pypy/dist/pypy/translator/stackless/test/test_transform.py	Sun May  7 23:59:02 2006
@@ -34,8 +34,18 @@
 
 from pypy.translator.stackless import code
 
+def factorial(n):
+    if n > 1:
+        return factorial(n-1) * n
+    else:
+        return 1
+
+def one():   # but the annotator doesn't know it's one
+    return factorial(5) / 120
+
+
 def test_nothing():
-    def fn(ignored):
+    def fn():
         return 21
     res = llinterp_stackless_function(fn)
     assert res == 21
@@ -48,8 +58,8 @@
     def g(x):
         check(x)
         return x + 1
-    def example(x):
-        return g(x) + 1
+    def example():
+        return g(one()) + 1
     res = llinterp_stackless_function(example)
     assert res == 3
 
@@ -60,8 +70,8 @@
     def g(x):
         check(x)
         return x + 0.125
-    def example(x):
-        return int((g(x) + 1)*1000.0)
+    def example():
+        return int((g(one()) + 1)*1000.0)
     res = llinterp_stackless_function(example)
     assert res == 2125
 
@@ -72,10 +82,10 @@
     def g(x):
         check(x)
         return x + 1
-    def example(x):
-        return g(x) + 1
+    def example():
+        return g(one()) + 1
     res = run_stackless_function(example)
-    assert res.strip() == "3"
+    assert res == 3
 
 def test_protected_call():
     def check(x):
@@ -84,16 +94,16 @@
     def g(x):
         check(x)
         return x + 1
-    def example(x):
+    def example():
         try:
-            y = g(x)
+            y = g(one())
         except Exception:
             y = -1
         return y + 1
     res = llinterp_stackless_function(example)
     assert res == 3
     res = run_stackless_function(example)
-    assert res == "3"
+    assert res == 3
 
 def test_resume_with_exception():
     def check(x):
@@ -107,8 +117,8 @@
             return x + 1
     def h(x):
         return g(x)
-    def example(x):
-        y = h(x)
+    def example():
+        y = h(one())
         return y + 1
     info = py.test.raises(
         llinterp.LLException,
@@ -127,9 +137,9 @@
             return x + 1
     def h(x):
         return g(x)
-    def example(x):
+    def example():
         try:
-            y = h(x)
+            y = h(one())
         except KeyError:
             y = -1
         return y + 1
@@ -141,7 +151,8 @@
         if x:
             raise code.UnwindException
     check.stackless_explicit = True
-    def f(l):
+    def f():
+        l = one()
         check(l)
         return len([x for x in range(l)])
     res = llinterp_stackless_function(f)
@@ -171,6 +182,9 @@
         raise Exception, "this probably isn't going to work"
     t.buildrtyper().specialize()
 
+    from pypy.translator.transform import insert_ll_stackcheck
+    insert_ll_stackcheck(t)
+
     if conftest.option.view:
         t.view()
     return t
@@ -178,7 +192,7 @@
 def run_stackless_function(fn):
     def entry_point(argv):
         try:
-            r = fn(len(argv))
+            r = fn()
         except code.UnwindException, u:
             code.slp_main_loop()
             r = code.global_state.retval_long
@@ -195,12 +209,13 @@
     if conftest.option.view:
         t.view()
     cbuilder.compile()
-    return cbuilder.cmdexec('').strip()
+    res = cbuilder.cmdexec('')
+    return int(res.strip())
 
 def llinterp_stackless_function(fn):
     def entry_point(argv):
         try:
-            r = fn(len(argv))
+            r = fn()
         except code.UnwindException, u:
             code.slp_main_loop()
             return code.global_state.retval_long

Modified: pypy/dist/pypy/translator/stackless/test/test_yield_current_frame_to_caller.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/test/test_yield_current_frame_to_caller.py	(original)
+++ pypy/dist/pypy/translator/stackless/test/test_yield_current_frame_to_caller.py	Sun May  7 23:59:02 2006
@@ -15,7 +15,7 @@
         return True
 
     def test_simple(self):
-        def f(ignored):
+        def f():
             c = g()
             return 1
         def g():
@@ -25,10 +25,10 @@
         assert data == 1
 
         res = run_stackless_function(f)
-        assert res.strip() == "1"
+        assert res == 1
 
     def test_switch(self):
-        def f(ignored):
+        def f():
             c = g()
             self.switch(c)
             return 1
@@ -40,7 +40,7 @@
         assert data == 1
 
         res = run_stackless_function(f)
-        assert res.strip() == "1"
+        assert res == 1
 
     def test_yield_frame(self):
 
@@ -52,7 +52,7 @@
             lst.append(6)
             return frametop_before_7
 
-        def f(ignored):
+        def f():
             lst = [1]
             frametop_before_4 = g(lst)
             lst.append(3)
@@ -60,7 +60,7 @@
             lst.append(5)
             frametop_after_return = self.switch(frametop_before_6)
             lst.append(7)
-            assert bool(frametop_after_return)
+            assert not frametop_after_return
             n = 0
             for i in lst:
                 n = n*10 + i
@@ -70,7 +70,7 @@
         assert data == 1234567
 
         res = run_stackless_function(f)
-        assert res.strip() == "1234567"
+        assert res == 1234567
 
 
 class TestFromRStack(TestFromCode):

Modified: pypy/dist/pypy/translator/stackless/transform.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/transform.py	(original)
+++ pypy/dist/pypy/translator/stackless/transform.py	Sun May  7 23:59:02 2006
@@ -10,7 +10,7 @@
 from pypy.rpython.rclass import getinstancerepr
 from pypy.rpython.rbuiltin import gen_cast
 from pypy.rpython.rtyper import LowLevelOpList
-from pypy.rpython.module import ll_stackless
+from pypy.rpython.module import ll_stackless, ll_stack
 
 from pypy.translator.stackless.code import STATE_HEADER, null_state
 
@@ -119,12 +119,19 @@
             code.fetch_retval_void_p, [], annmodel.SomeAddress())
 
         s_StatePtr = annmodel.SomePtr(code.OPAQUE_STATE_HEADER_PTR)
-        self.stack_frames_depth_ptr = mixlevelannotator.constfunc(
-            code.stack_frames_depth, [], annmodel.SomeInteger())
+        self.suggested_primitives = {
+            ll_stackless.ll_stackless_stack_frames_depth:
+                mixlevelannotator.constfunc(
+                    code.stack_frames_depth, [], annmodel.SomeInteger()),
+            ll_stackless.ll_stackless_switch:
+                mixlevelannotator.constfunc(
+                    code.ll_frame_switch, [s_StatePtr], s_StatePtr),
+            ll_stack.ll_stack_unwind:
+                mixlevelannotator.constfunc(
+                    code.ll_stack_unwind, [], annmodel.s_None),
+            }
         self.yield_current_frame_to_caller_ptr = mixlevelannotator.constfunc(
             code.yield_current_frame_to_caller, [], s_StatePtr)
-        self.ll_frame_switch_ptr = mixlevelannotator.constfunc(
-            code.ll_frame_switch, [s_StatePtr], s_StatePtr)
 
         mixlevelannotator.finish()
 
@@ -344,10 +351,8 @@
                 # trap calls to stackless-related suggested primitives
                 if op.opname == 'direct_call':
                     func = getattr(op.args[0].value._obj, '_callable', None)
-                    if func is ll_stackless.ll_stackless_stack_frames_depth:
-                        op = replace_with_call(self.stack_frames_depth_ptr)
-                    elif func is ll_stackless.ll_stackless_switch:
-                        op = replace_with_call(self.ll_frame_switch_ptr)
+                    if func in self.suggested_primitives:
+                        op = replace_with_call(self.suggested_primitives[func])
 
                 if i == len(block.operations) - 1 \
                        and block.exitswitch == model.c_last_exception:
@@ -357,23 +362,22 @@
                         return
                 else:
                     link = support.split_block_with_keepalive(block, i+1)
-                    # this section deserves a whinge:
-                    
-                    # i want to use rtyper.insert_link_conversions() in
-                    # insert_resume_handling().  insert_link_conversions()
-                    # calls bindingrepr(), which depends on variables having
-                    # annotations.  split_block called copyvar(None, ...)
-                    # which doesn't preserve the annotation.  so put it back
-                    # here.  it certainly sucks that this module has to worry
-                    # about annotations :(
-##                    XXX is this still needed?
-##                    ann = self.translator.annotator
-##                    for f, t in zip(link.args, link.target.inputargs):
-##                        nb = ann.binding(f, None)
-##                        if nb is not None:
-##                            ann.setbinding(t, nb)
                     block.exitswitch = model.c_last_exception
                     link.llexitcase = None
+                    # add a general Exception link, because all calls can
+                    # raise anything
+                    v_exctype = varoftype(etype)
+                    v_excvalue = varoftype(evalue)
+                    newlink = model.Link([v_exctype, v_excvalue],
+                                         self.curr_graph.exceptblock,
+                                         Exception)
+                    newlink.last_exception = v_exctype
+                    newlink.last_exc_value = v_excvalue
+                    newexits = list(block.exits)
+                    newexits.append(newlink)
+                    block.recloseblock(*newexits)
+                    self.translator.rtyper._convert_link(block, newlink)
+
                 var_unwind_exception = varoftype(evalue)
                
                 # for the case where we are resuming to an except:



More information about the Pypy-commit mailing list