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

antocuni at codespeak.net antocuni at codespeak.net
Mon Apr 10 23:18:45 CEST 2006


Author: antocuni
Date: Mon Apr 10 23:18:14 2006
New Revision: 25677

Added:
   pypy/dist/pypy/translator/cli/sdk.py   (contents, props changed)
   pypy/dist/pypy/translator/cli/src/pypylib.cs
      - copied, changed from r25666, pypy/dist/pypy/translator/cli/src/pypy.cs
   pypy/dist/pypy/translator/cli/test/test_list.py   (contents, props changed)
Removed:
   pypy/dist/pypy/translator/cli/src/pypy.cs
Modified:
   pypy/dist/pypy/translator/cli/cts.py
   pypy/dist/pypy/translator/cli/function.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/rte.py
   pypy/dist/pypy/translator/cli/test/compile.py
   pypy/dist/pypy/translator/cli/test/runtest.py
Log:
Added support for rpython lists.

Platform-specific issues are now grouped togheter in sdk.py.



Modified: pypy/dist/pypy/translator/cli/cts.py
==============================================================================
--- pypy/dist/pypy/translator/cli/cts.py	(original)
+++ pypy/dist/pypy/translator/cli/cts.py	Mon Apr 10 23:18:14 2006
@@ -6,7 +6,7 @@
 
 from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Void, Bool, Float
 from pypy.rpython.lltypesystem.lltype import SignedLongLong, UnsignedLongLong
-from pypy.rpython.ootypesystem.ootype import Instance, Class, StaticMethod
+from pypy.rpython.ootypesystem.ootype import Instance, Class, StaticMethod, List
 from pypy.translator.cli.option import getoption
 
 from pypy.tool.ansi_print import ansi_log
@@ -22,8 +22,11 @@
     SignedLongLong: 'int64',
     UnsignedLongLong: 'unsigned int64',
     Bool: 'bool',
-    Float: 'float64',
+    Float: 'float64',    
     Class: 'class [mscorlib]System.Type',
+
+    # TODO: it seems a hack
+    List.ITEMTYPE_T: '!0',
     }
 
 _pyexception_to_cts = {
@@ -53,6 +56,9 @@
             return 'class %s' % name
         elif isinstance(t, StaticMethod):
             return 'void' # TODO: is it correct to ignore StaticMethod?
+        elif isinstance(t, List):
+            item_type = self.lltype_to_cts(t._ITEMTYPE)
+            return 'class [pypylib]pypy.runtime.List`1<%s>' % item_type
 
         return _get_from_dict(_lltype_to_cts, t, 'Unknown type %s' % t)
 
@@ -62,6 +68,9 @@
     def llconst_to_cts(self, const):
         return self.lltype_to_cts(const.concretetype), const.value
 
+    def ctor_name(self, t):
+        return 'instance void %s::.ctor()' % self.lltype_to_cts(t)
+
     def graph_to_signature(self, graph, is_method = False, func_name = None):
         ret_type, ret_var = self.llvar_to_cts(graph.getreturnvar())
         func_name = func_name or graph.name
@@ -75,6 +84,24 @@
 
         return '%s %s(%s)' % (ret_type, func_name, arg_list)
 
+    def method_signature(self, obj, name):
+        # TODO: use callvirt only when strictly necessary
+        if isinstance(obj, Instance):
+            owner, meth = obj._lookup(name)
+            class_name = obj._name
+            full_name = 'class %s::%s' % (class_name, name)
+            return self.graph_to_signature(meth.graph, True, full_name), True
+
+        elif isinstance(obj, List):
+            meth = obj._GENERIC_METHODS[name]
+            class_name = self.lltype_to_cts(obj)
+            ret_type = self.lltype_to_cts(meth.RESULT)
+            arg_types = [self.lltype_to_cts(arg) for arg in meth.ARGS]
+            arg_list = ', '.join(arg_types)
+            return '%s %s::%s(%s)' % (ret_type, class_name, name, arg_list), False
+        else:
+            assert False
+
     def split_class_name(self, class_name):
         parts = class_name.rsplit('.', 1)
         if len(parts) == 2:

Modified: pypy/dist/pypy/translator/cli/function.py
==============================================================================
--- pypy/dist/pypy/translator/cli/function.py	(original)
+++ pypy/dist/pypy/translator/cli/function.py	Mon Apr 10 23:18:14 2006
@@ -238,18 +238,11 @@
         field_type = self.cts.lltype_to_cts(type_)
         return '%s %s::%s' % (field_type, class_name, field)
 
-    def ctor_name(self, ooinstance):
-        return 'instance void class %s::.ctor()' % self.class_name(ooinstance)
-
     # following methods belongs to the Generator interface
 
     def function_signature(self, graph):
         return self.cts.graph_to_signature(graph, False)
 
-    def method_signature(self, graph, class_name, name):
-        full_name = '%s::%s' % (class_name, name)
-        return self.cts.graph_to_signature(graph, True, full_name)
-
     def class_name(self, ooinstance):
         return ooinstance._name
 
@@ -261,7 +254,7 @@
         self.ilasm.call(func_name)
 
     def new(self, obj):
-        self.ilasm.new(self.ctor_name(obj))
+        self.ilasm.new(self.cts.ctor_name(obj))
 
     def set_field(self, obj, name):
         self.ilasm.opcode('stfld ' + self.field_name(obj, name))
@@ -270,11 +263,9 @@
         self.ilasm.opcode('ldfld ' + self.field_name(obj, name))
 
     def call_method(self, obj, name):
-        owner, meth = obj._lookup(name)
-        signature = self.method_signature(meth.graph, self.class_name(obj), name)
-        # TODO: there are cases when we don't need callvirt but a
-        # plain call is sufficient
-        self.ilasm.call_method(signature)
+        # TODO: use callvirt only when strictly necessary
+        signature, virtual = self.cts.method_signature(obj, name)
+        self.ilasm.call_method(signature, virtual)
 
     def load(self, v):
         if isinstance(v, flowmodel.Variable):

Modified: pypy/dist/pypy/translator/cli/ilgenerator.py
==============================================================================
--- pypy/dist/pypy/translator/cli/ilgenerator.py	(original)
+++ pypy/dist/pypy/translator/cli/ilgenerator.py	Mon Apr 10 23:18:14 2006
@@ -125,8 +125,11 @@
     def call(self, func):
         self.code.writeline('call ' + func)
 
-    def call_method(self, meth):
-        self.code.writeline('callvirt instance ' + meth)
+    def call_method(self, meth, virtual):
+        if virtual:
+            self.code.writeline('callvirt instance ' + meth)
+        else:
+            self.code.writeline('call instance ' + meth)
 
     def new(self, class_):
         self.code.writeline('newobj ' + class_)

Modified: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/cli/metavm.py	(original)
+++ pypy/dist/pypy/translator/cli/metavm.py	Mon Apr 10 23:18:14 2006
@@ -54,22 +54,6 @@
         cls = getattr(graph.func, 'class_', None)
 
         self._render_function(generator, graph, op.args)
-##        if cls is None:
-##            self._render_function(generator, graph, op.args)
-##        else:
-##            self._render_unbound_meth(generator, cls, graph, op.args)
-
-    def _render_unbound_meth(self, generator, cls, graph, args):
-        0/0
-        this = args[1]
-        # TODO: make sure that 'this' is compatible with 'cls'
-        for func_arg in args[1:]:
-            generator.load(func_arg)
-
-        # TODO: it doesn't work if cls is in another namespace
-        cls_name, meth_name = graph.name.rsplit('.', 1)
-        meth_sig = generator.method_signature(graph, cls_name, meth_name)
-        generator.call(graph, meth_sig) # TODO
 
     def _render_function(self, generator, graph, args):
         func_sig = generator.function_signature(graph)

Modified: pypy/dist/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/cli/opcodes.py	(original)
+++ pypy/dist/pypy/translator/cli/opcodes.py	Mon Apr 10 23:18:14 2006
@@ -11,7 +11,7 @@
 def _abs(type_):
     return [PushAllArgs, 'call %s class [mscorlib]System.Math::Abs(%s)' % (type_, type_)]
 
-_runtimenew = 'object [pypy]pypy.runtime.Utils::RuntimeNew([mscorlib]System.Type)'
+_runtimenew = 'object [pypylib]pypy.runtime.Utils::RuntimeNew([mscorlib]System.Type)'
 
 opcodes = {
     # __________ object oriented operations __________

Modified: pypy/dist/pypy/translator/cli/rte.py
==============================================================================
--- pypy/dist/pypy/translator/cli/rte.py	(original)
+++ pypy/dist/pypy/translator/cli/rte.py	Mon Apr 10 23:18:14 2006
@@ -6,10 +6,11 @@
 import os
 import os.path
 import subprocess
-import py
 
-SRC = 'pypy.cs'
-DLL = 'pypy.dll'
+from pypy.translator.cli.sdk import SDK
+
+SRC = 'pypylib.cs'
+DLL = 'pypylib.dll'
 
 def _filename(name):
     rel_path = os.path.join(os.path.dirname(__file__), 'src/' + name)
@@ -29,23 +30,19 @@
         pass
 
     if recompile:
-        compile(source)
+        compile(source, dll)
 
     return dll
     
-def compile(source):
-    mcs = _get_compiler()
-    compiler = subprocess.Popen([mcs, '/t:library', source],
+def compile(source, dll):
+    csc = SDK.csc()
+    compiler = subprocess.Popen([csc, '/t:library', '/out:%s' % dll, source],
                                 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     stdout, stderr = compiler.communicate()
     retval = compiler.wait()
 
     assert retval == 0, 'Failed to compile %s: the compiler said:\n %s' % (DLL, stderr)
 
-def _get_compiler():
-    try:
-        py.path.local.sysfind('mcs') # TODO: support windows
-        return 'mcs'
-    except py.error.ENOENT:
-        py.test.skip("%s is not on your path." % helper)
 
+if __name__ == '__main__':
+    get_pypy_dll()

Added: pypy/dist/pypy/translator/cli/sdk.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/cli/sdk.py	Mon Apr 10 23:18:14 2006
@@ -0,0 +1,40 @@
+import platform
+import py
+
+class AbstractSDK(object):
+    @classmethod
+    def _check_helper(cls, helper):
+        try:
+            py.path.local.sysfind(helper)
+            return helper
+        except py.error.ENOENT:
+            py.test.skip("%s is not on your path." % helper)
+
+    @classmethod
+    def runtime(cls):
+        for item in cls.RUNTIME:
+            cls._check_helper(item)
+        return cls.RUNTIME
+
+    @classmethod
+    def ilasm(cls):
+        return cls._check_helper(cls.ILASM)
+
+    @classmethod
+    def csc(cls):
+        return cls._check_helper(cls.CSC)
+
+class MicrosoftSDK(AbstractSDK):
+    RUNTIME = []
+    ILASM = 'ilasm'    
+    CSC = 'csc'
+
+class MonoSDK(AbstractSDK):
+    RUNTIME = ['mono']
+    ILASM = 'ilasm2'
+    CSC = 'gmcs'
+
+if platform.system() == 'Windows':
+    SDK = MicrosoftSDK
+else:
+    SDK = MonoSDK

Modified: pypy/dist/pypy/translator/cli/test/compile.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/compile.py	(original)
+++ pypy/dist/pypy/translator/cli/test/compile.py	Mon Apr 10 23:18:14 2006
@@ -23,23 +23,13 @@
     else:
         print 'OK'
 
-class Base:
-    def __init__(self, x):
-        self.x = x
-
-    def compute(self):
-        return self.x
-
-class Derived(Base):
-    def __init__(self, x):
-        Base.__init__(self, x+42)
-
-def foo(cls, x):
-    return cls(x).compute()
+def foo(mylist, i):
+    return mylist[i]
 
 def bar(x, y):
-    b = Derived(x)
-    return foo(Base, x) + foo(Derived, y)
+    mylist = [1,2,3,x,y]
+    mylist[0] = 432
+    return foo(mylist, (x+y)%5)
 
 f = compile_function(bar, [int, int])
 

Modified: pypy/dist/pypy/translator/cli/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/runtest.py	(original)
+++ pypy/dist/pypy/translator/cli/test/runtest.py	Mon Apr 10 23:18:14 2006
@@ -1,6 +1,5 @@
 import os
 import subprocess
-import platform
 import shutil
 
 import py
@@ -12,6 +11,7 @@
 from pypy.translator.cli.node import Node
 from pypy.translator.cli.cts import CTS
 from pypy.translator.cli.database import LowLevelDatabase
+from pypy.translator.cli.sdk import SDK
 from pypy.translator.cli.rte import get_pypy_dll
 
 FLOAT_PRECISION = 8
@@ -111,19 +111,6 @@
 
         return GenCli(self.tmpdir, t, TestEntryPoint(self.graph))
 
-    def __check_helper(self, helper):
-        try:
-            py.path.local.sysfind(helper)
-        except py.error.ENOENT:
-            py.test.skip("%s is not on your path." % helper)
-
-    def __get_runtime(self):
-        if platform.system() == 'Windows':
-            return []
-        else:
-            self.__check_helper('mono')
-            return ['mono']
-
     def _build_exe(self):        
         tmpfile = self._gen.generate_source()
         if getoption('source'):
@@ -132,10 +119,10 @@
         pypy_dll = get_pypy_dll() # get or recompile pypy.dll
         shutil.copy(pypy_dll, self.tmpdir.strpath)
 
-        self.__check_helper("ilasm")
-        ilasm = subprocess.Popen(["ilasm", tmpfile], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-        stdout, stderr = ilasm.communicate()
-        retval = ilasm.wait()
+        ilasm = SDK.ilasm()
+        proc = subprocess.Popen([ilasm, tmpfile], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        stdout, stderr = proc.communicate()
+        retval = proc.wait()
         assert retval == 0, 'ilasm failed to assemble %s (%s):\n%s' % (self.graph.name, tmpfile, stdout)
         return tmpfile.replace('.il', '.exe')
 
@@ -143,8 +130,7 @@
         if self._exe is None:
             py.test.skip("Compilation disabled")
 
-        runtime = self.__get_runtime()
-        arglist = runtime + [self._exe] + map(str, args)
+        arglist = SDK.runtime() + [self._exe] + map(str, args)
         mono = subprocess.Popen(arglist, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         stdout, stderr = mono.communicate()
         retval = mono.wait()

Added: pypy/dist/pypy/translator/cli/test/test_list.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/cli/test/test_list.py	Mon Apr 10 23:18:14 2006
@@ -0,0 +1,30 @@
+from pypy.translator.cli.test.runtest import check
+
+def test_list():
+    for name, func in globals().iteritems():
+        if not name.startswith('list_'):
+            continue
+
+        yield check, func, [int, int], (42, 13)
+
+
+def create(x, y):
+    return [x, y, x+y, x*y]
+
+def sum_(lst):
+    total = 0
+    i = 0
+    while i < len(lst):
+        total += lst[i]
+        i += 1
+
+    return total    
+
+def list_sum(x, y):
+    return sum_(create(x, y))
+
+def list_setitem(x, y):
+    lst = create(x, y)
+    lst[0] = 0
+    lst[1] = 0
+    return sum_(lst)



More information about the Pypy-commit mailing list