[pypy-svn] r33818 - in pypy/dist/pypy/translator/cli: . test

antocuni at codespeak.net antocuni at codespeak.net
Fri Oct 27 16:55:29 CEST 2006


Author: antocuni
Date: Fri Oct 27 16:55:29 2006
New Revision: 33818

Modified:
   pypy/dist/pypy/translator/cli/database.py
   pypy/dist/pypy/translator/cli/dotnet.py
   pypy/dist/pypy/translator/cli/query.py
   pypy/dist/pypy/translator/cli/test/test_dotnet.py
Log:
Initial support for passing Null value to native .NET methods.



Modified: pypy/dist/pypy/translator/cli/database.py
==============================================================================
--- pypy/dist/pypy/translator/cli/database.py	(original)
+++ pypy/dist/pypy/translator/cli/database.py	Fri Oct 27 16:55:29 2006
@@ -241,7 +241,7 @@
 
     PRIMITIVE_TYPES = set([ootype.Void, ootype.Bool, ootype.Char, ootype.UniChar,
                            ootype.Float, ootype.Signed, ootype.Unsigned, ootype.String,
-                           lltype.SignedLongLong, lltype.UnsignedLongLong])
+                           lltype.SignedLongLong, lltype.UnsignedLongLong, dotnet.NullType])
 
     def is_primitive(cls, TYPE):
         return TYPE in cls.PRIMITIVE_TYPES
@@ -272,6 +272,9 @@
                 ilasm.opcode('ldnull')
             else:
                 ilasm.opcode("ldstr", string_literal(value._str))
+        elif TYPE is dotnet.NullType:
+            assert value is dotnet.Null
+            ilasm.opcode('ldnull')
         else:
             assert TYPE not in cls.PRIMITIVE_TYPES
             const = db.record_const(value)

Modified: pypy/dist/pypy/translator/cli/dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/dotnet.py	(original)
+++ pypy/dist/pypy/translator/cli/dotnet.py	Fri Oct 27 16:55:29 2006
@@ -1,5 +1,5 @@
 from pypy.annotation.pairtype import pair, pairtype
-from pypy.annotation.model import SomeObject, SomeOOInstance, SomeInteger,\
+from pypy.annotation.model import SomeObject, SomeOOInstance, SomeInteger, s_None,\
      s_ImpossibleValue, lltype_to_annotation, annotation_to_lltype, SomeChar, SomeString
 from pypy.rpython.error import TyperError
 from pypy.rpython.extregistry import ExtRegistryEntry
@@ -102,6 +102,12 @@
 
 class OverloadingResolver(ootype.OverloadingResolver):
 
+    def _can_convert_from_to(self, ARG1, ARG2):
+        if ARG1 is NullType and isinstance(ARG2, NativeInstance):
+            return True # Null is always convertible to a NativeInstance
+        else:
+            return ootype.OverloadingResolver._can_convert_from_to(self, ARG1, ARG2)
+
     def annotation_to_lltype(cls, ann):
         if isinstance(ann, SomeChar):
             return ootype.Char
@@ -137,8 +143,10 @@
 
 
 class _overloaded_static_meth(object):
-    def __init__(self, *overloadings):
-        self._resolver = ootype.OverloadingResolver(overloadings)
+    def __init__(self, *overloadings, **attrs):
+        resolver = attrs.pop('resolver', OverloadingResolver)
+        assert not attrs
+        self._resolver = resolver(overloadings)
 
     def _set_attrs(self, cls, name):
         for meth in self._resolver.overloadings:
@@ -158,8 +166,25 @@
         self._classname = name
         ootype.Instance.__init__(self, fullname, superclass, fields, methods, _is_root, _hints)
 
+class NullType(ootype.OOType):
+    pass
+NullType = NullType()
+
+
 ## RPython interface definition
 
+class NullValue:
+    _TYPE = NullType
+Null = NullValue()
+del NullValue
+
+class Entry(ExtRegistryEntry):
+    _about_ = Null
+
+    def compute_annotation(self):
+        return SomeOOInstance(ootype=NullType)
+
+
 class CliClass(object):
     def __init__(self, INSTANCE, static_methods):
         self._name = INSTANCE._name
@@ -281,7 +306,7 @@
         assert type_s.is_constant()
         TYPE = type_s.const
         assert TYPE in BOXABLE_TYPES
-        return ootype.OverloadingResolver.lltype_to_annotation(TYPE)
+        return OverloadingResolver.lltype_to_annotation(TYPE)
 
     def specialize_call(self, hop):
         v_obj, v_type = hop.inputargs(*hop.args_r)

Modified: pypy/dist/pypy/translator/cli/query.py
==============================================================================
--- pypy/dist/pypy/translator/cli/query.py	(original)
+++ pypy/dist/pypy/translator/cli/query.py	Fri Oct 27 16:55:29 2006
@@ -6,7 +6,7 @@
 from pypy.translator.cli.sdk import SDK
 from pypy.translator.cli.support import log
 from pypy.translator.cli.dotnet import CLR, CliNamespace, CliClass,\
-     NativeInstance, _overloaded_static_meth, _static_meth
+     NativeInstance, _overloaded_static_meth, _static_meth, OverloadingResolver
     
 ClassCache = {}
 OOTypeCache = {}
@@ -139,10 +139,11 @@
             groups.setdefault(name, []).append((args, result))
 
         res = {}
+        attrs = dict(resolver=OverloadingResolver)
         for name, methlist in groups.iteritems():
             TYPES = [self.get_method_type(Meth, args, result) for (args, result) in methlist]
             meths = [meth(TYPE) for TYPE in TYPES]
-            res[name] = overload(*meths)
+            res[name] = overload(*meths, **attrs)
         return res
 
     def get_method_type(self, Meth, args, result):

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	Fri Oct 27 16:55:29 2006
@@ -6,7 +6,7 @@
      ROOT, overload, Instance, new
 from pypy.translator.cli.test.runtest import CliTest
 from pypy.translator.cli.dotnet import SomeCliClass, SomeCliStaticMethod,\
-     NativeInstance, CLR, box, unbox, OverloadingResolver
+     NativeInstance, CLR, box, unbox, OverloadingResolver, Null, NullType
 
 System = CLR.System
 Math = CLR.System.Math
@@ -112,6 +112,12 @@
         assert isinstance(s, annmodel.SomeOOInstance)
         assert s.ootype._name == '[mscorlib]System.Object'
 
+    def test_Null(self):
+        def fn():
+            return Null
+        a = RPythonAnnotator()
+        s = a.build_types(fn, [])
+        assert s.ootype is NullType
 
 class TestDotnetRtyping(CliTest):
     def _skip_pythonnet(self, msg):
@@ -188,6 +194,23 @@
             return unbox(array[0], ootype.Signed)
         assert self.interpret(fn, []) == 42
 
+    def test_Null(self):
+        self._skip_pythonnet("Null support not yet completed'")
+        def fn():
+            return System.Object.Equals(Null, Null)
+        assert self.interpret(fn, []) == True
+
+    def test_Null_bound_method(self):
+        self._skip_pythonnet("Null support not yet completed'")
+        def fn():
+            x = ArrayList()
+            x.Add(Null)
+            return x.get_Item(0)
+        # a bit of explanation for the result: after IL has been
+        # generated there is no distinction between dotnet.Null and
+        # None, because both are rendered as the CLI 'null' value. So
+        # interpret returns 'None', as it has always done.
+        assert self.interpret(fn, []) is None
 
 class TestPythonnet(TestDotnetRtyping):
     # don't interpreter functions but execute them directly through pythonnet



More information about the Pypy-commit mailing list