[pypy-svn] r61782 - pypy/branch/oo-jit/pypy/jit/codegen/cli

antocuni at codespeak.net antocuni at codespeak.net
Thu Feb 12 14:53:55 CET 2009


Author: antocuni
Date: Thu Feb 12 14:53:53 2009
New Revision: 61782

Modified:
   pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py
   pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py
Log:
automatically generate *_ovf and *_zer operations



Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py	Thu Feb 12 14:53:53 2009
@@ -347,12 +347,13 @@
     def getExceptionType(self):
         raise NotImplementedError
 
+    def emit_op(self):
+        raise NotImplementedError
+
     def emit(self):
         il = self.meth.il
         lbl = il.BeginExceptionBlock()
-        self.pushAllArgs()
-        il.Emit(self.getOpCode())
-        self.storeResult()
+        self.emit_op()
         il.Emit(OpCodes.Leave, lbl)
         il.BeginCatchBlock(self.getExceptionType())
         il.Emit(OpCodes.Ldc_I4, 1)
@@ -360,6 +361,7 @@
         il.EndExceptionBlock()
 
 
+
 class RaisingBinaryOp(CatchAndRaiseMixin, BinaryOp):
     pass
 
@@ -405,12 +407,11 @@
     out = {}
     for opname, value in ops.iteritems():
         renderOp(baseclass, opname, value, out)
-
     return out
 
-def renderOp(baseclass, opname, value, out, optional_lines=''):
+def renderOp(baseclass, opname, value, out):
     if isinstance(value, str):
-        renderSimpleOp(baseclass, opname, value, out, optional_lines)
+        renderSimpleOp(baseclass, opname, value, out)
     elif value is cli_opcodes.DoNothing:
         # create a new subclass of SameAs; we can't use SameAs directly
         # because its restype could be patched later
@@ -419,9 +420,9 @@
         assert isinstance(value, list)
         steps = value
         if len(steps) == 1 and isinstance(steps[0], cli_opcodes.MapException):
-            #renderRaisingOp(baseclass, opname, steps[0], out)
-            return # XXX
-        renderCustomOp(baseclass, opname, value, out)
+            renderRaisingOp(baseclass, opname, steps[0], out)
+        else:
+            renderCustomOp(baseclass, opname, value, out)
 
     # fix the restype for comparison ops and casts
     if is_comparison(opname):
@@ -431,41 +432,19 @@
         funcname = 'restype_%s' % to
         out[opname].restype = globals()[funcname]
 
-def renderSimpleOp(baseclass, opname, value, out, optional_lines=''):
+
+def renderSimpleOp(baseclass, opname, value, out):
     attrname = opcode2attrname(value)
     source = py.code.Source("""
     class %(opname)s (%(baseclass)s):
         def getOpCode(self):
             return OpCodes.%(attrname)s
-
-%(optional_lines)s
     """ % locals())
     code = source.compile()
     exec code in globals(), out
 
-## def get_exctype(exctype_str):
-##     if exctype_str == '[mscorlib]System.OverflowException':
-##         return typeof(System.OverflowException)
-##     elif exctype_str == '[mscorlib]System.DivideByZeroException':
-##         return typeof(System.DivideByZeroException)
-##     else:
-##         assert False, 'Unknown exception type'
-
-## def renderRaisingOp(baseclass, opname, value, out):
-##     mapping = value.mapping
-##     assert len(mapping) == 1, 'Catching more than one exception is not supported'
-##     exctype = mapping[0][0]
-##     assert exctype.startswith('[mscorlib]')
-##     exctype = exctype[len('[mscorlib]'):]
-##     source = """
-##         def getExceptionType(self):
-##             return typeof(%(exctype)s)
-##     """ % locals()
-##     baseclass = 'Raising' + baseclass
-##     renderOp(baseclass, opname, value.instr, out, source)
 
-
-def renderCustomOp(baseclass, opname, steps, out):
+def renderCustomOp(baseclass, opname, steps, out, emitName='emit', optional_lines=''):
     assert steps
     body = []
     for step in steps:
@@ -479,7 +458,9 @@
             attrname = opcode2attrname(step)
             body.append('self.meth.il.Emit(OpCodes.%s)' % attrname)
         elif isinstance(step, cli_opcodes.MapException):
-            return # XXX, TODO
+            # MapException is supported only if it's the only element of the
+            # instr list, look inside RenderOp
+            assert False, 'MapException not supported here'
         else:
             return # ignore it for now
 
@@ -487,12 +468,39 @@
         body.append('self.storeResult()')
 
     emit = py.code.Source('\n'.join(body))
-    emit = emit.putaround('def emit(self):')
-    source = emit.putaround('class %(opname)s (%(baseclass)s):' % locals())
+    emit = emit.putaround('def %s(self):' % emitName).indent(' '*8)
+    source = py.code.Source("""
+    class %(opname)s (%(baseclass)s):
+%(emit)s
+%(optional_lines)s
+    """ % locals())
+
     code = source.compile()
     exec code in globals(), out
 
 
+def renderRaisingOp(baseclass, opname, value, out):
+    mapping = value.mapping
+    assert len(mapping) == 1, 'Catching more than one exception is not supported'
+    exctype = mapping[0][0]
+    assert exctype.startswith('[mscorlib]')
+    exctype = exctype[len('[mscorlib]'):]
+    source = """
+        def getExceptionType(self):
+            return typeof(%(exctype)s)
+    """ % locals()
+    baseclass = 'Raising' + baseclass
+    renderCustomOp(baseclass, opname, value.instr, out, 'emit_op', source)
+
+def get_exctype(exctype_str):
+    if exctype_str == '[mscorlib]System.OverflowException':
+        return typeof(System.OverflowException)
+    elif exctype_str == '[mscorlib]System.DivideByZeroException':
+        return typeof(System.DivideByZeroException)
+    else:
+        assert False, 'Unknown exception type'
+
+
 UNARYOPS = fillops(cli_opcodes.unary_ops, "UnaryOp")
 BINARYOPS = fillops(cli_opcodes.binary_ops, "BinaryOp")
 

Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py	Thu Feb 12 14:53:53 2009
@@ -818,15 +818,12 @@
 
     @specialize.arg(1)
     def genraisingop2(self, opname, gv_arg1, gv_arg2):
-        if opname == 'int_add_ovf':
-            opcls = ops.IntAddOvf
-            op = opcls(self.meth, gv_arg1, gv_arg2)
-            self.appendop(op)
-            gv_res = op.gv_res()
-            gv_excflag = op.gv_excflag()
-            return gv_res, gv_excflag
-        else:
-            assert False
+        opcls = ops.getopclass2(opname)
+        op = opcls(self.meth, gv_arg1, gv_arg2)
+        self.appendop(op)
+        gv_res = op.gv_res()
+        gv_excflag = op.gv_excflag()
+        return gv_res, gv_excflag
 
     def genop_call(self, sigtoken, gv_fnptr, args_gv):
         op = ops.Call(self.meth, sigtoken, gv_fnptr, args_gv)



More information about the Pypy-commit mailing list