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

Reply via email to