[pypy-svn] r26525 - in pypy/dist/pypy/translator: c/test stackless stackless/test

mwh at codespeak.net mwh at codespeak.net
Fri Apr 28 18:11:50 CEST 2006


Author: mwh
Date: Fri Apr 28 18:11:48 2006
New Revision: 26525

Added:
   pypy/dist/pypy/translator/stackless/test/test_yield_current_frame_to_caller.py   (contents, props changed)
Modified:
   pypy/dist/pypy/translator/c/test/test_stackless.py
   pypy/dist/pypy/translator/stackless/code.py
Log:
a failed attempt to implement yield_current_frame_to_caller & some tests.
off on holiday for a week now, yippee!


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	Fri Apr 28 18:11:48 2006
@@ -178,6 +178,18 @@
         data = self.wrap_stackless_function(f)
         assert int(data.strip()) == 1234567
 
+    def test_foo(self):
+        def f():
+            c = g()
+            c.switch()
+            return 1
+        def g():
+            d = yield_current_frame_to_caller()
+            return d
+        data = self.wrap_stackless_function(f)
+        assert data.strip() == '1'
+        
+
     def test_yield_noswitch_frame(self):
         # this time we make sure that function 'g' does not
         # need to switch and even does not need to be stackless

Modified: pypy/dist/pypy/translator/stackless/code.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/code.py	(original)
+++ pypy/dist/pypy/translator/stackless/code.py	Fri Apr 28 18:11:48 2006
@@ -14,30 +14,86 @@
     return (currentframe.function,
             currentframe.retval_type,
             currentframe.restartstate)
-decode_state.stackless_explict = True
+decode_state.stackless_explicit = True
 
 SWITCH_STATE = lltype.GcStruct('state_switch',
                                ('header', STATE_HEADER),
                                ('c', llmemory.Address))
 
-def switch(c):
-    # this is untested so far!
-    if not global_state.restartstate:
+class Frame(object):
+    def __init__(self, state):
+        self.state = state
+    __init__.stackless_explicit = True
+    def switch(self):
+        if global_state.restart_substate == 0:
+            u = UnwindException()
+            s = lltype.malloc(SWITCH_STATE)
+            s.header.restartstate = 1
+            # the next three lines are pure rtyper-pleasing hacks
+            f = Frame.switch
+            if global_state.restart_substate:
+                f = None
+            s.c = llmemory.cast_ptr_to_adr(self.state)
+            s.header.function = llmemory.cast_ptr_to_adr(f)
+            add_frame_state(u, s.header)
+            raise u
+        elif global_state.restart_substate == 1:
+            top = global_state.top
+            state = lltype.cast_pointer(lltype.Ptr(SWITCH_STATE), top)
+            u = UnwindException()
+            s.header.restartstate = 2
+            c = lltype.cast_adr_to_ptr(lltype.Ptr(STATE_HEADER), top)
+            s.header.function = c.function
+            s.reader.retval_type = RETVAL_VOID_P
+            # the next three lines are pure rtyper-pleasing hacks
+            f = Frame.switch
+            if global_state.restart_substate:
+                f = None
+            add_frame_state(u, s.header)
+            raise u            
+        else:
+            top = global_state.top
+            global_state.restart_substate = 0
+            r = top.f_back
+            state = lltype.cast_pointer(lltype.Ptr(SWITCH_STATE), top)
+            global_state.top = lltype.cast_adr_to_ptr(lltype.Ptr(STATE_HEADER), state.c)
+            #global_state.restart_substate = state.header.restartstate
+            return r
+    switch.stackless_explicit = True
+
+def yield_current_frame_to_caller():
+    if global_state.restart_substate == 0:
+        u = UnwindException()
+        s = lltype.malloc(STATE_HEADER)
+        s.restartstate = 1
+        # the next three lines are pure rtyper-pleasing hacks
+        f = yield_current_frame_to_caller
+        if global_state.restart_substate:
+            f = None
+        s.function = llmemory.cast_ptr_to_adr(f)
+        s.retval_type = RETVAL_VOID_P
+        add_frame_state(u, s)
+        raise u
+    elif global_state.restart_substate == 1:
+        ycftc_state = global_state.top
+        our_caller_state = ycftc_state.f_back
+        caller_state = our_caller_state.f_back
+        cur = caller_state
+        while cur.f_back:
+            cur = cur.f_back
+        bot = cur
         u = UnwindException()
-        s = lltype.malloc(SWITCH_STATE)
-        s.c = llmemory.cast_ptr_to_adr(c)
-        s.header.restartstate = 1
-        s.header.function = llmemory.cast_ptr_to_adr(switch)
-        s.header.retval_type = RETVAL_VOID_P
-        add_frame_state(u, s.header)
+        u.frame_top = caller_state
+        u.frame_bottom = bot
+        global_state.retval_void_p = llmemory.cast_ptr_to_adr(Frame(ycftc_state))
+        global_state.restart_substate = 2
         raise u
     else:
-        top = global_state.top
-        s = lltype.cast_pointer(lltype.Ptr(SWITCH_STATE), top)
-        global_state.top = s.c
-        return top.f_back
-switch.stackless_explicit = True
-
+        pass
+        
+        
+yield_current_frame_to_caller.stackless_explicit = True
+    
 
 def stack_frames_depth():
     if not global_state.restart_substate:

Added: pypy/dist/pypy/translator/stackless/test/test_yield_current_frame_to_caller.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/stackless/test/test_yield_current_frame_to_caller.py	Fri Apr 28 18:11:48 2006
@@ -0,0 +1,47 @@
+from pypy.translator.stackless.test.test_transform import \
+     llinterp_stackless_function, run_stackless_function
+from pypy.translator.stackless import code
+import py
+import os
+
+py.test.skip('in progress')
+
+def test_simple():
+    def f(ignored):
+        c = g()
+        #c.switch()
+        return 1
+    def g():
+        d = code.yield_current_frame_to_caller()
+        return d
+
+    data = llinterp_stackless_function(f)
+    assert data == 1234567
+
+
+def test_yield_frame():
+
+    def g(lst):
+        lst.append(2)
+        frametop_before_5 = code.yield_current_frame_to_caller()
+        lst.append(4)
+        frametop_before_7 = frametop_before_5.switch()
+        lst.append(6)
+        return frametop_before_7
+
+    def f(ignored):
+        lst = [1]
+        frametop_before_4 = g(lst)
+        lst.append(3)
+        frametop_before_6 = frametop_before_4.switch()
+        lst.append(5)
+        frametop_after_return = frametop_before_6.switch()
+        lst.append(7)
+        assert frametop_after_return is None
+        n = 0
+        for i in lst:
+            n = n*10 + i
+        return n
+
+    data = llinterp_stackless_function(f)
+    assert data == 1234567



More information about the Pypy-commit mailing list