Author: Armin Rigo <[email protected]>
Branch: stm
Changeset: r48527:070bf17d0fbb
Date: 2011-10-27 16:47 +0200
http://bitbucket.org/pypy/pypy/changeset/070bf17d0fbb/
Log: We cannot return out of the frame that started a regular
transaction.
diff --git a/pypy/translator/stm/llstminterp.py
b/pypy/translator/stm/llstminterp.py
--- a/pypy/translator/stm/llstminterp.py
+++ b/pypy/translator/stm/llstminterp.py
@@ -5,12 +5,20 @@
class ForbiddenInstructionInSTMMode(Exception):
pass
+class ReturnWithTransactionActive(Exception):
+ pass
+
def eval_stm_graph(llinterp, graph, values, stm_mode="not_in_transaction"):
llinterp.frame_class = LLSTMFrame
try:
llinterp.stm_mode = stm_mode
- return llinterp.eval_graph(graph, values)
+ llinterp.last_transaction_started_in_frame = None
+ res = llinterp.eval_graph(graph, values)
+ assert llinterp.stm_mode == stm_mode, (
+ "llinterp.stm_mode is %r after eval_graph, but should be %r" % (
+ llinterp.stm_mode, stm_mode))
+ return res
finally:
llinterp.frame_class = LLFrame
@@ -19,6 +27,7 @@
ALWAYS_ALLOW_OPERATIONS = set([
'int_*',
+ 'direct_call',
])
ALLOW_WHEN_NOT_IN_TRANSACTION = set([
'stm_begin_transaction',
@@ -30,6 +39,13 @@
ALLOW_WHEN_INEVITABLE_TRANSACTION = ALLOW_WHEN_REGULAR_TRANSACTION.union([
])
+ def eval(self):
+ res = LLFrame.eval(self)
+ if (self.llinterpreter.stm_mode == "regular_transaction" and
+ self.llinterpreter.last_transaction_started_in_frame is self):
+ raise ReturnWithTransactionActive(self.graph)
+ return res
+
def getoperationhandler(self, opname):
stm_mode = self.llinterpreter.stm_mode
attrname = '_opstm_%s__%s' % (stm_mode, opname)
@@ -69,6 +85,7 @@
def op_stm_begin_transaction(self):
assert self.llinterpreter.stm_mode == "not_in_transaction"
self.llinterpreter.stm_mode = "regular_transaction"
+ self.llinterpreter.last_transaction_started_in_frame = self
def op_stm_commit_transaction(self):
assert self.llinterpreter.stm_mode != "not_in_transaction"
diff --git a/pypy/translator/stm/test/test_llstminterp.py
b/pypy/translator/stm/test/test_llstminterp.py
--- a/pypy/translator/stm/test/test_llstminterp.py
+++ b/pypy/translator/stm/test/test_llstminterp.py
@@ -3,6 +3,7 @@
from pypy.rpython.test.test_llinterp import get_interpreter
from pypy.translator.stm.llstminterp import eval_stm_graph
from pypy.translator.stm.llstminterp import ForbiddenInstructionInSTMMode
+from pypy.translator.stm.llstminterp import ReturnWithTransactionActive
from pypy.translator.stm import rstm
@@ -53,3 +54,25 @@
interp, graph = get_interpreter(func, [p])
res = eval_stm_graph(interp, graph, [p])
assert res == 42
+
+def test_call_and_return_with_regular_transaction():
+ def g():
+ pass
+ g._dont_inline_ = True
+ def func():
+ rstm.begin_transaction()
+ g()
+ rstm.commit_transaction()
+ interp, graph = get_interpreter(func, [])
+ eval_stm_graph(interp, graph, [])
+
+def test_cannot_return_with_regular_transaction():
+ def g():
+ rstm.begin_transaction()
+ g._dont_inline_ = True
+ def func():
+ g()
+ rstm.commit_transaction()
+ interp, graph = get_interpreter(func, [])
+ py.test.raises(ReturnWithTransactionActive,
+ eval_stm_graph, interp, graph, [])
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit