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

antocuni at codespeak.net antocuni at codespeak.net
Thu Oct 26 14:21:13 CEST 2006


Author: antocuni
Date: Thu Oct 26 14:21:13 2006
New Revision: 33765

Modified:
   pypy/dist/pypy/translator/cli/dotnet.py
   pypy/dist/pypy/translator/cli/metavm.py
   pypy/dist/pypy/translator/cli/opcodes.py
   pypy/dist/pypy/translator/cli/test/test_dotnet.py
Log:
Support for unboxing



Modified: pypy/dist/pypy/translator/cli/dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/dotnet.py	(original)
+++ pypy/dist/pypy/translator/cli/dotnet.py	Thu Oct 26 14:21:13 2006
@@ -172,22 +172,46 @@
         return SomeCliClass()
 
 
+class CliNamespace(object):
+    def __init__(self, name):
+        self._name = name
+
+    def __fullname(self, name):
+        if self._name is None:
+            return name
+        else:
+            return '%s.%s' % (self._name, name)
+
+    def __getattr__(self, attr):
+        from pypy.translator.cli.query import load_class_or_namespace
+        name = self.__fullname(attr)
+        load_class_or_namespace(name)
+        assert attr in self.__dict__
+        return getattr(self, attr)
+
+CLR = CliNamespace(None)
+
+
+BOXABLE_TYPES = [ootype.Signed, ootype.Unsigned, ootype.SignedLongLong,
+                 ootype.UnsignedLongLong, ootype.Bool, ootype.Float,
+                 ootype.Char, ootype.String]
+
 def box(x):
     return x
 
+def unbox(x, TYPE):
+    # TODO: check that x is really of type TYPE
+    return x
+
 class Entry(ExtRegistryEntry):
     _about_ = box
 
-    boxable_types = [ootype.Signed, ootype.Unsigned, ootype.SignedLongLong,
-                     ootype.UnsignedLongLong, ootype.Bool, ootype.Float,
-                     ootype.Char, ootype.String]
-
     def compute_result_annotation(self, x_s):
         return annmodel.SomeOOInstance(CLR.System.Object._INSTANCE)
 
     def specialize_call(self, hop):
         v_obj, = hop.inputargs(*hop.args_r)
-        if v_obj.concretetype not in self.boxable_types:
+        if v_obj.concretetype not in BOXABLE_TYPES:
             raise TyperError, "Can't box values of type %s" % v_obj.concretetype
         
         if (v_obj.concretetype is ootype.String):
@@ -195,21 +219,20 @@
         else:
             return hop.genop('clibox', [v_obj], hop.r_result.lowleveltype)
 
-class CliNamespace(object):
-    def __init__(self, name):
-        self._name = name
-
-    def __fullname(self, name):
-        if self._name is None:
-            return name
-        else:
-            return '%s.%s' % (self._name, name)
+class Entry(ExtRegistryEntry):
+    _about_ = unbox
 
-    def __getattr__(self, attr):
-        from pypy.translator.cli.query import load_class_or_namespace
-        name = self.__fullname(attr)
-        load_class_or_namespace(name)
-        assert attr in self.__dict__
-        return getattr(self, attr)
+    def compute_result_annotation(self, x_s, type_s):
+        assert isinstance(x_s, annmodel.SomeOOInstance)
+        assert x_s.ootype == CLR.System.Object._INSTANCE
+        assert type_s.is_constant()
+        TYPE = type_s.const
+        assert TYPE in BOXABLE_TYPES
+        return ootype._overloaded_mixin._lltype_to_annotation(TYPE)
 
-CLR = CliNamespace(None)
+    def specialize_call(self, hop):
+        v_obj, v_type = hop.inputargs(*hop.args_r)
+        if v_type.value is ootype.String:
+            return hop.genop('oodowncast', [v_obj], hop.r_result.lowleveltype)
+        else:
+            return hop.genop('cliunbox', [v_obj, v_type], hop.r_result.lowleveltype)

Modified: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/cli/metavm.py	(original)
+++ pypy/dist/pypy/translator/cli/metavm.py	Thu Oct 26 14:21:13 2006
@@ -163,6 +163,15 @@
         boxtype = generator.cts.lltype_to_cts(TYPE)
         generator.ilasm.opcode('box', boxtype)
 
+class _Unbox(MicroInstruction):
+    def render(self, generator, op):
+        v_obj, v_type = op.args
+        assert v_type.concretetype is ootype.Void
+        TYPE = v_type.value
+        boxtype = generator.cts.lltype_to_cts(TYPE)
+        generator.load(v_obj)
+        generator.ilasm.opcode('unbox.any', boxtype)
+
 Call = _Call()
 CallMethod = _CallMethod()
 IndirectCall = _IndirectCall()
@@ -172,3 +181,4 @@
 NewCustomDict = _NewCustomDict()
 CastWeakAdrToPtr = _CastWeakAdrToPtr()
 Box = _Box()
+Unbox = _Unbox()

Modified: pypy/dist/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/cli/opcodes.py	(original)
+++ pypy/dist/pypy/translator/cli/opcodes.py	Thu Oct 26 14:21:13 2006
@@ -1,6 +1,6 @@
 from pypy.translator.cli.metavm import  Call, CallMethod, RuntimeNew, \
      IndirectCall, GetField, SetField, CastTo, OOString, DownCast, NewCustomDict,\
-     CastWeakAdrToPtr, MapException, Box
+     CastWeakAdrToPtr, MapException, Box, Unbox
 from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\
     New
 from pypy.translator.cli.cts import WEAKREF
@@ -35,6 +35,7 @@
     'ooupcast':                 DoNothing,
     'oodowncast':               [DownCast],
     'clibox':                   [Box],
+    'cliunbox':                 [Unbox],
     'oois':                     'ceq',
     'oononnull':                [PushAllArgs, 'ldnull', 'ceq']+Not,
     'instanceof':               [CastTo, 'ldnull', 'cgt.un'],

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	Thu Oct 26 14:21:13 2006
@@ -1,9 +1,10 @@
 import py
 from pypy.annotation.annrpython import RPythonAnnotator
 from pypy.annotation import model as annmodel
+from pypy.rpython.ootypesystem import ootype
 from pypy.translator.cli.test.runtest import CliTest
 from pypy.translator.cli.dotnet import SomeCliClass, SomeCliStaticMethod,\
-     NativeInstance, CLR, box
+     NativeInstance, CLR, box, unbox
 
 Math = CLR.System.Math
 ArrayList = CLR.System.Collections.ArrayList
@@ -11,7 +12,7 @@
 
 class TestDotnetAnnotation(object):
 
-    def test_class_ann(self):
+    def test_class(self):
         def fn():
             return Math
         a = RPythonAnnotator()
@@ -19,7 +20,7 @@
         assert isinstance(s, SomeCliClass)
         assert s.const is Math
 
-    def test_staticmeth_ann(self):
+    def test_staticmeth(self):
         def fn():
             return Math.Abs
         a = RPythonAnnotator()
@@ -28,7 +29,7 @@
         assert s.cli_class is Math
         assert s.meth_name == 'Abs'
 
-    def test_staticmeth_call_ann(self):
+    def test_staticmeth_call(self):
         def fn1():
             return Math.Abs(42)
         def fn2():
@@ -37,7 +38,7 @@
         assert type(a.build_types(fn1, [])) is annmodel.SomeInteger
         assert type(a.build_types(fn2, [])) is annmodel.SomeFloat
 
-    def test_new_instance_ann(self):
+    def test_new_instance(self):
         def fn():
             return ArrayList()
         a = RPythonAnnotator()
@@ -46,7 +47,23 @@
         assert isinstance(s.ootype, NativeInstance)
         assert s.ootype._name == '[mscorlib]System.Collections.ArrayList'
 
-class TestDotnetRtyping(TestDotnetAnnotation, CliTest):
+    def test_box(self):
+        def fn():
+            return box(42)
+        a = RPythonAnnotator()
+        s = a.build_types(fn, [])
+        assert isinstance(s, annmodel.SomeOOInstance)
+        assert s.ootype._name == '[mscorlib]System.Object'
+
+    def test_unbox(self):
+        def fn():
+            x = box(42)
+            return unbox(x, ootype.Signed)
+        a = RPythonAnnotator()
+        s = a.build_types(fn, [])
+        assert isinstance(s, annmodel.SomeInteger)
+
+class TestDotnetRtyping(CliTest):
     def _skip_pythonnet(self):
         pass
 
@@ -88,6 +105,20 @@
             return x.get_Count()
         assert self.interpret(fn, []) == 2
 
+    def test_unbox(self):
+        def fn():
+            x = ArrayList()
+            x.Add(box(42))
+            return unbox(x.get_Item(0), ootype.Signed)
+        assert self.interpret(fn, []) == 42
+
+    def test_unbox_string(self):
+        def fn():
+            x = ArrayList()
+            x.Add(box('foo'))
+            return unbox(x.get_Item(0), ootype.String)
+        assert self.interpret(fn, []) == 'foo'
+
 
 class TestPythonnet(TestDotnetRtyping):
     # don't interpreter functions but execute them directly through pythonnet



More information about the Pypy-commit mailing list