[pypy-svn] r41309 - pypy/dist/pypy/jit/tl
arigo at codespeak.net
arigo at codespeak.net
Mon Mar 26 10:33:20 CEST 2007
Author: arigo
Date: Mon Mar 26 10:33:19 2007
New Revision: 41309
Added:
pypy/dist/pypy/jit/tl/targettiny2.py (contents, props changed)
pypy/dist/pypy/jit/tl/tiny2.py (contents, props changed)
Log:
A "tiny" interpreter, sadly heavily hacked at to be JIT-friendly.
Added: pypy/dist/pypy/jit/tl/targettiny2.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/jit/tl/targettiny2.py Mon Mar 26 10:33:19 2007
@@ -0,0 +1,28 @@
+from pypy.jit.tl import tiny2
+from pypy.jit.codegen.hlinfo import highleveljitinfo
+
+
+def entry_point(args):
+ highleveljitinfo.sys_executable = args[0]
+ bytecode = [s for s in args[1].split(' ') if s != '']
+ args = [tiny2.StrBox(arg) for arg in args[2:]]
+ res = tiny2.interpret(bytecode, args)
+ print res.as_str()
+ return 0
+
+def target(driver, args):
+ return entry_point, None
+
+# ____________________________________________________________
+
+from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy
+
+class MyHintAnnotatorPolicy(HintAnnotatorPolicy):
+ novirtualcontainer = True
+ oopspec = True
+
+ def look_inside_graph(self, graph):
+ return getattr(graph, 'func', None) is not tiny2.myint_internal
+
+def portal(driver):
+ return tiny2.interpret, MyHintAnnotatorPolicy()
Added: pypy/dist/pypy/jit/tl/tiny2.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/jit/tl/tiny2.py Mon Mar 26 10:33:19 2007
@@ -0,0 +1,131 @@
+from pypy.rlib.objectmodel import hint, _is_early_constant
+import sys
+
+
+INVALID = -sys.maxint-1
+
+def myint_internal(s, start=0):
+ if start >= len(s):
+ return INVALID
+ res = 0
+ while start < len(s):
+ c = s[start]
+ n = ord(c) - ord('0')
+ if not (0 <= n <= 9):
+ return INVALID
+ res = res * 10 + n
+ start += 1
+ return res
+
+def myint(s, start=0):
+ if _is_early_constant(s):
+ s = hint(s, promote=True)
+ start = hint(start, promote=True)
+ n = myint_internal(s, start)
+ if n == INVALID:
+ raise ValueError
+ else:
+ n = myint_internal(s, start)
+ if n == INVALID:
+ raise ValueError
+ return n
+
+
+class Box:
+ pass
+
+class IntBox(Box):
+ def __init__(self, intval):
+ self.intval = intval
+ def as_int(self):
+ return self.intval
+ def as_str(self):
+ return str(self.intval)
+
+class StrBox(Box):
+ def __init__(self, strval):
+ self.strval = strval
+ def as_int(self):
+ return myint(self.strval)
+ def as_str(self):
+ return self.strval
+
+
+def func_add_int(ix, iy): return ix + iy
+def func_sub_int(ix, iy): return ix - iy
+def func_mul_int(ix, iy): return ix * iy
+
+def func_add_str(sx, sy): return sx + ' ' + sy
+def func_sub_str(sx, sy): return sx + '-' + sy
+def func_mul_str(sx, sy): return sx + '*' + sy
+
+def op2(stack, func_int, func_str):
+ y = stack.pop()
+ hint(y.__class__, promote=True)
+ x = stack.pop()
+ hint(x.__class__, promote=True)
+ try:
+ z = IntBox(func_int(x.as_int(), y.as_int()))
+ except ValueError:
+ z = StrBox(func_str(x.as_str(), y.as_str()))
+ stack.append(z)
+
+
+def interpret(bytecode, args):
+ hint(None, global_merge_point=True)
+ bytecode = hint(bytecode, deepfreeze=True)
+ # ------------------------------
+ oldargs = args
+ argcount = hint(len(oldargs), promote=True)
+ args = []
+ n = 0
+ while n < argcount:
+ hint(n, concrete=True)
+ args.append(oldargs[n])
+ n += 1
+ # ------------------------------
+ loops = []
+ stack = []
+ pos = 0
+ while pos < len(bytecode):
+ hint(None, global_merge_point=True)
+ opcode = bytecode[pos]
+ hint(opcode, concrete=True)
+ pos += 1
+ if opcode == 'ADD': op2(stack, func_add_int, func_add_str)
+ elif opcode == 'SUB': op2(stack, func_sub_int, func_sub_str)
+ elif opcode == 'MUL': op2(stack, func_mul_int, func_mul_str)
+ elif opcode[0] == '#':
+ n = myint(opcode, start=1)
+ stack.append(args[n-1])
+ elif opcode.startswith('->#'):
+ n = myint(opcode, start=3)
+ args[n-1] = stack.pop()
+ elif opcode == '{':
+ loops.append(pos)
+ elif opcode == '}':
+ if stack.pop().as_int() == 0:
+ loops.pop()
+ else:
+ pos = loops[-1]
+ pos = hint(pos, promote=True)
+ else:
+ stack.append(StrBox(opcode))
+ while len(stack) > 1:
+ op2(stack, func_add_int, func_add_str)
+ return stack.pop()
+
+
+def test_main():
+ main = """#1 5 ADD""".split()
+ res = interpret(main, [IntBox(20)])
+ assert res.as_int() == 25
+ res = interpret(main, [StrBox('foo')])
+ assert res.as_str() == 'foo 5'
+
+FACTORIAL = """The factorial of #1 is
+ 1 { #1 MUL #1 1 SUB ->#1 #1 }""".split()
+
+def test_factorial():
+ res = interpret(FACTORIAL, [IntBox(5)])
+ assert res.as_str() == 'The factorial of 5 is 120'
More information about the Pypy-commit
mailing list