[pypy-svn] r51366 - pypy/dist/pypy/jit/codegen/cli
antocuni at codespeak.net
antocuni at codespeak.net
Sun Feb 10 12:37:01 CET 2008
Author: antocuni
Date: Sun Feb 10 12:37:01 2008
New Revision: 51366
Added:
pypy/dist/pypy/jit/codegen/cli/dumpgenerator.py (contents, props changed)
Modified:
pypy/dist/pypy/jit/codegen/cli/operation.py
pypy/dist/pypy/jit/codegen/cli/rgenop.py
Log:
don't render operations on BranchBuilder on the fly, but save them to
be rendered later; this is needed when calling pause().
Added: pypy/dist/pypy/jit/codegen/cli/dumpgenerator.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/jit/codegen/cli/dumpgenerator.py Sun Feb 10 12:37:01 2008
@@ -0,0 +1,33 @@
+class DumpGenerator:
+ def __init__(self, il, filename='dynamicmethod.il'):
+ self.il = il
+ self.out = file(filename, 'w')
+ self.localcount = 0
+ self.labels = {}
+
+ def _fmt(self, arg):
+ from System.Reflection import Emit
+ if isinstance(arg, Emit.LocalBuilder):
+ return 'v%d' % arg.LocalIndex
+ elif isinstance(arg, Emit.Label):
+ return 'label%d' % self.labels[arg]
+ return repr(arg)
+
+ def Emit(self, opcode, *args):
+ arglist = ', '.join(map(self._fmt, args))
+ self.out.write(' %s %s\n' % (opcode.Name, arglist))
+ return self.il.Emit(opcode, *args)
+
+ def DeclareLocal(self, t):
+ return self.il.DeclareLocal(t)
+
+ def DefineLabel(self):
+ lbl = self.il.DefineLabel()
+ count = len(self.labels)
+ self.labels[lbl] = count
+ return lbl
+
+ def MarkLabel(self, lbl):
+ self.out.write('\n%s:\n' % self._fmt(lbl))
+ return self.il.MarkLabel(lbl)
+
Modified: pypy/dist/pypy/jit/codegen/cli/operation.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/cli/operation.py (original)
+++ pypy/dist/pypy/jit/codegen/cli/operation.py Sun Feb 10 12:37:01 2008
@@ -65,6 +65,51 @@
self.gv_res().store(self.il)
+class FollowLink(Operation):
+
+ def __init__(self, il, outputargs_gv, inputargs_gv, label):
+ self.il = il
+ self.outputargs_gv = outputargs_gv
+ self.inputargs_gv = inputargs_gv
+ self.label = label
+
+ def restype(self):
+ return None
+
+ def emit(self):
+ for i in range(len(self.outputargs_gv)):
+ self.outputargs_gv[i].load(self.il)
+ self.inputargs_gv[i].store(self.il)
+ self.il.Emit(OpCodes.Br, self.label)
+
+class BranchIf(Operation):
+
+ def __init__(self, il, gv_cond, opcode, label):
+ self.il = il
+ self.gv_cond = gv_cond
+ self.opcode = opcode
+ self.label = label
+
+ def restype(self):
+ return None
+
+ def emit(self):
+ self.gv_cond.load(self.il)
+ self.il.Emit(self.opcode, self.label)
+
+class Return(Operation):
+
+ def __init__(self, il, gv_x):
+ self.il = il
+ self.gv_x = gv_x
+
+ def restype(self):
+ return None
+
+ def emit(self):
+ self.gv_x.load(self.il)
+ self.il.Emit(OpCodes.Ret)
+
class Call(Operation):
def __init__(self, il, sigtoken, gv_fnptr, args_gv):
Modified: pypy/dist/pypy/jit/codegen/cli/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/cli/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/cli/rgenop.py Sun Feb 10 12:37:01 2008
@@ -4,12 +4,15 @@
from pypy.jit.codegen.model import AbstractRGenOp, GenBuilder, GenLabel
from pypy.jit.codegen.model import GenVarOrConst, GenVar, GenConst, CodeGenSwitch
from pypy.jit.codegen.cli import operation as ops
+from pypy.jit.codegen.cli.dumpgenerator import DumpGenerator
from pypy.translator.cli.dotnet import CLR, typeof, new_array, clidowncast
System = CLR.System
Utils = CLR.pypy.runtime.Utils
Constants = CLR.pypy.runtime.Constants
OpCodes = System.Reflection.Emit.OpCodes
+DEBUG = False
+
def token2clitype(tok):
if tok == '<Signed>':
return typeof(System.Int32)
@@ -199,19 +202,24 @@
return builder, builder.gv_entrypoint, builder.inputargs_gv[:]
-
class Builder(GenBuilder):
def __init__(self, rgenop, name, res, args, sigtoken):
self.rgenop = rgenop
self.meth = Utils.CreateDynamicMethod(name, res, args)
self.il = self.meth.GetILGenerator()
+ if DEBUG:
+ self.il = DumpGenerator(self.il)
self.inputargs_gv = []
for i in range(len(args)):
self.inputargs_gv.append(GenArgVar(i, args[i]))
self.gv_entrypoint = self.rgenop.newconst(FunctionConst)
self.sigtoken = sigtoken
self.isOpen = False
+ self.operations = []
+ self.branches = []
+ self.retlabel = self.il.DefineLabel()
+ self.gv_returnvar = None
@specialize.arg(1)
def genop1(self, opname, gv_arg):
@@ -235,24 +243,35 @@
def emit(self, op):
op.emit()
+ def appendbranch(self, branch):
+ self.branches.append(branch)
+
def start_writing(self):
self.isOpen = True
def finish_and_return(self, sigtoken, gv_returnvar):
- gv_returnvar.load(self.il)
- self.il.Emit(OpCodes.Ret)
+ self.il.Emit(OpCodes.Br, self.retlabel)
+ self.gv_returnvar = gv_returnvar
self.isOpen = False
def finish_and_goto(self, outputargs_gv, target):
inputargs_gv = target.inputargs_gv
assert len(inputargs_gv) == len(outputargs_gv)
- for i in range(len(outputargs_gv)):
- outputargs_gv[i].load(self.il)
- inputargs_gv[i].store(self.il)
- self.il.Emit(OpCodes.Br, target.label)
+ op = ops.FollowLink(self.il, outputargs_gv, inputargs_gv, target.label)
+ self.emit(op)
self.isOpen = False
def end(self):
+ # render all the pending branches
+ for branch in self.branches:
+ branch.replayops()
+
+ # render the return block for last, else the verifier could complain
+ self.il.MarkLabel(self.retlabel)
+ op = ops.Return(self.il, self.gv_returnvar)
+ self.emit(op)
+
+ # build the delegate
delegate_type = sigtoken2clitype(self.sigtoken)
myfunc = self.meth.CreateDelegate(delegate_type)
self.gv_entrypoint.setobj(myfunc)
@@ -268,9 +287,11 @@
def _jump_if(self, gv_condition, opcode):
label = self.il.DefineLabel()
- gv_condition.load(self.il)
- self.il.Emit(opcode, label)
- return BranchBuilder(self, label)
+ op = ops.BranchIf(self.il, gv_condition, opcode, label)
+ self.emit(op)
+ branch = BranchBuilder(self, label)
+ self.appendbranch(branch)
+ return branch
def jump_if_false(self, gv_condition, args_for_jump_gv):
return self._jump_if(gv_condition, OpCodes.Brfalse)
@@ -284,12 +305,11 @@
self.parent = parent
self.label = label
self.il = parent.il
+ self.operations = []
self.isOpen = False
def start_writing(self):
- assert not self.parent.isOpen
self.isOpen = True
- self.il.MarkLabel(self.label)
@specialize.arg(1)
def genop2(self, opname, gv_arg1, gv_arg2):
@@ -297,3 +317,22 @@
# feel like fixing now. Try to uncomment this and run
# test_goto_compile to see why it fails
return Builder.genop2(self, opname, gv_arg1, gv_arg2)
+
+ def finish_and_return(self, sigtoken, gv_returnvar):
+ op = ops.Return(self.parent.il, gv_returnvar)
+ self.emit(op)
+ self.isOpen = False
+
+ def emit(self, op):
+ self.operations.append(op)
+
+ def appendbranch(self, branch):
+ self.parent.appendbranch(branch)
+
+ def replayops(self):
+ assert not self.isOpen
+ assert not self.parent.isOpen
+ il = self.parent.il
+ il.MarkLabel(self.label)
+ for op in self.operations:
+ op.emit()
More information about the Pypy-commit
mailing list