[pypy-svn] r64098 - in pypy/trunk/pypy: rlib rpython/lltypesystem translator/stackless translator/stackless/test

arigo at codespeak.net arigo at codespeak.net
Wed Apr 15 16:15:17 CEST 2009


Author: arigo
Date: Wed Apr 15 16:15:16 2009
New Revision: 64098

Modified:
   pypy/trunk/pypy/rlib/rstack.py
   pypy/trunk/pypy/rpython/lltypesystem/lloperation.py
   pypy/trunk/pypy/translator/stackless/code.py
   pypy/trunk/pypy/translator/stackless/test/test_depth.py
   pypy/trunk/pypy/translator/stackless/transform.py
Log:
(niko, arigo)
Add rstack.{set,get}_stack_depth_limit() functions.


Modified: pypy/trunk/pypy/rlib/rstack.py
==============================================================================
--- pypy/trunk/pypy/rlib/rstack.py	(original)
+++ pypy/trunk/pypy/rlib/rstack.py	Wed Apr 15 16:15:16 2009
@@ -208,3 +208,16 @@
         return hop.genop('resume_state_invoke', [v_state, v_returning, v_raising],
                          hop.r_result)
         
+# ____________________________________________________________
+
+def get_stack_depth_limit():
+    if we_are_translated():
+        from pypy.rpython.lltypesystem.lloperation import llop
+        return llop.get_stack_depth_limit(lltype.Signed)
+    raise RuntimeError("no stack depth limit in non-translated versions")
+
+def set_stack_depth_limit(limit):
+    if we_are_translated():
+        from pypy.rpython.lltypesystem.lloperation import llop
+        return llop.set_stack_depth_limit(lltype.Void, limit)
+    raise RuntimeError("no stack depth limit in non-translated versions")

Modified: pypy/trunk/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/trunk/pypy/rpython/lltypesystem/lloperation.py	Wed Apr 15 16:15:16 2009
@@ -443,16 +443,21 @@
 
     # __________ stackless operation(s) __________
 
-    'yield_current_frame_to_caller': LLOp(canraise=(StackException,)),
+    'yield_current_frame_to_caller': LLOp(canraise=(StackException,
+                                                    RuntimeError)),
     #                               can always unwind, not just if stackless gc
 
     'resume_point':         LLOp(canraise=(Exception,)),
     'resume_state_create':  LLOp(canraise=(MemoryError,), canunwindgc=True),
-    'resume_state_invoke':  LLOp(canraise=(Exception, StackException)),
-    'stack_frames_depth':   LLOp(sideeffects=False, canraise=(StackException, )),
-    'stack_switch':         LLOp(canraise=(StackException, )),
-    'stack_unwind':         LLOp(canraise=(StackException, )),
-    'stack_capture':        LLOp(canraise=(StackException, )),
+    'resume_state_invoke':  LLOp(canraise=(Exception, StackException,
+                                           RuntimeError)),
+    'stack_frames_depth':   LLOp(sideeffects=False, canraise=(StackException,
+                                                              RuntimeError)),
+    'stack_switch':         LLOp(canraise=(StackException, RuntimeError)),
+    'stack_unwind':         LLOp(canraise=(StackException, RuntimeError)),
+    'stack_capture':        LLOp(canraise=(StackException, RuntimeError)),
+    'get_stack_depth_limit':LLOp(sideeffects=False),
+    'set_stack_depth_limit':LLOp(),
 
     # __________ misc operations __________
 

Modified: pypy/trunk/pypy/translator/stackless/code.py
==============================================================================
--- pypy/trunk/pypy/translator/stackless/code.py	(original)
+++ pypy/trunk/pypy/translator/stackless/code.py	Wed Apr 15 16:15:16 2009
@@ -1,3 +1,4 @@
+import sys
 from pypy.rpython.lltypesystem import lltype, llmemory, lloperation
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rlib import rarithmetic
@@ -285,6 +286,14 @@
 
 # ____________________________________________________________
 
+def ll_get_stack_depth_limit():
+    return global_state.stack_depth_limit
+
+def ll_set_stack_depth_limit(limit):
+    global_state.stack_depth_limit = limit
+
+# ____________________________________________________________
+
 class StacklessData:
     def __init__(self):
         self.top = frame.null_state
@@ -297,6 +306,7 @@
         self.exception = None
         self.masterarray = lltype.malloc(frame.FRAME_INFO_ARRAY, 0,
                                          immortal=True)
+        self.stack_depth_limit = sys.maxint
 
 global_state = StacklessData()
 
@@ -360,33 +370,42 @@
     """
     slp_main_loop() keeps resuming...
     """
-    pending = global_state.top
-    pending.f_depth = depth        # this starts after the first Unwind
-    
     while True:
-        prevdepth = pending.f_depth - 1
-        back = pending.f_back
-        decoded = frame.decodestate(pending.f_restart)
-        (fn, global_state.restart_substate, signature_index) = decoded
-        try:
-            call_function(fn, signature_index)
-        except UnwindException, u:   #XXX annotation support needed
-            u.frame_bottom.f_back = back
-            pending = global_state.top
-            pending.f_depth = prevdepth + u.depth
-            continue
-        except SwitchException:
-            pending = global_state.top
-            continue
-        except Exception, e:
-            if not back:
-                raise
+        pending = global_state.top
+        pending.f_depth = depth        # this starts after the first Unwind
+        if pending.f_depth > global_state.stack_depth_limit:
+            # uncommon case: exceed the limit
+            pending = pending.f_back
+            pending.f_depth = depth - 1
+            e = RuntimeError()
+            if not pending:
+                raise e
             global_state.exception = e
-        else:
-            if not back:
-                return
-        global_state.top = pending = back
-        pending.f_depth = prevdepth
+            global_state.top = pending
+
+        while True:
+            prevdepth = pending.f_depth - 1
+            back = pending.f_back
+            decoded = frame.decodestate(pending.f_restart)
+            (fn, global_state.restart_substate, signature_index) = decoded
+            try:
+                call_function(fn, signature_index)
+            except UnwindException, u:   #XXX annotation support needed
+                u.frame_bottom.f_back = back
+                depth = prevdepth + u.depth
+                break
+            except SwitchException:
+                pending = global_state.top
+                continue
+            except Exception, e:
+                if not back:
+                    raise
+                global_state.exception = e
+            else:
+                if not back:
+                    return
+            global_state.top = pending = back
+            pending.f_depth = prevdepth
 
 slp_main_loop.stackless_explicit = True
 

Modified: pypy/trunk/pypy/translator/stackless/test/test_depth.py
==============================================================================
--- pypy/trunk/pypy/translator/stackless/test/test_depth.py	(original)
+++ pypy/trunk/pypy/translator/stackless/test/test_depth.py	Wed Apr 15 16:15:16 2009
@@ -2,7 +2,7 @@
      llinterp_stackless_function, run_stackless_function
 from pypy.rlib import rstack
 import py
-import os
+import os, sys
 
 
 def test_simple():
@@ -177,3 +177,36 @@
 
     res = run_stackless_function(entrypoint)
     assert res == 7874837
+
+def test_get_set_stack_depth_limit():
+    def f():
+        assert rstack.get_stack_depth_limit() == sys.maxint
+        rstack.set_stack_depth_limit(12321)
+        return rstack.get_stack_depth_limit()
+    data = llinterp_stackless_function(f, assert_unwind=False)
+    assert data == 12321
+
+def test_stack_limit():
+    def g():
+        return rstack.stack_frames_depth()
+    def f():
+        rstack.set_stack_depth_limit(1)
+        try:
+            return g()
+        except RuntimeError:
+            return -123
+    data = llinterp_stackless_function(f)
+    assert data == -123
+
+def test_stack_limit_2():
+    def g():
+        return rstack.stack_frames_depth()
+    def f():
+        rstack.stack_frames_depth()
+        rstack.set_stack_depth_limit(1)
+        try:
+            return g()
+        except RuntimeError:
+            return -123
+    data = llinterp_stackless_function(f)
+    assert data == -123

Modified: pypy/trunk/pypy/translator/stackless/transform.py
==============================================================================
--- pypy/trunk/pypy/translator/stackless/transform.py	(original)
+++ pypy/trunk/pypy/translator/stackless/transform.py	Wed Apr 15 16:15:16 2009
@@ -250,7 +250,8 @@
     def operation_is_true(self, op):
         if op.opname in ('yield_current_frame_to_caller', 'resume_point',
                 'resume_state_invoke', 'resume_state_create', 'stack_frames_depth',
-                'stack_switch', 'stack_unwind', 'stack_capture'):
+                'stack_switch', 'stack_unwind', 'stack_capture',
+                'get_stack_depth_limit', 'set_stack_depth_limit'):
             return True
         if self.stackless_gc:
             if op.opname in ('malloc', 'malloc_varsize'):
@@ -379,6 +380,11 @@
                     code.ll_stack_unwind, [], annmodel.s_None),
                 'stack_capture': mixlevelannotator.constfunc(
                     code.ll_stack_capture, [], s_StatePtr),
+                'get_stack_depth_limit': mixlevelannotator.constfunc(
+                    code.ll_get_stack_depth_limit, [], annmodel.SomeInteger()),
+                'set_stack_depth_limit': mixlevelannotator.constfunc(
+                    code.ll_set_stack_depth_limit, [annmodel.SomeInteger()],
+                    annmodel.s_None),
         }
 
 



More information about the Pypy-commit mailing list