[pypy-svn] r65023 - in pypy/branch/pyjitpl5/pypy/jit/backend/cli: . test
antocuni at codespeak.net
antocuni at codespeak.net
Mon May 4 16:10:48 CEST 2009
Author: antocuni
Date: Mon May 4 16:10:47 2009
New Revision: 65023
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_runner.py
Log:
automatically build various emit_op_* based on the definition in translator/cli/opcodes.py
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Mon May 4 16:10:47 2009
@@ -1,7 +1,9 @@
+import py
from pypy.tool.pairtype import extendabletype
from pypy.rpython.ootypesystem import ootype
from pypy.translator.cli import dotnet
from pypy.translator.cli.dotnet import CLR
+from pypy.translator.cli import opcodes
from pypy.jit.metainterp import history
from pypy.jit.metainterp.history import AbstractValue, Const
from pypy.jit.metainterp.resoperation import rop, opname
@@ -74,6 +76,8 @@
class Method(object):
+ operations = [] # overwritten at the end of the module
+
def __init__(self, cpu, name, loop):
self.cpu = cpu
self.name = name
@@ -145,19 +149,146 @@
def emit_operations(self):
for op in self.loop.operations:
- if op.opnum == rop.INT_LSHIFT:
- for box in op.args:
- box.load(self)
- self.il.Emit(OpCodes.Shl)
- op.result.store(self)
- elif op.opnum == rop.FAIL:
- i = 0
- for box in op.args:
- self.store_inputarg(i, box.type,
- box.getCliType(), box)
- self.il.Emit(OpCodes.Ret)
- else:
- assert False, 'TODO'
+ func = self.operations[op.opnum]
+ assert func is not None
+ func(self, op)
def emit_end(self):
self.il.Emit(OpCodes.Ret)
+
+ # -----------------------------
+
+ def push_all_args(self, op):
+ for box in op.args:
+ box.load(self)
+
+ def store_result(self, op):
+ op.result.store(self)
+
+ def emit_op_fail(self, op):
+ i = 0
+ for box in op.args:
+ self.store_inputarg(i, box.type, box.getCliType(), box)
+ i+=1
+ self.il.Emit(OpCodes.Ret)
+
+ def not_implemented(self, op):
+ raise NotImplementedError
+
+ emit_op_guard_value = not_implemented
+ emit_op_cast_int_to_ptr = not_implemented
+ emit_op_guard_nonvirtualized = not_implemented
+ emit_op_setarrayitem_gc = not_implemented
+ emit_op_guard_false = not_implemented
+ emit_op_unicodelen = not_implemented
+ emit_op_jump = not_implemented
+ emit_op_setfield_raw = not_implemented
+ emit_op_cast_ptr_to_int = not_implemented
+ emit_op_guard_no_exception = not_implemented
+ emit_op_newunicode = not_implemented
+ emit_op_new_array = not_implemented
+ emit_op_unicodegetitem = not_implemented
+ emit_op_strgetitem = not_implemented
+ emit_op_getfield_raw = not_implemented
+ emit_op_setfield_gc = not_implemented
+ emit_op_oosend_pure = not_implemented
+ emit_op_getarrayitem_gc_pure = not_implemented
+ emit_op_arraylen_gc = not_implemented
+ emit_op_guard_true = not_implemented
+ emit_op_unicodesetitem = not_implemented
+ emit_op_getfield_raw_pure = not_implemented
+ emit_op_new_with_vtable = not_implemented
+ emit_op_getfield_gc_pure = not_implemented
+ emit_op_guard_class = not_implemented
+ emit_op_getarrayitem_gc = not_implemented
+ emit_op_getfield_gc = not_implemented
+ emit_op_call_pure = not_implemented
+ emit_op_strlen = not_implemented
+ emit_op_newstr = not_implemented
+ emit_op_guard_exception = not_implemented
+ emit_op_call = not_implemented
+ emit_op_strsetitem = not_implemented
+
+
+# --------------------------------------------------------------------
+
+# the follwing functions automatically build the various emit_op_*
+# operations based on the definitions in translator/cli/opcodes.py
+
+def make_operation_list():
+ operations = [None] * (rop._LAST+1)
+ for key, value in rop.__dict__.items():
+ key = key.lower()
+ if key.startswith('_'):
+ continue
+ methname = 'emit_op_%s' % key
+ if hasattr(Method, methname):
+ func = getattr(Method, methname).im_func
+ else:
+ instrlist = opcodes.opcodes[key]
+ func = render_op(methname, instrlist)
+ operations[value] = func
+ return operations
+
+def render_op(methname, instrlist):
+ lines = []
+ for instr in instrlist:
+ if instr == opcodes.PushAllArgs:
+ lines.append('self.push_all_args(op)')
+ elif instr == opcodes.StoreResult:
+ lines.append('self.store_result(op)')
+ else:
+ if not isinstance(instr, str):
+ print 'WARNING: unknown instruction %s' % instr
+ return
+
+ if instr.startswith('call '):
+ signature = instr[len('call '):]
+ renderCall(lines, signature)
+ else:
+ attrname = opcode2attrname(instr)
+ lines.append('self.il.Emit(OpCodes.%s)' % attrname)
+ body = py.code.Source('\n'.join(lines))
+ src = body.putaround('def %s(self, op):' % methname)
+ dic = {'OpCodes': OpCodes,
+ 'System': System,
+ 'dotnet': dotnet}
+ exec src.compile() in dic
+ return dic[methname]
+
+def opcode2attrname(opcode):
+ if opcode == 'ldc.r8 0':
+ return 'Ldc_R8, 0' # XXX this is a hack
+ if opcode == 'ldc.i8 0':
+ return 'Ldc_I8, 0' # XXX this is a hack
+ parts = map(str.capitalize, opcode.split('.'))
+ return '_'.join(parts)
+
+def renderCall(body, signature):
+ # signature is like this:
+ # int64 class [mscorlib]System.Foo::Bar(int64, int32)
+
+ typenames = {
+ 'int32': 'System.Int32',
+ 'int64': 'System.Int64',
+ 'float64': 'System.Double',
+ }
+
+ restype, _, signature = signature.split(' ', 3)
+ assert signature.startswith('[mscorlib]'), 'external assemblies '\
+ 'not supported'
+ signature = signature[len('[mscorlib]'):]
+ typename, signature = signature.split('::')
+ methname, signature = signature.split('(')
+ assert signature.endswith(')')
+ params = signature[:-1].split(',')
+ params = map(str.strip, params)
+ params = [typenames.get(p, p) for p in params]
+ params = ['dotnet.typeof(%s)' % p for p in params]
+
+ body.append("t = System.Type.GetType('%s')" % typename)
+ body.append("params = dotnet.init_array(System.Type, %s)" % ', '.join(params))
+ body.append("methinfo = t.GetMethod('%s', params)" % methname)
+ body.append("self.il.Emit(OpCodes.Call, methinfo)")
+
+Method.operations = make_operation_list()
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_runner.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_runner.py Mon May 4 16:10:47 2009
@@ -30,7 +30,4 @@
def skip(self):
py.test.skip('in-progress')
- test_uint_rshift = skip
- test_binary_operations = skip
- test_unary_operations = skip
test_ovf_operations = skip
More information about the Pypy-commit
mailing list