[pypy-svn] r65810 - in pypy/branch/pyjitpl5/pypy/jit/tl/spli: . test

benjamin at codespeak.net benjamin at codespeak.net
Thu Jun 18 04:19:24 CEST 2009


Author: benjamin
Date: Thu Jun 18 04:19:22 2009
New Revision: 65810

Added:
   pypy/branch/pyjitpl5/pypy/jit/tl/spli/interpreter.py   (contents, props changed)
   pypy/branch/pyjitpl5/pypy/jit/tl/spli/objects.py   (contents, props changed)
   pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_interpreter.py   (contents, props changed)
Log:
Add the beginnings of SPLI.

So far you can store and load variables, return things, add ints, and
concatenate strings.



Added: pypy/branch/pyjitpl5/pypy/jit/tl/spli/interpreter.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/tl/spli/interpreter.py	Thu Jun 18 04:19:22 2009
@@ -0,0 +1,76 @@
+from pypy.interpreter import pycode
+from pypy.tool import stdlib_opcode as opcode
+from pypy.jit.tl.spli import objects
+
+
+def spli_run_from_cpython_code(co):
+    pyco = pycode.PyCode._from_code(objects.DumbObjSpace(), co)
+    return SPLIFrame(pyco).run()
+
+
+class BlockUnroller(Exception):
+    pass
+
+class Return(BlockUnroller):
+
+    def __init__(self, value):
+        self.value = value
+
+
+class SPLIFrame(object):
+
+    def __init__(self, code):
+        self.code = code
+        self.value_stack = [None] * code.co_stacksize
+        self.locals = [None] * len(code.getvarnames())
+
+    def run(self):
+        self.stack_depth = 0
+        try:
+            self._dispatch_loop()
+        except Return, ret:
+            return ret.value
+
+    def _dispatch_loop(self):
+        code = self.code.co_code
+        instr_index = 0
+        while True:
+            op = ord(code[instr_index])
+            instr_index += 1
+            if op >= opcode.HAVE_ARGUMENT:
+                low = ord(code[instr_index])
+                hi = ord(code[instr_index + 1])
+                oparg = (hi << 8) | low
+                instr_index += 2
+            else:
+                oparg = 0
+            meth = getattr(self, opcode.opcode_method_names[op])
+            res = meth(oparg)
+            if res is not None:
+                instr_index = res
+
+    def push(self, value):
+        self.value_stack[self.stack_depth] = value
+        self.stack_depth += 1
+
+    def pop(self):
+        self.stack_depth -= 1
+        val = self.value_stack[self.stack_depth]
+        return val
+
+    def LOAD_FAST(self, name_index):
+        self.push(self.locals[name_index])
+
+    def STORE_FAST(self, name_index):
+        self.locals[name_index] = self.pop()
+
+    def RETURN_VALUE(self, _):
+        raise Return(self.pop())
+
+    def LOAD_CONST(self, const_index):
+        self.push(self.code.co_consts_w[const_index])
+
+    def BINARY_ADD(self, _):
+        right = self.pop()
+        left = self.pop()
+        self.push(left.add(right))

Added: pypy/branch/pyjitpl5/pypy/jit/tl/spli/objects.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/tl/spli/objects.py	Thu Jun 18 04:19:22 2009
@@ -0,0 +1,52 @@
+from pypy.interpreter.baseobjspace import ObjSpace
+
+
+class DumbObjSpace(ObjSpace):
+    """Implement just enough of the ObjSpace API to satisfy PyCode."""
+
+    def wrap(self, x):
+        if isinstance(x, int):
+            return Int(x)
+        if isinstance(x, str):
+            return Str(x)
+
+
+class InvalidOperation(Exception):
+    pass
+
+
+class SPLIObject(object):
+
+    def add(self, other):
+        raise InvalidOperation
+
+    def call(self, args):
+        raise InvalidOperation
+
+
+class Int(SPLIObject):
+
+    def __init__(self, value):
+        self.value = value
+
+    def add(self, other):
+        return Int(self.value + other.value)
+
+
+class Str(SPLIObject):
+
+    def __init__(self, value):
+        self.value = value
+
+    def add(self, other):
+        return Str(self.value + other.value)
+
+
+class Function(SPLIObject):
+
+    def __init__(self, code):
+        self.code = code
+
+    def call(self, args):
+        from pypy.jit.tl.spli import interpreter
+        return interpreter.SPLIFrame(self.code).run()

Added: pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_interpreter.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/tl/spli/test/test_interpreter.py	Thu Jun 18 04:19:22 2009
@@ -0,0 +1,31 @@
+from pypy.jit.tl.spli import interpreter, objects
+
+
+class TestSPLIInterpreter:
+
+    def eval(self, func):
+        return interpreter.spli_run_from_cpython_code(func.func_code)
+
+    def test_int_add(self):
+        def f():
+            return 4 + 6
+        v = self.eval(f)
+        assert isinstance(v, objects.Int)
+        assert v.value == 10
+        def f():
+            a = 4
+            return a + 6
+        assert self.eval(f).value == 10
+
+    def test_str(self):
+        def f():
+            return "Hi!"
+        v = self.eval(f)
+        assert isinstance(v, objects.Str)
+        assert v.value == "Hi!"
+        def f():
+            a = "Hello, "
+            return a + "SPLI world!"
+        v = self.eval(f)
+        assert isinstance(v, objects.Str)
+        assert v.value == "Hello, SPLI world!"



More information about the Pypy-commit mailing list