[pypy-svn] r51355 - in pypy/dist/pypy: jit/codegen/cli jit/codegen/cli/test translator/cli translator/cli/src

antocuni at codespeak.net antocuni at codespeak.net
Sat Feb 9 15:15:19 CET 2008


Author: antocuni
Date: Sat Feb  9 15:15:17 2008
New Revision: 51355

Modified:
   pypy/dist/pypy/jit/codegen/cli/operation.py
   pypy/dist/pypy/jit/codegen/cli/rgenop.py
   pypy/dist/pypy/jit/codegen/cli/test/test_rgenop.py
   pypy/dist/pypy/translator/cli/dotnet.py
   pypy/dist/pypy/translator/cli/src/pypylib.cs
Log:
- first tentative to add support for GenConsts that contain objects;
  each of those is stored in a static field, but for now only a fixed
  number of those is available;

- improve the automatic generation of Operations from the descriptions in cli/opcodes.py

- as a result, some more tests pass :-)



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	Sat Feb  9 15:15:17 2008
@@ -65,7 +65,37 @@
         self.gv_res().store(self.il)
 
 
+class Call(Operation):
+
+    def __init__(self, il, sigtoken, gv_fnptr, args_gv):
+        from pypy.jit.codegen.cli.rgenop import token2clitype
+        self.il = il
+        self.sigtoken = sigtoken
+        self.gv_fnptr = gv_fnptr
+        self.args_gv = args_gv
+        self._restype = token2clitype(sigtoken[1])
+
+    def restype(self):
+        return self._restype
+
+    def emit(self):
+        from pypy.jit.codegen.cli.rgenop import sigtoken2clitype
+        delegate_type = sigtoken2clitype(self.sigtoken)
+        meth_invoke = delegate_type.GetMethod('Invoke')
+        self.gv_fnptr.load(self.il)
+        self.il.Emit(OpCodes.Castclass, delegate_type)
+        for gv_arg in self.args_gv:
+            gv_arg.load(self.il)
+        self.il.EmitCall(OpCodes.Callvirt, meth_invoke, None)
+        self.storeResult()
+
+        
+
 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)
 
@@ -97,9 +127,37 @@
         elif value is cli_opcodes.DoNothing:
             out[opname] = SameAs
         else:
-            pass # XXX: handle remaining ops
+            renderCustomOp(opname, baseclass, value, out)
     return out
 
+def renderCustomOp(opname, baseclass, steps, out):
+    assert steps
+    body = []
+    for step in steps:
+        if step is cli_opcodes.PushAllArgs:
+            body.append('self.pushAllArgs()')
+        elif step is cli_opcodes.StoreResult:
+            body.append('self.storeResult()')
+        elif isinstance(step, str):
+            if 'call' in step:
+                return # XXX, fix this
+            attrname = opcode2attrname(step)
+            body.append('self.il.Emit(OpCodes.%s)' % attrname)
+        elif isinstance(step, cli_opcodes.MapException):
+            return # XXX, TODO
+        else:
+            return # ignore it for now
+
+    if cli_opcodes.StoreResult not in steps:
+        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())
+    code = source.compile()
+    exec code in globals(), out
+
+
 UNARYOPS = fillops(cli_opcodes.unary_ops, "UnaryOp")
 BINARYOPS = fillops(cli_opcodes.binary_ops, "BinaryOp")
 

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	Sat Feb  9 15:15:17 2008
@@ -7,6 +7,7 @@
 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
 
 def token2clitype(tok):
@@ -96,30 +97,51 @@
     def __repr__(self):
         return "const=%s" % self.value
 
-SM_INT__INT = ootype.StaticMethod([ootype.Signed], ootype.Signed)
-SM_INT__INT_INT = ootype.StaticMethod([ootype.Signed, ootype.Signed], ootype.Signed)
-SM_INT__INT_100 = ootype.StaticMethod([ootype.Signed] * 100, ootype.Signed)
+class BaseConst(GenConst):
+    def __init__(self, num):
+        self.num = num
+        self.fieldname = "const" + str(num)
+
+    def getobj(self):
+        t = typeof(Constants)
+        return t.GetField(self.fieldname).GetValue(None)
+
+    def setobj(self, obj):
+        t = typeof(Constants)
+        t.GetField(self.fieldname).SetValue(None, obj)
 
-class ObjectConst(GenConst):
+    def load(self, il):
+        t = typeof(Constants)
+        field = t.GetField(self.fieldname)
+        il.Emit(OpCodes.Ldsfld, field)
 
-    def __init__(self, obj):
-        self.obj = obj
 
+SM_INT__INT = ootype.StaticMethod([ootype.Signed], ootype.Signed)
+SM_INT__INT_INT = ootype.StaticMethod([ootype.Signed, ootype.Signed], ootype.Signed)
+SM_INT__INT_100 = ootype.StaticMethod([ootype.Signed] * 100, ootype.Signed)
+class FunctionConst(BaseConst):
+    
     @specialize.arg(1)
     def revealconst(self, T):
-        # XXX: probably you can't mix StaticMethod and others OOTypes
         if T == SM_INT__INT:
             DelegateType = CLR.pypy.runtime.DelegateType_int__int
-            return clidowncast(DelegateType, self.obj)
+            return clidowncast(DelegateType, self.getobj())
         elif T == SM_INT__INT_INT:
             DelegateType = CLR.pypy.runtime.DelegateType_int__int_int
-            return clidowncast(DelegateType, self.obj)
+            return clidowncast(DelegateType, self.getobj())
         elif T == SM_INT__INT_100:
             DelegateType = CLR.pypy.runtime.DelegateType_int__int_100
-            return clidowncast(DelegateType, self.obj)
+            return clidowncast(DelegateType, self.getobj())
         else:
-            assert isinstance(T, ootype.OOType)
-            return ootype.oodowncast(T, self.obj)
+            assert False
+
+class ObjectConst(BaseConst):
+
+    @specialize.arg(1)
+    def revealconst(self, T):
+        assert isinstance(T, ootype.OOType)
+        return ootype.oodowncast(T, self.obj)
+
 
 class Label(GenLabel):
     def __init__(self, label, inputargs_gv):
@@ -132,6 +154,13 @@
     def __init__(self):
         self.meth = None
         self.il = None
+        self.constcount = 0
+
+    def newconst(self, cls):
+        assert self.constcount < 3 # the number of static fields declared in Constants
+        res = cls(self.constcount)
+        self.constcount += 1
+        return res
 
     @specialize.genconst(1)
     def genconst(self, llvalue):
@@ -139,7 +168,9 @@
         if T is ootype.Signed:
             return IntConst(llvalue)
         elif isinstance(T, ootype.OOType):
-            return ObjectConst(llvalue)
+            const = self.newconst(ObjectConst)
+            const.setobj(llvalue)
+            return const
         else:
             assert False, "XXX not implemented"
 
@@ -178,10 +209,17 @@
         self.inputargs_gv = []
         for i in range(len(args)):
             self.inputargs_gv.append(GenArgVar(i, args[i]))
-        self.gv_entrypoint = ObjectConst(None) # XXX?
+        self.gv_entrypoint = self.rgenop.newconst(FunctionConst)
         self.sigtoken = sigtoken
         self.isOpen = False
- 
+
+    @specialize.arg(1)
+    def genop1(self, opname, gv_arg):
+        opcls = ops.getopclass1(opname)
+        op = opcls(self.il, gv_arg)
+        self.emit(op)
+        return op.gv_res()
+
     @specialize.arg(1)
     def genop2(self, opname, gv_arg1, gv_arg2):
         opcls = ops.getopclass2(opname)
@@ -189,6 +227,11 @@
         self.emit(op)
         return op.gv_res()
 
+    def genop_call(self, sigtoken, gv_fnptr, args_gv):
+        op = ops.Call(self.il, sigtoken, gv_fnptr, args_gv)
+        self.emit(op)
+        return op.gv_res()
+        
     def emit(self, op):
         op.emit()
 
@@ -212,7 +255,7 @@
     def end(self):
         delegate_type = sigtoken2clitype(self.sigtoken)
         myfunc = self.meth.CreateDelegate(delegate_type)
-        self.gv_entrypoint.obj = myfunc
+        self.gv_entrypoint.setobj(myfunc)
 
     def enter_next_block(self, kinds, args_gv):
         for i in range(len(args_gv)):

Modified: pypy/dist/pypy/jit/codegen/cli/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/cli/test/test_rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/cli/test/test_rgenop.py	Sat Feb  9 15:15:17 2008
@@ -10,10 +10,13 @@
         'test_adder',
         'test_dummy',
         'test_hide_and_reveal',
-        'test_hide_and_reveal_p',
+        # 'test_hide_and_reveal_p', # think about this
         'test_largedummy_direct', # _compile works if we set a higher maxstack
         'test_branching',
         'test_goto',
+        'test_if',
+        # 'test_switch', # no promotion/flexswitch for now please :-)
+        'test_fact',
         ]
 
     for p in prefixes:
@@ -38,7 +41,7 @@
     def cast(self, gv, nb_args):
         "NOT_RPYTHON"
         def fn(*args):
-            return gv.obj.Invoke(*args)
+            return gv.getobj().Invoke(*args)
         return fn
 
     def directtesthelper(self, FUNCTYPE, func):

Modified: pypy/dist/pypy/translator/cli/dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/dotnet.py	(original)
+++ pypy/dist/pypy/translator/cli/dotnet.py	Sat Feb  9 15:15:17 2008
@@ -306,7 +306,7 @@
             self._load_class()
             return getattr(self._PythonNet_class, attr)
         else:
-            raise AttributeError
+            raise AttributeError, attr
 
     def __call__(self, *args):
         self._load_class()

Modified: pypy/dist/pypy/translator/cli/src/pypylib.cs
==============================================================================
--- pypy/dist/pypy/translator/cli/src/pypylib.cs	(original)
+++ pypy/dist/pypy/translator/cli/src/pypylib.cs	Sat Feb  9 15:15:17 2008
@@ -59,6 +59,7 @@
 
     public class Constants
     {
+        public static object const0;
         public static object const1;
         public static object const2;
     }



More information about the Pypy-commit mailing list