[pypy-svn] r51428 - in pypy/dist/pypy: rpython/ootypesystem translator/cli translator/cli/src translator/cli/test

antocuni at codespeak.net antocuni at codespeak.net
Wed Feb 13 10:06:15 CET 2008


Author: antocuni
Date: Wed Feb 13 10:06:14 2008
New Revision: 51428

Modified:
   pypy/dist/pypy/rpython/ootypesystem/rootype.py
   pypy/dist/pypy/translator/cli/dotnet.py
   pypy/dist/pypy/translator/cli/metavm.py
   pypy/dist/pypy/translator/cli/query.py
   pypy/dist/pypy/translator/cli/src/pypylib.cs
   pypy/dist/pypy/translator/cli/test/test_dotnet.py
Log:
a much saner approach to handle dynamically generated delegates; they
are converted to the equivalent StaticMethod, and called by
indirect_call; this way, gencli automatically handles the generation
of the corresponding delegate class.

Hardcoded delegate classes are still used but only for testing, when
we interprets things on pythonnet, so they have been moved to the
pypy.test namespace.



Modified: pypy/dist/pypy/rpython/ootypesystem/rootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rootype.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rootype.py	Wed Feb 13 10:06:14 2008
@@ -105,6 +105,12 @@
     def __init__(self, METHODTYPE):
         self.lowleveltype = METHODTYPE
 
+    def rtype_simple_call(self, hop):
+        vlist = hop.inputargs(*hop.args_r)
+        cgraphs = hop.inputconst(ootype.Void, None)
+        vlist.append(cgraphs)
+        return hop.genop("indirect_call", vlist, resulttype = hop.r_result.lowleveltype)
+
 
 class __extend__(pairtype(OOInstanceRepr, OOBoundMethRepr)):
 

Modified: pypy/dist/pypy/translator/cli/dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/dotnet.py	(original)
+++ pypy/dist/pypy/translator/cli/dotnet.py	Wed Feb 13 10:06:14 2008
@@ -2,7 +2,7 @@
 
 from pypy.tool.pairtype import pair, pairtype
 from pypy.annotation.model import SomeObject, SomeInstance, SomeOOInstance, SomeInteger, s_None,\
-     s_ImpossibleValue, lltype_to_annotation, annotation_to_lltype, SomeChar, SomeString, SomePBC
+     s_ImpossibleValue, lltype_to_annotation, annotation_to_lltype, SomeChar, SomeString, SomeOOStaticMeth
 from pypy.annotation.unaryop import immutablevalue
 from pypy.annotation.binaryop import _make_none_union
 from pypy.annotation import model as annmodel
@@ -534,8 +534,13 @@
             hop.genop('cli_setelem', [v_array, c_index, v_elem], ootype.Void)
         return v_array
 
-
-def typeof(cliClass):
+def typeof(cliClass_or_type):
+    if isinstance(cliClass_or_type, ootype.StaticMethod):
+        FUNCTYPE = cliClass_or_type
+        cliClass = known_delegates[FUNCTYPE]
+    else:
+        assert isinstance(cliClass_or_type, CliClass)
+        cliClass = cliClass_or_type
     TYPE = cliClass._INSTANCE
     return PythonNet.System.Type.GetType(TYPE._assembly_qualified_name)
 
@@ -571,25 +576,37 @@
         return hop.genop('cli_eventhandler', [v_obj, c_methodname], hop.r_result.lowleveltype)
 
 
-def clidowncast(cliClass, obj):
+def clidowncast(obj, TYPE):
     return obj
 
 class Entry(ExtRegistryEntry):
     _about_ = clidowncast
 
-    def compute_result_annotation(self, s_type, s_value):
-        assert s_type.is_constant()
-        cliClass = s_type.const
-        TYPE = cliClass._INSTANCE
-        assert ootype.isSubclass(TYPE, s_value.ootype)
-        return SomeOOInstance(TYPE)
+    def compute_result_annotation(self, s_value, s_type):
+        if isinstance(s_type.const, ootype.OOType):
+            TYPE = s_type.const
+        else:
+            cliClass = s_type.const
+            TYPE = cliClass._INSTANCE
+        if isinstance(TYPE, ootype.StaticMethod):
+            assert ootype.isSubclass(s_value.ootype, CLR.System.Delegate._INSTANCE)
+            return SomeOOStaticMeth(TYPE)
+        else:
+            assert ootype.isSubclass(TYPE, s_value.ootype)
+            return SomeOOInstance(TYPE)
 
     def specialize_call(self, hop):
-        assert isinstance(hop.args_s[0].const, CliClass)
-        assert isinstance(hop.args_s[1], annmodel.SomeOOInstance)
-        v_inst = hop.inputarg(hop.args_r[1], arg=1)
+        assert isinstance(hop.args_s[0], annmodel.SomeOOInstance)
+        v_inst = hop.inputarg(hop.args_r[0], arg=0)
         return hop.genop('oodowncast', [v_inst], resulttype = hop.r_result.lowleveltype)
 
 from pypy.translator.cli.query import CliNamespace
 CLR = CliNamespace(None)
 CLR._buildtree()
+
+known_delegates = {
+    ootype.StaticMethod([ootype.Signed], ootype.Signed):       CLR.pypy.test.DelegateType_int__int_1,
+    ootype.StaticMethod([ootype.Signed] * 2, ootype.Signed):   CLR.pypy.test.DelegateType_int__int_2,
+    ootype.StaticMethod([ootype.Signed] * 3, ootype.Signed):   CLR.pypy.test.DelegateType_int__int_3,
+    ootype.StaticMethod([ootype.Signed] * 100, ootype.Signed): CLR.pypy.test.DelegateType_int__int_100
+    }

Modified: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/cli/metavm.py	(original)
+++ pypy/dist/pypy/translator/cli/metavm.py	Wed Feb 13 10:06:14 2008
@@ -191,10 +191,14 @@
 
 class _TypeOf(MicroInstruction):
     def render(self, generator, op):
-        v_type, = op.args
-        assert v_type.concretetype is ootype.Void
-        cliClass = v_type.value
-        fullname = cliClass._INSTANCE._name
+        c_type, = op.args
+        assert c_type.concretetype is ootype.Void
+        if isinstance(c_type.value, ootype.StaticMethod):
+            FUNC = c_type.value
+            fullname = generator.cts.lltype_to_cts(FUNC)
+        else:
+            cliClass = c_type.value
+            fullname = cliClass._INSTANCE._name
         generator.ilasm.opcode('ldtoken', fullname)
         generator.ilasm.call('class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)')
 

Modified: pypy/dist/pypy/translator/cli/query.py
==============================================================================
--- pypy/dist/pypy/translator/cli/query.py	(original)
+++ pypy/dist/pypy/translator/cli/query.py	Wed Feb 13 10:06:14 2008
@@ -229,6 +229,7 @@
             parent, name = fullname.rsplit('.', 1)
             parent = getattr_ex(self, parent)
             setattr(parent, name, placeholder)
+        self.System.Object # XXX hack
 
     def __getattribute__(self, attr):
         value = object.__getattribute__(self, attr)

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	Wed Feb 13 10:06:14 2008
@@ -49,15 +49,16 @@
             return string.Format("ExceptionWrapper('{0}')", obj.GetType().FullName);
         }
     }
-}
 
-namespace pypy.runtime
-{
     public delegate int DelegateType_int__int_1(int a);
     public delegate int DelegateType_int__int_2(int a, int b);
     public delegate int DelegateType_int__int_3(int a, int b, int c);
     public delegate int DelegateType_int__int_100(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20, int a21, int a22, int a23, int a24, int a25, int a26, int a27, int a28, int a29, int a30, int a31, int a32, int a33, int a34, int a35, int a36, int a37, int a38, int a39, int a40, int a41, int a42, int a43, int a44, int a45, int a46, int a47, int a48, int a49, int a50, int a51, int a52, int a53, int a54, int a55, int a56, int a57, int a58, int a59, int a60, int a61, int a62, int a63, int a64, int a65, int a66, int a67, int a68, int a69, int a70, int a71, int a72, int a73, int a74, int a75, int a76, int a77, int a78, int a79, int a80, int a81, int a82, int a83, int a84, int a85, int a86, int a87, int a88, int a89, int a90, int a91, int a92, int a93, int a94, int a95, int a96, int a97, int a98, int a99);
 
+}
+
+namespace pypy.runtime
+{
     public class Constants
     {
         public static object const0;

Modified: pypy/dist/pypy/translator/cli/test/test_dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_dotnet.py	(original)
+++ pypy/dist/pypy/translator/cli/test/test_dotnet.py	Wed Feb 13 10:06:14 2008
@@ -13,21 +13,8 @@
 ArrayList = CLR.System.Collections.ArrayList
 OpCodes = System.Reflection.Emit.OpCodes
 DynamicMethod = System.Reflection.Emit.DynamicMethod
-DelegateType = CLR.pypy.runtime.DelegateType_int__int_int
 Utils = CLR.pypy.runtime.Utils
-
-# RPython function, used by test_dynamic_method and test_call_delegate
-def build_fn():
-    tInt = typeof(System.Int32)
-    args = init_array(System.Type, tInt, tInt)
-    meth = Utils.CreateDynamicMethod("add", tInt, args)
-    il = meth.GetILGenerator()
-    il.Emit(OpCodes.Ldarg_0)
-    il.Emit(OpCodes.Ldarg_1)
-    il.Emit(OpCodes.Add)
-    il.Emit(OpCodes.Ret)
-    myfunc = meth.CreateDelegate(typeof(DelegateType))
-    return clidowncast(DelegateType, myfunc)
+FUNCTYPE = ootype.StaticMethod([ootype.Signed, ootype.Signed], ootype.Signed)
 
 class TestDotnetAnnotation(object):
 
@@ -371,19 +358,40 @@
         assert res is True
 
     def test_typeof_pypylib(self):
-        DelegateType = CLR.pypy.runtime.DelegateType_int__int_int
+        DelegateType = CLR.pypy.test.DelegateType_int__int_2
         def fn():
             return typeof(DelegateType) is not None
         res = self.interpret(fn, [])
         assert res is True
 
+    def test_typeof_functype(self):
+        # this test is overridden in TestPythonnet
+        def fn():
+            t = typeof(FUNCTYPE)
+            return t.get_Name()
+        res = self.interpret(fn, [])
+        assert res.startswith('StaticMethod__')
+
     def test_clidowncast(self):
         def fn():
             a = ArrayList()
             b = ArrayList()
             a.Add(b)
             c = a.get_Item(0) # type of c is Object
-            c = clidowncast(ArrayList, c)
+            c = clidowncast(c, ArrayList)
+            c.Add(None)
+            return c.get_Item(0)
+        res = self.interpret(fn, [])
+        assert res is None
+
+    def test_clidowncast_lltype(self):
+        ARRAY_LIST = ArrayList._INSTANCE
+        def fn():
+            a = ArrayList()
+            b = ArrayList()
+            a.Add(b)
+            c = a.get_Item(0) # type of c is Object
+            c = clidowncast(c, ARRAY_LIST)
             c.Add(None)
             return c.get_Item(0)
         res = self.interpret(fn, [])
@@ -483,16 +491,21 @@
         res = self.interpret(fn, [])
         assert self.ll_to_string(res) == '42'
 
-    def test_dynamic_method(self):
-        def fn():
-            myfunc = build_fn()
-            return myfunc.Invoke(30, 12)
-        res = self.interpret(fn, [])
-        assert res == 42
-
     def test_call_delegate(self):
+        def build_fn():
+            tInt = typeof(System.Int32)
+            args = init_array(System.Type, tInt, tInt)
+            meth = Utils.CreateDynamicMethod("add", tInt, args)
+            il = meth.GetILGenerator()
+            il.Emit(OpCodes.Ldarg_0)
+            il.Emit(OpCodes.Ldarg_1)
+            il.Emit(OpCodes.Add)
+            il.Emit(OpCodes.Ret)
+            myfunc = meth.CreateDelegate(typeof(FUNCTYPE))
+            return myfunc
+        
         def fn():
-            myfunc = build_fn()
+            myfunc = clidowncast(build_fn(), FUNCTYPE)
             return myfunc(30, 12)
         res = self.interpret(fn, [])
         assert res == 42
@@ -519,3 +532,9 @@
     def test_whitout_box(self):
         pass # it makes sense only during translation
         
+    def test_typeof_functype(self):
+        def fn():
+            t = typeof(FUNCTYPE)
+            return t.get_Name()
+        res = self.interpret(fn, [])
+        assert res == 'DelegateType_int__int_2'



More information about the Pypy-commit mailing list