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

antocuni at codespeak.net antocuni at codespeak.net
Sun Jul 16 16:31:59 CEST 2006


Author: antocuni
Date: Sun Jul 16 16:31:46 2006
New Revision: 30078

Added:
   pypy/dist/pypy/translator/cli/comparer.py   (contents, props changed)
   pypy/dist/pypy/translator/cli/test/test_objectmodel.py   (contents, props changed)
Modified:
   pypy/dist/pypy/translator/cli/database.py
   pypy/dist/pypy/translator/cli/ilgenerator.py
   pypy/dist/pypy/translator/cli/metavm.py
   pypy/dist/pypy/translator/cli/opcodes.py
   pypy/dist/pypy/translator/cli/src/pypylib.cs
Log:
Initial support for r_dict.



Added: pypy/dist/pypy/translator/cli/comparer.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/cli/comparer.py	Sun Jul 16 16:31:46 2006
@@ -0,0 +1,64 @@
+from pypy.translator.cli.cts import CTS
+from pypy.translator.cli.node import Node
+
+IEQUALITY_COMPARER = 'class [mscorlib]System.Collections.Generic.IEqualityComparer`1<%s>'
+
+class EqualityComparer(Node):
+    count = 0
+    
+    def __init__(self, db, KEY_TYPE, eq_args, hash_args):
+        self.db = db
+        self.cts = CTS(db)
+        self.KEY_TYPE = KEY_TYPE
+        self.key_type = self.cts.lltype_to_cts(KEY_TYPE)
+        self.eq_args = eq_args
+        self.hash_args = hash_args
+        self.name = 'EqualityComparer_%d' % EqualityComparer.count
+        EqualityComparer.count += 1
+
+    def get_ctor(self):
+        return 'instance void %s::.ctor()' % self.name
+
+    def render(self, ilasm):
+        self.ilasm = ilasm
+        IEqualityComparer = IEQUALITY_COMPARER % self.key_type
+        ilasm.begin_class(self.name, interfaces=[IEqualityComparer])
+        self._ctor()
+        self._method('Equals', [(self.key_type, 'x'), (self.key_type, 'y')],
+                     'bool', self.eq_args)
+        self._method('GetHashCode', [(self.key_type, 'x')], 'int32', self.hash_args)
+        ilasm.end_class()
+
+    def _ctor(self):
+        self.ilasm.begin_function('.ctor', [], 'void', False, 'specialname', 'rtspecialname', 'instance')
+        self.ilasm.opcode('ldarg.0')
+        self.ilasm.call('instance void [mscorlib]System.Object::.ctor()')
+        self.ilasm.opcode('ret')
+        self.ilasm.end_function()
+        
+    def _method(self, name, arglist, return_type, fn_args):
+        self.ilasm.begin_function(name, arglist, return_type, False,
+                                  'final', 'virtual', 'hidebysig', 'newslot',
+                                  'instance', 'default')
+
+        fn, obj, method_name = fn_args
+        if method_name.value is None:
+            if obj.value is None:
+                self._call_function(fn, len(arglist), [])
+            else:
+                assert False, 'XXX'
+        else:
+            assert False, 'XXX'
+
+        self.ilasm.end_function()
+
+    def _call_function(self, fn, n_args, additional_args):
+        # fn is a HalfConcreteWrapper
+        sm = fn.value.concretize().value
+        self.db.pending_function(sm.graph)
+        for arg in range(1, n_args+1):
+            self.ilasm.opcode('ldarg', arg)
+
+        signature = self.cts.graph_to_signature(sm.graph)
+        self.ilasm.call(signature)
+        self.ilasm.opcode('ret')

Modified: pypy/dist/pypy/translator/cli/database.py
==============================================================================
--- pypy/dist/pypy/translator/cli/database.py	(original)
+++ pypy/dist/pypy/translator/cli/database.py	Sun Jul 16 16:31:46 2006
@@ -45,7 +45,9 @@
         return self.name_count
 
     def pending_function(self, graph):
-        self.pending_node(self.function_class(self, graph))
+        function = self.function_class(self, graph)
+        self.pending_node(function)
+        return function.get_name()
 
     def pending_class(self, classdef):
         self.pending_node(Class(self, classdef))

Modified: pypy/dist/pypy/translator/cli/ilgenerator.py
==============================================================================
--- pypy/dist/pypy/translator/cli/ilgenerator.py	(original)
+++ pypy/dist/pypy/translator/cli/ilgenerator.py	Sun Jul 16 16:31:46 2006
@@ -53,7 +53,7 @@
     def end_namespace(self):
         self.code.closeblock()
 
-    def begin_class(self, name, base = None, sealed = False):
+    def begin_class(self, name, base=None, sealed=False, interfaces=()):
         if base is None:
             base = '[mscorlib]System.Object'
         if sealed:
@@ -62,6 +62,8 @@
             s = ''
         
         self.code.writeline('.class public %s %s extends %s' % (s, name, base))
+        if interfaces:
+            self.code.writeline('  implements %s' % ', '.join(interfaces))
         self.code.openblock()
 
     def end_class(self):

Modified: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/cli/metavm.py	(original)
+++ pypy/dist/pypy/translator/cli/metavm.py	Sun Jul 16 16:31:46 2006
@@ -1,6 +1,7 @@
 from pypy.translator.cli import oopspec
 from pypy.rpython.ootypesystem import ootype
 from pypy.translator.oosupport.metavm import Generator, InstructionList, MicroInstruction
+from pypy.translator.cli.comparer import EqualityComparer
 
 STRING_HELPER_CLASS = '[pypylib]pypy.runtime.String'
 
@@ -102,6 +103,22 @@
         generator.load(op.args[0])
         generator.ilasm.opcode('castclass', resulttype)
 
+class _NewCustomDict(MicroInstruction):
+    def render(self, generator, op):
+        DICT = op.args[0].value
+        comparer = EqualityComparer(generator.db, DICT._KEYTYPE,
+                                    (op.args[1], op.args[2], op.args[3]),
+                                    (op.args[4], op.args[5], op.args[6]))
+        generator.db.pending_node(comparer)
+        dict_type = generator.cts.lltype_to_cts(DICT)
+
+        generator.ilasm.new(comparer.get_ctor())
+        generator.ilasm.new('instance void %s::.ctor(class'
+                            '[mscorlib]System.Collections.Generic.IEqualityComparer`1<!0>)'
+                            % dict_type)
+
+
+
 Call = _Call()
 CallMethod = _CallMethod()
 IndirectCall = _IndirectCall()
@@ -111,3 +128,4 @@
 CastTo = _CastTo()
 OOString = _OOString()
 DownCast = _DownCast()
+NewCustomDict = _NewCustomDict()

Modified: pypy/dist/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/cli/opcodes.py	(original)
+++ pypy/dist/pypy/translator/cli/opcodes.py	Sun Jul 16 16:31:46 2006
@@ -1,5 +1,5 @@
 from pypy.translator.cli.metavm import  Call, CallMethod, RuntimeNew, \
-     IndirectCall, GetField, SetField, CastTo, OOString, DownCast
+     IndirectCall, GetField, SetField, CastTo, OOString, DownCast, NewCustomDict
 from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\
     New
 
@@ -54,6 +54,7 @@
     'oohash':                   [PushAllArgs, 'callvirt instance int32 object::GetHashCode()'],    
     'oostring':                 [OOString],
     'ooparse_int':              [PushAllArgs, 'call int32 [pypylib]pypy.runtime.Utils::OOParseInt(string, int32)'],
+    'oonewcustomdict':          [NewCustomDict],
     
     'same_as':                  DoNothing, # TODO: does same_as really do nothing else than renaming?    
     'direct_call':              [Call],

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	Sun Jul 16 16:31:46 2006
@@ -331,6 +331,13 @@
 
     public class Dict<TKey, TValue>: System.Collections.Generic.Dictionary<TKey, TValue>
     {
+        IEqualityComparer<TKey> comparer = null;
+        public Dict() {}
+        public Dict(IEqualityComparer<TKey> comparer): base(comparer) 
+        { 
+            this.comparer = comparer;
+        }
+
         public int ll_length() { return this.Count; }
         public TValue ll_get(TKey key) { return this[key]; }
         public void ll_set(TKey key, TValue value) { this[key] = value; }
@@ -342,6 +349,15 @@
         {
             return new DictItemsIterator<TKey, TValue>(this.GetEnumerator());
         }
+
+        // XXX: this is CustomDict specific, maybe we should have a separate class for it
+        public Dict<TKey, TValue> ll_copy()
+        {
+            Dict<TKey, TValue> res = new Dict<TKey, TValue>(comparer);
+            foreach(KeyValuePair<TKey, TValue> item in this)
+                res[item.Key] = item.Value;
+            return res;
+        }
     }
 
     public class DictOfVoid<TKey>: System.Collections.Generic.Dictionary<TKey, int> // int is a placeholder

Added: pypy/dist/pypy/translator/cli/test/test_objectmodel.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/cli/test/test_objectmodel.py	Sun Jul 16 16:31:46 2006
@@ -0,0 +1,15 @@
+import py
+from pypy.translator.cli.test.runtest import CliTest
+from pypy.rpython.test.test_objectmodel import BaseTestObjectModel
+
+def skip_r_dict(self):
+    py.test.skip('r_dict support is still incomplete')
+
+class TestCliObjectModel(CliTest, BaseTestObjectModel):
+    test_rtype_r_dict_bm = skip_r_dict
+    test_rtype_constant_r_dicts = skip_r_dict
+    test_rtype_r_dict_singlefrozen_func = skip_r_dict
+
+    def test_hint(self):
+        py.test.skip('Hint is not supported, yet')
+    



More information about the Pypy-commit mailing list