[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