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

antocuni at codespeak.net antocuni at codespeak.net
Mon Oct 16 22:58:52 CEST 2006


Author: antocuni
Date: Mon Oct 16 22:58:51 2006
New Revision: 33351

Added:
   pypy/dist/pypy/translator/cli/dotnet.py   (contents, props changed)
   pypy/dist/pypy/translator/cli/test/test_dotnet.py   (contents, props changed)
Modified:
   pypy/dist/pypy/translator/cli/metavm.py
Log:
First attempt to expose CLI native classes and methods to RPython.
The goals of dotnet.py and ootypesystem/bltregistry.py are a bit
overlapping, so they could be merged in the future.



Added: pypy/dist/pypy/translator/cli/dotnet.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/cli/dotnet.py	Mon Oct 16 22:58:51 2006
@@ -0,0 +1,106 @@
+from pypy.rpython.extregistry import ExtRegistryEntry
+from pypy.rpython.ootypesystem import ootype
+from pypy.annotation import model as annmodel
+from pypy.rpython.rmodel import Repr
+
+class SomeCliClass(annmodel.SomeObject):
+    def getattr(self, s_attr):
+        assert self.is_constant()
+        assert s_attr.is_constant()
+        return SomeCliStaticMethod(self.const, s_attr.const)
+
+    def rtyper_makerepr(self, rtyper):
+        return CliClassRepr(self.const)
+
+    def rtyper_makekey(self):
+        return self.__class__, self.const
+
+class SomeCliStaticMethod(annmodel.SomeObject):
+    def __init__(self, cli_class, meth_name):
+        self.cli_class = cli_class
+        self.meth_name = meth_name
+
+    def simple_call(self, *args_s):
+        return self.cli_class.annotate_method(self.meth_name, args_s)
+
+    def rtyper_makerepr(self, rtyper):
+        return CliStaticMethodRepr(self.cli_class, self.meth_name)
+
+    def rtyper_makekey(self):
+        return self.__class__, self.cli_class, self.meth_name
+
+
+class CliClassRepr(Repr):
+    lowleveltype = ootype.Void
+
+    def __init__(self, cli_class):
+        self.cli_class = cli_class
+
+    def rtype_getattr(self, hop):
+        return hop.inputconst(ootype.Void, self.cli_class)
+
+class StaticMethodDesc(object):
+    def __init__(self, class_name, method_name, argtypes, resulttype):
+        # TODO: maybe use ootype.StaticMeth for describing signature?
+        self.class_name = class_name
+        self.method_name = method_name
+        self.argtypes = argtypes
+        self.resulttype = resulttype
+
+
+class CliStaticMethodRepr(Repr):
+    lowleveltype = ootype.Void
+
+    def __init__(self, cli_class, meth_name):
+        self.cli_class = cli_class
+        self.meth_name = meth_name
+
+    def _build_desc(self, args_v, resulttype):
+        argtypes = [v.concretetype for v in args_v]
+        return StaticMethodDesc(self.cli_class.name, self.meth_name, argtypes, resulttype)
+
+    def rtype_simple_call(self, hop):
+        vlist = []
+        for i, repr in enumerate(hop.args_r[1:]):
+            vlist.append(hop.inputarg(repr, i+1))
+        resulttype = hop.r_result.lowleveltype
+        desc = self._build_desc(vlist, resulttype)
+        v_desc = hop.inputconst(ootype.Void, desc)
+        return hop.genop("direct_call", [v_desc] + vlist, resulttype=resulttype)
+
+
+class CliClass(object):
+    def __init__(self, name, methods):
+        self.name = name
+        self.methods = methods
+
+    def annotate_method(self, meth_name, args_s):
+        argtypes, rettype = self._lookup(meth_name, args_s)
+        return annmodel.lltype_to_annotation(rettype)
+
+    def _lookup(self, meth_name, args_s):
+        # TODO: handle conversion
+        overloads = self.methods[meth_name]
+        argtypes = tuple([_annotation_to_lltype(arg_s) for arg_s in args_s])
+        return argtypes, overloads[argtypes]
+
+def _annotation_to_lltype(arg_s):
+    if isinstance(arg_s, annmodel.SomeString):
+        return ootype.String
+    else:
+        return annmodel.annotation_to_lltype(arg_s)
+
+class Entry(ExtRegistryEntry):
+    _type_ = CliClass
+
+    def compute_annotation(self):
+        return SomeCliClass()
+
+Console = CliClass('System.Console',
+                   {'WriteLine': {(ootype.String,): ootype.Void,
+                                  (ootype.Signed,): ootype.Void,
+                                  (ootype.String, ootype.Signed): ootype.Void }
+                    })
+Math = CliClass('System.Math',
+                {'Abs': {(ootype.Signed,): ootype.Signed}
+                 })

Modified: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/cli/metavm.py	(original)
+++ pypy/dist/pypy/translator/cli/metavm.py	Mon Oct 16 22:58:51 2006
@@ -4,17 +4,32 @@
      PushAllArgs, StoreResult, GetField, SetField, DownCast
 from pypy.translator.cli.comparer import EqualityComparer
 from pypy.translator.cli.cts import WEAKREF
+from pypy.translator.cli.dotnet import StaticMethodDesc
 
 STRING_HELPER_CLASS = '[pypylib]pypy.runtime.String'
 
 class _Call(MicroInstruction):
     def render(self, generator, op):
-        graph = op.args[0].value.graph
-        method_name = oopspec.get_method_name(graph, op)
-        if method_name is None:
-            self._render_function(generator, graph, op.args)
+        callee = op.args[0].value
+        if isinstance(callee, StaticMethodDesc):
+            self._render_native_function(generator, callee, op.args)
         else:
-            self._render_method(generator, method_name, op.args[1:])
+            graph = callee.graph
+            method_name = oopspec.get_method_name(graph, op)
+            if method_name is None:
+                self._render_function(generator, graph, op.args)
+            else:
+                self._render_method(generator, method_name, op.args[1:])
+
+    def _render_native_function(self, generator, funcdesc, args):
+        for func_arg in args[1:]: # push parameters
+            generator.load(func_arg)
+        cts = generator.cts
+        ret_type = cts.lltype_to_cts(funcdesc.resulttype)
+        arg_types = [cts.lltype_to_cts(arg) for arg in funcdesc.argtypes if arg is not ootype.Void]
+        arg_list = ', '.join(arg_types)
+        signature = '%s [mscorlib]%s::%s(%s)' % (ret_type, funcdesc.class_name, funcdesc.method_name, arg_list)
+        generator.call_signature(signature)
 
     def _render_function(self, generator, graph, args):
         primitive = getattr(graph.func, 'suggested_primitive', False)

Added: pypy/dist/pypy/translator/cli/test/test_dotnet.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/cli/test/test_dotnet.py	Mon Oct 16 22:58:51 2006
@@ -0,0 +1,9 @@
+from pypy.translator.cli.test.runtest import CliTest
+from pypy.translator.cli.dotnet import Math
+
+class TestDotnet(CliTest):
+
+    def test_abs(self):
+        def fn(x):
+            return Math.Abs(x)
+        assert self.interpret(fn, [-42]) == 42



More information about the Pypy-commit mailing list