Author: Armin Rigo <[email protected]>
Branch: stm
Changeset: r48524:6ed608d0af8e
Date: 2011-10-27 15:39 +0200
http://bitbucket.org/pypy/pypy/changeset/6ed608d0af8e/
Log: A subclass of llinterp that detects non-STM-friendly instructions.
diff --git a/pypy/translator/stm/llstminterp.py
b/pypy/translator/stm/llstminterp.py
new file mode 100644
--- /dev/null
+++ b/pypy/translator/stm/llstminterp.py
@@ -0,0 +1,37 @@
+from pypy.rpython.llinterp import LLFrame
+
+
+class ForbiddenInstructionInSTMMode(Exception):
+ pass
+
+
+def eval_stm_graph(llinterp, graph, values):
+ llinterp.frame_class = LLSTMFrame
+ try:
+ return llinterp.eval_graph(graph, values)
+ finally:
+ llinterp.frame_class = LLFrame
+
+
+class LLSTMFrame(LLFrame):
+
+ ALLOW_OPERATIONS = set([
+ 'int_*',
+ ])
+
+ def getoperationhandler(self, opname):
+ ophandler = getattr(self, 'opstm_' + opname, None)
+ if ophandler is None:
+ self._validate_stmoperation_handler(opname)
+ ophandler = LLFrame.getoperationhandler(self, opname)
+ setattr(self, 'opstm_' + opname, ophandler)
+ return ophandler
+
+ def _validate_stmoperation_handler(self, opname):
+ OK = self.ALLOW_OPERATIONS
+ if opname in OK:
+ return
+ for i in range(len(opname)-1, -1, -1):
+ if (opname[:i] + '*') in OK:
+ return
+ raise ForbiddenInstructionInSTMMode(opname, self.graph)
diff --git a/pypy/translator/stm/test/test_llstminterp.py
b/pypy/translator/stm/test/test_llstminterp.py
new file mode 100644
--- /dev/null
+++ b/pypy/translator/stm/test/test_llstminterp.py
@@ -0,0 +1,23 @@
+import py
+from pypy.rpython.lltypesystem import lltype
+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
+
+
+def test_simple():
+ def func(n):
+ return (n+1) * (n+2)
+ interp, graph = get_interpreter(func, [5])
+ res = eval_stm_graph(interp, graph, [5])
+ assert res == 42
+
+def test_forbidden():
+ S = lltype.GcStruct('S', ('x', lltype.Signed))
+ p = lltype.malloc(S, immortal=True)
+ p.x = 42
+ def func(p):
+ return p.x
+ interp, graph = get_interpreter(func, [p])
+ py.test.raises(ForbiddenInstructionInSTMMode,
+ eval_stm_graph, interp, graph, [p])
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit