[pypy-svn] r51985 - in pypy/dist/pypy/translator: cli cli/test oosupport

antocuni at codespeak.net antocuni at codespeak.net
Sat Mar 1 12:37:37 CET 2008


Author: antocuni
Date: Sat Mar  1 12:37:37 2008
New Revision: 51985

Modified:
   pypy/dist/pypy/translator/cli/constant.py
   pypy/dist/pypy/translator/cli/dotnet.py
   pypy/dist/pypy/translator/cli/test/test_class.py
   pypy/dist/pypy/translator/cli/test/test_dotnet.py
   pypy/dist/pypy/translator/oosupport/constant.py
Log:
add a way to cast an ootype._record to System.Object and back.



Modified: pypy/dist/pypy/translator/cli/constant.py
==============================================================================
--- pypy/dist/pypy/translator/cli/constant.py	(original)
+++ pypy/dist/pypy/translator/cli/constant.py	Sat Mar  1 12:37:37 2008
@@ -84,11 +84,19 @@
         type = self.cts.lltype_to_cts(EXPECTED_TYPE)
         gen.ilasm.opcode('castclass', type)
 
+    def _get_key_for_const(self, value):
+        from pypy.translator.cli.dotnet import _record_view
+        if isinstance(value, _record_view):
+            return value._record
+        return BaseConstantGenerator._get_key_for_const(self, value)
+
     def _create_complex_const(self, value):
-        from pypy.translator.cli.dotnet import _fieldinfo
+        from pypy.translator.cli.dotnet import _fieldinfo, _record_view
         if isinstance(value, _fieldinfo):
             uniq = self.db.unique()
             return CLIFieldInfoConst(self.db, value.llvalue, uniq)
+        elif isinstance(value, _record_view):
+            return self.record_const(value._record)
         else:
             return BaseConstantGenerator._create_complex_const(self, value)
 

Modified: pypy/dist/pypy/translator/cli/dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/dotnet.py	(original)
+++ pypy/dist/pypy/translator/cli/dotnet.py	Sat Mar  1 12:37:37 2008
@@ -465,6 +465,7 @@
             return hop.genop('cliunbox', [v_obj, c_type], hop.r_result.lowleveltype)
 
 
+
 native_exc_cache = {}
 def NativeException(cliClass):
     try:
@@ -632,6 +633,71 @@
         v_inst = hop.inputarg(hop.args_r[0], arg=0)
         return hop.genop('oodowncast', [v_inst], resulttype = hop.r_result.lowleveltype)
 
+class _record_view(object):
+    
+    def __init__(self, record):
+        self._record = record
+        self._TYPE = CLR.System.Object._INSTANCE
+
+    def __ne__(self, other):
+        return not (self == other)
+
+    def __eq__(self, other):
+        if isinstance(other, ootype._record):
+            return self._record == other
+        assert isinstance(other, _record_view)
+        return self._record == other._record
+
+    def __hash__(self):
+        return hash(self._record)
+
+    def __nonzero__(self):
+        return bool(self._record)
+
+
+def cast_record_to_object(record):
+    T = ootype.typeOf(record)
+    assert isinstance(T, ootype.Record)
+    return _record_view(record)
+
+def cast_object_to_record(T, obj):
+    assert isinstance(T, ootype.Record)
+    assert isinstance(obj, _record_view)
+    record = obj._record
+    assert ootype.typeOf(record) == T
+    return record
+
+class Entry(ExtRegistryEntry):
+    _about_ = cast_record_to_object
+
+    def compute_result_annotation(self, s_value):
+        T = s_value.ootype
+        assert isinstance(T, ootype.Record)
+        can_be_None = getattr(s_value, 'can_be_None', False)
+        return SomeOOInstance(CLR.System.Object._INSTANCE, can_be_None=can_be_None)
+
+    def specialize_call(self, hop):
+        assert isinstance(hop.args_s[0], annmodel.SomeOOInstance)
+        v_obj, = hop.inputargs(*hop.args_r)
+        hop.exception_cannot_occur()
+        return hop.genop('ooupcast', [v_obj], hop.r_result.lowleveltype)
+
+class Entry(ExtRegistryEntry):
+    _about_ = cast_object_to_record
+
+    def compute_result_annotation(self, s_type, s_value):
+        assert s_type.is_constant()
+        T = s_type.const
+        assert isinstance(T, ootype.Record)
+        can_be_None = getattr(s_value, 'can_be_None', False)
+        return SomeOOInstance(T, can_be_None)
+
+    def specialize_call(self, hop):
+        assert hop.args_s[0].is_constant()
+        TYPE = hop.args_s[0].const
+        v_obj = hop.inputarg(hop.args_r[1], arg=1)
+        return hop.genop('oodowncast', [v_obj], hop.r_result.lowleveltype)
+
 class _fieldinfo(object):
     def __init__(self, llvalue):
         self._TYPE = CLR.System.Reflection.FieldInfo._INSTANCE

Modified: pypy/dist/pypy/translator/cli/test/test_class.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_class.py	(original)
+++ pypy/dist/pypy/translator/cli/test/test_class.py	Sat Mar  1 12:37:37 2008
@@ -2,6 +2,8 @@
 from pypy.translator.cli.test.runtest import CliTest
 from pypy.translator.oosupport.test_template.class_ import BaseTestClass, BaseTestSpecialcase
 
+# ====> ../../oosupport/test_template/class_.py
+
 class TestCliClass(CliTest, BaseTestClass):    
     pass
 

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	Sat Mar  1 12:37:37 2008
@@ -8,7 +8,7 @@
 from pypy.translator.cli.dotnet import SomeCliClass, SomeCliStaticMethod,\
      NativeInstance, CLR, box, unbox, OverloadingResolver, NativeException,\
      native_exc, new_array, init_array, typeof, eventhandler, clidowncast,\
-     fieldinfo_for_const, classof
+     fieldinfo_for_const, classof, cast_record_to_object, cast_object_to_record
 
 System = CLR.System
 ArrayList = CLR.System.Collections.ArrayList
@@ -641,6 +641,29 @@
         res = self.interpret(fn, [True])
         assert res == 'Int32'
 
+    def test_mix_record_and_object(self):
+        T = ootype.Record({'x': ootype.Signed})
+        record = ootype.new(T)
+        def fn(flag):
+            if flag:
+                obj = cast_record_to_object(record)
+            else:
+                obj = System.Object()
+            record2 = cast_object_to_record(T, obj)
+            return record is record2
+        res = self.interpret(fn, [True])
+        assert res
+
+    def test_cast_record_pbc(self):
+        T = ootype.Record({'x': ootype.Signed})
+        record = ootype.new(T)
+        record.x = 42
+        obj = cast_record_to_object(record)
+        def fn():
+            record2 = cast_object_to_record(T, obj)
+            return record is record2
+        res = self.interpret(fn, [])
+        assert res
 
 class TestPythonnet(TestDotnetRtyping):
     # don't interpreter functions but execute them directly through pythonnet

Modified: pypy/dist/pypy/translator/oosupport/constant.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/constant.py	(original)
+++ pypy/dist/pypy/translator/oosupport/constant.py	Sat Mar  1 12:37:37 2008
@@ -159,7 +159,10 @@
         constant will be stored in the field of a singleton object.
         """
         pass
-        
+
+    def _get_key_for_const(self, value):
+        return value
+    
     # _________________________________________________________________
     # Constant Object Creation
     #
@@ -175,7 +178,8 @@
         if value in self.cache:
             return self.cache[value]
         const = self._create_complex_const(value)
-        self.cache[value] = const
+        key = self._get_key_for_const(value)
+        self.cache[key] = const
         self._init_constant(const)
         const.record_dependencies()
         return const



More information about the Pypy-commit mailing list