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

antocuni at codespeak.net antocuni at codespeak.net
Fri Feb 15 17:07:17 CET 2008


Author: antocuni
Date: Fri Feb 15 17:07:16 2008
New Revision: 51542

Modified:
   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:
make the cli jit backend using the new box/unbox interface to cast
delegates to static methods. Moreover, FunctionConsts are now properly
handled just like other ObjectConsts, instead of being stored into
static fields of the old Constant class.




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	Fri Feb 15 17:07:16 2008
@@ -5,10 +5,10 @@
 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
+from pypy.translator.cli.dotnet import CLR, typeof, new_array, box, unbox
 System = CLR.System
 Utils = CLR.pypy.runtime.Utils
-Constants = CLR.pypy.runtime.Constants
+DelegateHolder = CLR.pypy.runtime.DelegateHolder
 OpCodes = System.Reflection.Emit.OpCodes
 
 DUMP_IL = False
@@ -112,53 +112,67 @@
     def __repr__(self):
         return "const=%s" % self.value
 
-class FunctionConst(GenConst):
-    
-    def __init__(self, num):
-        self.num = num
-        self.fieldname = "const" + str(num)
+class BaseConst(GenConst):
+
+    def _get_index(self, builder):
+        # check whether there is already an index associated to this const
+        try:
+            index = builder.genconsts[self]
+        except KeyError:
+            index = len(builder.genconsts)
+            builder.genconsts[self] = index
+        return index
+
+    def _load_from_array(self, builder, index, clitype):
+        builder.il.Emit(OpCodes.Ldarg_0)
+        builder.il.Emit(OpCodes.Ldc_I4, index)
+        builder.il.Emit(OpCodes.Ldelem_Ref)
+        builder.il.Emit(OpCodes.Castclass, clitype)
 
     def getobj(self):
-        t = typeof(Constants)
-        return t.GetField(self.fieldname).GetValue(None)
+        raise NotImplementedError
+
+class ObjectConst(BaseConst):
+
+    def __init__(self, obj):
+        self.obj = obj
 
-    def setobj(self, obj):
-        t = typeof(Constants)
-        t.GetField(self.fieldname).SetValue(None, obj)
+    def getobj(self):
+        return self.obj
 
     def load(self, builder):
-        t = typeof(Constants)
-        field = t.GetField(self.fieldname)
-        builder.il.Emit(OpCodes.Ldsfld, field)
+        index = self._get_index(builder)
+        t = self.obj.GetType()
+        self._load_from_array(builder, index, t)
 
     @specialize.arg(1)
     def revealconst(self, T):
-        return clidowncast(self.getobj(), T)
+        assert isinstance(T, ootype.OOType)
+        return unbox(self.obj, T)
 
-class ObjectConst(GenConst):
 
-    def __init__(self, obj):
-        self.obj = obj
+class FunctionConst(BaseConst):
 
-    def load(self, builder):
-        # check whether there is already an index associated to this const
-        try:
-            index = builder.genconsts[self.obj]
-        except KeyError:
-            index = len(builder.genconsts)
-            builder.genconsts[self.obj] = index
+    def __init__(self, delegatetype):
+        self.holder = DelegateHolder()
+        self.delegatetype = delegatetype
 
-        t = self.obj.GetType()
-        builder.il.Emit(OpCodes.Ldarg_0)
-        builder.il.Emit(OpCodes.Ldc_i4, index)
-        builder.il.Emit(OpCodes.Ldelem_ref)
-        builder.il.Emit(OpCodes.Castclass, t)
+    def getobj(self):
+        return self.holder
+
+    def load(self, builder):
+        holdertype = box(self.holder).GetType()
+        funcfield = holdertype.GetField('func')
+        delegatetype = self.delegatetype
+        index = self._get_index(builder)
+        self._load_from_array(builder, index, holdertype)
+        builder.il.Emit(OpCodes.Ldfld, funcfield)
+        builder.il.Emit(OpCodes.Castclass, delegatetype)
 
     @specialize.arg(1)
     def revealconst(self, T):
         assert isinstance(T, ootype.OOType)
-        return ootype.oodowncast(T, self.obj)
-
+        return unbox(self.holder.GetFunc(), T)
 
 class Label(GenLabel):
     def __init__(self, label, inputargs_gv):
@@ -173,12 +187,6 @@
         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):
         T = ootype.typeOf(llvalue)
@@ -187,7 +195,7 @@
         elif T is ootype.Bool:
             return IntConst(int(llvalue))
         elif isinstance(T, ootype.OOType):
-            return ObjectConst(llvalue)
+            return ObjectConst(box(llvalue))
         else:
             assert False, "XXX not implemented"
 
@@ -229,8 +237,8 @@
         # we start from 1 because the 1st arg is an Object[] containing the genconsts
         for i in range(1, len(args)):
             self.inputargs_gv.append(GenArgVar(i, args[i]))
-        self.gv_entrypoint = self.rgenop.newconst(FunctionConst)
-        self.sigtoken = sigtoken
+        self.delegatetype = sigtoken2clitype(sigtoken)
+        self.gv_entrypoint = FunctionConst(self.delegatetype)
         self.isOpen = False
         self.operations = []
         self.branches = []
@@ -250,7 +258,6 @@
             self.il.EmitWriteLine('')
         return gv_res
     
-
     @specialize.arg(1)
     def genop2(self, opname, gv_arg1, gv_arg2):
         opcls = ops.getopclass2(opname)
@@ -322,12 +329,11 @@
 
         # initialize the array of genconsts
         consts = new_array(System.Object, len(self.genconsts))
-        for obj, i in self.genconsts.iteritems():
-            consts[i] = obj
+        for gv_const, i in self.genconsts.iteritems():
+            consts[i] = gv_const.getobj()
         # build the delegate
-        delegate_type = sigtoken2clitype(self.sigtoken)
-        myfunc = self.meth.CreateDelegate(delegate_type, consts)
-        self.gv_entrypoint.setobj(myfunc)
+        myfunc = self.meth.CreateDelegate(self.delegatetype, consts)
+        self.gv_entrypoint.holder.SetFunc(myfunc)
 
     def enter_next_block(self, kinds, args_gv):
         for i in range(len(args_gv)):
@@ -360,6 +366,7 @@
         self.il = parent.il
         self.operations = []
         self.isOpen = False
+        self.genconsts = parent.genconsts
 
     def start_writing(self):
         self.isOpen = True

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	Fri Feb 15 17:07:16 2008
@@ -61,12 +61,12 @@
     def getcompiled(self, fn, annotation, annotatorpolicy):
         return compile_function(fn, annotation,
                                 annotatorpolicy=annotatorpolicy,
-                                nowrap=True)
+                                nowrap=False)
 
     def cast(self, gv, nb_args):
         "NOT_RPYTHON"
         def fn(*args):
-            return gv.getobj().Invoke(*args)
+            return gv.getobj().func.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	Fri Feb 15 17:07:16 2008
@@ -445,7 +445,8 @@
             return OverloadingResolver.lltype_to_annotation(TYPE)
 
     def specialize_call(self, hop):
-        TYPE = hop.args_v[1].value
+        assert hop.args_s[1].is_constant()
+        TYPE = hop.args_s[1].const
         v_obj = hop.inputarg(hop.args_r[0], arg=0)
         if TYPE is ootype.String or isinstance(TYPE, (type, types.ClassType)) or isinstance(TYPE, ootype.OOType):
             return hop.genop('oodowncast', [v_obj], hop.r_result.lowleveltype)

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	Fri Feb 15 17:07:16 2008
@@ -59,11 +59,21 @@
 
 namespace pypy.runtime
 {
-    public class Constants
+
+    public class DelegateHolder
     {
-        public static object const0;
-        public static object const1;
-        public static object const2;
+        public Delegate func;
+
+        // we need getter and setter because we can't directly access fields from RPython
+        public void SetFunc(Delegate func)
+        {
+            this.func = func;
+        }
+
+        public Delegate GetFunc()
+        {
+            return this.func;
+        }
     }
 
     public class Utils



More information about the Pypy-commit mailing list