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

antocuni at codespeak.net antocuni at codespeak.net
Wed Nov 15 11:12:10 CET 2006


Author: antocuni
Date: Wed Nov 15 11:12:09 2006
New Revision: 34618

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/query.py
   pypy/dist/pypy/translator/cli/test/test_dotnet.py
Log:
Added support for creating arrays to .NET-types



Modified: pypy/dist/pypy/translator/cli/dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/dotnet.py	(original)
+++ pypy/dist/pypy/translator/cli/dotnet.py	Wed Nov 15 11:12:09 2006
@@ -343,3 +343,34 @@
     def specialize_call(self, hop):
         v_obj, = hop.inputargs(*hop.args_r)
         return hop.genop('same_as', [v_obj], hop.r_result.lowleveltype)
+
+
+def init_array(type, *args):
+    # PythonNet doesn't provide a straightforward way to create arrays... fake it with a list
+    return args
+
+class Entry(ExtRegistryEntry):
+    _about_ = init_array
+
+    def compute_result_annotation(self, type_s, *args_s):
+        from pypy.translator.cli.query import load_class_maybe
+        assert type_s.is_constant()
+        TYPE = type_s.const._INSTANCE
+        for i, arg_s in enumerate(args_s):
+            if TYPE is not arg_s.ootype:
+                raise TypeError, 'Wrong type of arg #%d: %s expected, %s found' % \
+                      (i, TYPE, arg_s.ootype)
+        fullname = '%s.%s[]' % (TYPE._namespace, TYPE._classname)
+        cliArray = load_class_maybe(fullname)
+        return SomeOOInstance(cliArray._INSTANCE)
+
+    def specialize_call(self, hop):
+        vlist = hop.inputargs(*hop.args_r)
+        c_type, v_elems = vlist[0], vlist[1:]
+        c_length = hop.inputconst(ootype.Signed, len(v_elems))
+        hop.exception_cannot_occur()
+        v_array = hop.genop('cli_newarray', [c_type, c_length], hop.r_result.lowleveltype)
+        for i, v_elem in enumerate(v_elems):
+            c_index = hop.inputconst(ootype.Signed, i)
+            hop.genop('cli_setelem', [v_array, c_index, v_elem], ootype.Void)
+        return v_array

Modified: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/cli/metavm.py	(original)
+++ pypy/dist/pypy/translator/cli/metavm.py	Wed Nov 15 11:12:09 2006
@@ -185,6 +185,15 @@
         generator.load(v_obj)
         generator.ilasm.opcode('unbox.any', boxtype)
 
+class _NewArray(MicroInstruction):
+    def render(self, generator, op):
+        v_type, v_length = op.args
+        assert v_type.concretetype is ootype.Void
+        TYPE = v_type.value._INSTANCE
+        typetok = generator.cts.lltype_to_cts(TYPE)
+        generator.load(v_length)
+        generator.ilasm.opcode('newarr', typetok)
+
 class _GetArrayElem(MicroInstruction):
     def render(self, generator, op):
         generator.load(op.args[0])
@@ -192,6 +201,16 @@
         rettype = generator.cts.lltype_to_cts(op.result.concretetype)
         generator.ilasm.opcode('ldelem', rettype)
 
+class _SetArrayElem(MicroInstruction):
+    def render(self, generator, op):
+        v_array, v_index, v_elem = op.args
+        generator.load(v_array)
+        generator.load(v_index)
+        generator.load(v_elem)
+        elemtype = generator.cts.lltype_to_cts(v_array.concretetype)
+        generator.ilasm.opcode('stelem', elemtype)
+
+
 Call = _Call()
 CallMethod = _CallMethod()
 IndirectCall = _IndirectCall()
@@ -202,4 +221,6 @@
 CastWeakAdrToPtr = _CastWeakAdrToPtr()
 Box = _Box()
 Unbox = _Unbox()
+NewArray = _NewArray()
 GetArrayElem = _GetArrayElem()
+SetArrayElem = _SetArrayElem()

Modified: pypy/dist/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/cli/opcodes.py	(original)
+++ pypy/dist/pypy/translator/cli/opcodes.py	Wed Nov 15 11:12:09 2006
@@ -1,6 +1,6 @@
 from pypy.translator.cli.metavm import  Call, CallMethod, \
      IndirectCall, GetField, SetField, CastTo, OOString, DownCast, NewCustomDict,\
-     CastWeakAdrToPtr, MapException, Box, Unbox, GetArrayElem
+     CastWeakAdrToPtr, MapException, Box, Unbox, NewArray, GetArrayElem, SetArrayElem
 from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\
     New, RuntimeNew
 from pypy.translator.cli.cts import WEAKREF
@@ -36,7 +36,9 @@
     'oodowncast':               [DownCast],
     'clibox':                   [Box],
     'cliunbox':                 [Unbox],
+    'cli_newarray':             [NewArray],
     'cli_getelem':              [GetArrayElem],
+    'cli_setelem':              [SetArrayElem],
     'oois':                     'ceq',
     'oononnull':                [PushAllArgs, 'ldnull', 'ceq']+Not,
     'instanceof':               [CastTo, 'ldnull', 'cgt.un'],

Modified: pypy/dist/pypy/translator/cli/query.py
==============================================================================
--- pypy/dist/pypy/translator/cli/query.py	(original)
+++ pypy/dist/pypy/translator/cli/query.py	Wed Nov 15 11:12:09 2006
@@ -63,7 +63,9 @@
     except KeyError:
         desc = query_description(name)
         Descriptions[name] = desc
-    setattr_ex(CLR, name, desc.build())
+    res = desc.build()
+    setattr_ex(CLR, name, res)
+    return res
 
 def query_description(name):
     log.query('Loading description for %s' % name)
@@ -84,9 +86,13 @@
 
 def load_class_maybe(name):
     if name.startswith('System.Array+InternalArray'):
-        ClassCache[name] = ClassCache['System.Array']
+        res = ClassCache['System.Array']
+        ClassCache[name] = res
+        return res
     elif name not in ClassCache:
-        load_class_or_namespace(name)
+        return load_class_or_namespace(name)
+    else:
+        return ClassCache[name]
 
 
 class Desc:

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 Nov 15 11:12:09 2006
@@ -7,7 +7,7 @@
 from pypy.translator.cli.test.runtest import CliTest
 from pypy.translator.cli.dotnet import SomeCliClass, SomeCliStaticMethod,\
      NativeInstance, CLR, box, unbox, OverloadingResolver, NativeException,\
-     native_exc
+     native_exc, init_array
 
 System = CLR.System
 Math = CLR.System.Math
@@ -188,6 +188,12 @@
             return unbox(array[0], ootype.Signed)
         assert self.interpret(fn, []) == 42
 
+    def test_init_array(self):
+        def fn():
+            array = init_array(System.Object, box(42), box(43))
+            return unbox(array[0], ootype.Signed) + unbox(array[1], ootype.Signed)
+        assert self.interpret(fn, []) == 42+43
+
     def test_null(self):
         def fn():
             return System.Object.Equals(None, None)
@@ -235,6 +241,7 @@
         res = self.ll_to_string(self.interpret(fn, []))
         assert res.startswith("Index is less than 0")
 
+
 class TestPythonnet(TestDotnetRtyping):
     # don't interpreter functions but execute them directly through pythonnet
     def interpret(self, f, args):



More information about the Pypy-commit mailing list