[pypy-svn] r33434 - in pypy/dist/pypy/translator: . cli cli/test
antocuni at codespeak.net
antocuni at codespeak.net
Thu Oct 19 00:21:44 CEST 2006
Author: antocuni
Date: Thu Oct 19 00:21:43 2006
New Revision: 33434
Modified:
pypy/dist/pypy/translator/cli/database.py
pypy/dist/pypy/translator/cli/dotnet.py
pypy/dist/pypy/translator/cli/metavm.py
pypy/dist/pypy/translator/cli/support.py
pypy/dist/pypy/translator/cli/test/runtest.py
pypy/dist/pypy/translator/cli/test/test_builtin.py
pypy/dist/pypy/translator/cli/test/test_dotnet.py
pypy/dist/pypy/translator/cli/test/test_runtest.py
pypy/dist/pypy/translator/driver.py
Log:
Second attempt to ".NET-types". The implementation is quite simple
because it reuses most of the logic from ootype.
Modified: pypy/dist/pypy/translator/cli/database.py
==============================================================================
--- pypy/dist/pypy/translator/cli/database.py (original)
+++ pypy/dist/pypy/translator/cli/database.py Thu Oct 19 00:21:43 2006
@@ -14,6 +14,7 @@
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.lltypesystem import llmemory
from pypy.translator.cli.opcodes import opcodes
+from pypy.translator.cli import dotnet
from pypy.rpython.objectmodel import CDefinedIntSymbolic
try:
@@ -102,16 +103,21 @@
return self.classes[INSTANCE]
except KeyError:
pass
- namespace, name = self._default_class_name(INSTANCE)
- name = self.get_unique_class_name(namespace, name)
- if namespace is None:
- full_name = name
+
+ if isinstance(INSTANCE, dotnet.NativeInstance):
+ self.classes[INSTANCE] = INSTANCE._name
+ return INSTANCE._name
else:
- full_name = '%s.%s' % (namespace, name)
- self.classes[INSTANCE] = full_name
- cls = Class(self, INSTANCE, namespace, name)
- self.pending_node(cls)
- return full_name
+ namespace, name = self._default_class_name(INSTANCE)
+ name = self.get_unique_class_name(namespace, name)
+ if namespace is None:
+ full_name = name
+ else:
+ full_name = '%s.%s' % (namespace, name)
+ self.classes[INSTANCE] = full_name
+ cls = Class(self, INSTANCE, namespace, name)
+ self.pending_node(cls)
+ return full_name
def pending_record(self, RECORD):
try:
Modified: pypy/dist/pypy/translator/cli/dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/dotnet.py (original)
+++ pypy/dist/pypy/translator/cli/dotnet.py Thu Oct 19 00:21:43 2006
@@ -3,32 +3,42 @@
from pypy.annotation import model as annmodel
from pypy.rpython.rmodel import Repr
+## Annotation model
+
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 simple_call(self, *s_args):
+ assert self.is_constant()
+ return annmodel.SomeOOInstance(self.const._INSTANCE)
+
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
+ def simple_call(self, *args_s):
+ return self.cli_class._ann_static_method(self.meth_name, args_s)
+
+
+
+## Rtyper model
class CliClassRepr(Repr):
lowleveltype = ootype.Void
@@ -39,14 +49,12 @@
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
-
+ def rtype_simple_call(self, hop):
+ # TODO: resolve constructor overloading
+ INSTANCE = hop.args_r[0].cli_class._INSTANCE
+ cINST = hop.inputconst(ootype.Void, INSTANCE)
+ vlist = hop.inputargs(*hop.args_r)[1:] # discard the first argument
+ return hop.genop("new", [cINST]+vlist, resulttype=hop.r_result.lowleveltype)
class CliStaticMethodRepr(Repr):
lowleveltype = ootype.Void
@@ -57,7 +65,7 @@
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)
+ return StaticMethodDesc(self.cli_class._INSTANCE._name, self.meth_name, argtypes, resulttype)
def rtype_simple_call(self, hop):
vlist = []
@@ -69,26 +77,39 @@
return hop.genop("direct_call", [v_desc] + vlist, resulttype=resulttype)
+
+## RPython interface definition
+
+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 CliClass(object):
- def __init__(self, name, methods):
- self.name = name
- self.methods = methods
+ def __init__(self, INSTANCE, static_methods):
+ self._INSTANCE = INSTANCE
+ self._static_methods = static_methods
- def annotate_method(self, meth_name, args_s):
- argtypes, rettype = self._lookup(meth_name, args_s)
- return annmodel.lltype_to_annotation(rettype)
+ def __repr__(self):
+ return '<%s>' % (self,)
+
+ def __str__(self):
+ return '%s(%s)' % (self.__class__.__name__, self._INSTANCE._name)
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])
+ overloads = self._static_methods[meth_name]
+ argtypes = tuple([annmodel.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)
+ def _ann_static_method(self, meth_name, args_s):
+ argtypes, rettype = self._lookup(meth_name, args_s)
+ return annmodel.lltype_to_annotation(rettype)
+
class Entry(ExtRegistryEntry):
_type_ = CliClass
@@ -96,11 +117,27 @@
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}
- })
+
+## OOType model
+
+class NativeInstance(ootype.Instance):
+ def __init__(self, assembly, namespace, name, superclass,
+ fields={}, methods={}, _is_root=False, _hints = {}):
+ fullname = '%s%s.%s' % (assembly, namespace, name)
+ ootype.Instance.__init__(self, fullname, superclass, fields, methods, _is_root, _hints)
+
+STRING_BUILDER = NativeInstance('[mscorlib]', 'System.Text', 'StringBuilder', ootype.ROOT, {}, {})
+STRING_BUILDER._add_methods({'Append': ootype.meth(ootype.Meth([ootype.String], STRING_BUILDER))})
+StringBuilder = CliClass(STRING_BUILDER, {})
+
+CONSOLE = NativeInstance('[mscorlib]', 'System', 'Console', ootype.ROOT, {}, {})
+Console = CliClass(CONSOLE, {'WriteLine': {(ootype.String,): ootype.Void,
+ (ootype.Signed,): ootype.Void}})
+MATH = NativeInstance('[mscorlib]', 'System', 'Math', ootype.ROOT, {}, {})
+Math = CliClass(MATH, {'Abs': {(ootype.Signed,): ootype.Signed,
+ (ootype.Float,): ootype.Float}})
+
+ARRAY_LIST = NativeInstance('[mscorlib]', 'System.Collections', 'ArrayList', ootype.ROOT, {},
+ {'Add': ootype.meth(ootype.Meth([ootype.ROOT], ootype.Signed)),
+ 'get_Count': ootype.meth(ootype.Meth([], ootype.Signed))})
+ArrayList = CliClass(ARRAY_LIST, {})
Modified: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/cli/metavm.py (original)
+++ pypy/dist/pypy/translator/cli/metavm.py Thu Oct 19 00:21:43 2006
@@ -28,7 +28,7 @@
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)
+ signature = '%s %s::%s(%s)' % (ret_type, funcdesc.class_name, funcdesc.method_name, arg_list)
generator.call_signature(signature)
def _render_function(self, generator, graph, args):
Modified: pypy/dist/pypy/translator/cli/support.py
==============================================================================
--- pypy/dist/pypy/translator/cli/support.py (original)
+++ pypy/dist/pypy/translator/cli/support.py Thu Oct 19 00:21:43 2006
@@ -1,3 +1,5 @@
+from pypy.rpython.ootypesystem import ootype
+
# some code has been stolen from genc
def string_literal(s):
def char_repr(c):
@@ -58,7 +60,7 @@
O_BINARY = 0x8000
)
-def patch_os(defs=None):
+def _patch_os(defs=None):
"""
Modify the value of some attributes of the os module to be sure
they are the same on every platform pypy is compiled on. Returns a
@@ -77,3 +79,24 @@
pass
setattr(os, name, value)
return olddefs
+
+def _patch_ROOT():
+ """
+ In gencli ootype.ROOT corresponds to System.Object: make the
+ annotator aware of its native methods such as ToString().
+ """
+ oldmeths = ootype.ROOT._methods.copy()
+ ootype.ROOT._add_methods({'ToString': ootype.meth(ootype.Meth([], ootype.String))})
+ return oldmeths
+
+def _unpatch_ROOT(oldmeths):
+ ootype.ROOT._methods = oldmeths
+
+def patch():
+ olddefs = _patch_os()
+ oldmeths = _patch_ROOT()
+ return olddefs, oldmeths
+
+def unpatch(olddefs, oldmeths):
+ _patch_os(olddefs)
+ _unpatch_ROOT(oldmeths)
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 Thu Oct 19 00:21:43 2006
@@ -18,7 +18,7 @@
from pypy.translator.cli.database import LowLevelDatabase
from pypy.translator.cli.sdk import SDK
from pypy.translator.cli.entrypoint import BaseEntryPoint
-from pypy.translator.cli.support import patch_os
+from pypy.translator.cli.support import patch, unpatch
FLOAT_PRECISION = 8
@@ -113,11 +113,11 @@
def compile_function(func, annotation=[], graph=None):
- olddefs = patch_os() # patch the values of some attributes of the os module
+ olddefs = patch()
gen = _build_gen(func, annotation, graph)
gen.generate_source()
exe_name = gen.build_exe()
- patch_os(olddefs) # restore original values
+ unpatch(*olddefs) # restore original values
return CliFunctionWrapper(exe_name)
def _build_gen(func, annotation, graph=None):
@@ -136,6 +136,9 @@
ann = t.buildannotator()
ann.build_types(func, annotation)
+ if getoption('view'):
+ t.view()
+
t.buildrtyper(type_system="ootype").specialize()
main_graph = t.graphs[0]
Modified: pypy/dist/pypy/translator/cli/test/test_builtin.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_builtin.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_builtin.py Thu Oct 19 00:21:43 2006
@@ -17,14 +17,6 @@
test_os_path_exists = skip_os
test_os_isdir = skip_os
- def test_patch_os(self):
- from pypy.translator.cli.support import patch_os, NT_OS
- original_O_CREAT = os.O_CREAT
- olddefs = patch_os()
- assert os.O_CREAT == NT_OS['O_CREAT']
- patch_os(olddefs)
- assert os.O_CREAT == original_O_CREAT
-
def test_os_flags(self):
from pypy.translator.cli.support import NT_OS
def fn():
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 Thu Oct 19 00:21:43 2006
@@ -1,9 +1,61 @@
+from pypy.annotation.annrpython import RPythonAnnotator
+from pypy.annotation import model as annmodel
from pypy.translator.cli.test.runtest import CliTest
-from pypy.translator.cli.dotnet import Math
+from pypy.translator.cli.dotnet import SomeCliClass, SomeCliStaticMethod,\
+ NativeInstance, Math, ArrayList, StringBuilder
class TestDotnet(CliTest):
- def test_abs(self):
+ def test_class_ann(self):
+ def fn():
+ return Math
+ a = RPythonAnnotator()
+ s = a.build_types(fn, [])
+ assert isinstance(s, SomeCliClass)
+ assert s.const is Math
+
+ def test_staticmeth_ann(self):
+ def fn():
+ return Math.Abs
+ a = RPythonAnnotator()
+ s = a.build_types(fn, [])
+ assert isinstance(s, SomeCliStaticMethod)
+ assert s.cli_class is Math
+ assert s.meth_name == 'Abs'
+
+ def test_new_instance_ann(self):
+ def fn():
+ return ArrayList()
+ a = RPythonAnnotator()
+ s = a.build_types(fn, [])
+ assert isinstance(s, annmodel.SomeOOInstance)
+ assert isinstance(s.ootype, NativeInstance)
+ assert s.ootype._name == '[mscorlib]System.Collections.ArrayList'
+
+ def test_static_method_call(self):
def fn(x):
return Math.Abs(x)
assert self.interpret(fn, [-42]) == 42
+
+ def test_static_method_overload(self):
+ def fn(x, y):
+ return Math.Abs(x), Math.Abs(y)
+ res = self.interpret(fn, [-42, -42.5])
+ assert res.item0 == 42
+ assert res.item1 == 42.5
+
+ def test_method_call(self):
+ def fn():
+ x = ArrayList()
+ x.Add("foo")
+ x.Add("bar")
+ return x.get_Count()
+ assert self.interpret(fn, []) == 2
+
+ def test_tostring(self):
+ def fn():
+ x = StringBuilder()
+ x.Append("foo").Append("bar")
+ return x.ToString()
+ res = self.ll_to_string(self.interpret(fn, []))
+ assert res == 'foobar'
Modified: pypy/dist/pypy/translator/cli/test/test_runtest.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_runtest.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_runtest.py Thu Oct 19 00:21:43 2006
@@ -7,6 +7,23 @@
class TestRunTest(CliTest):
+ def test_patch_os(self):
+ import os
+ from pypy.translator.cli.support import patch, unpatch, NT_OS
+ original_O_CREAT = os.O_CREAT
+ olddefs = patch()
+ assert os.O_CREAT == NT_OS['O_CREAT']
+ unpatch(*olddefs)
+ assert os.O_CREAT == original_O_CREAT
+
+ def test_patch_ROOT(self):
+ from pypy.translator.cli.support import patch, unpatch
+ from pypy.rpython.ootypesystem import ootype
+ olddefs = patch()
+ assert 'ToString' in ootype.ROOT._methods
+ unpatch(*olddefs)
+ assert 'ToString' not in ootype.ROOT._methods
+
def test_int(self):
assert self.interpret(ident, [42]) == 42
Modified: pypy/dist/pypy/translator/driver.py
==============================================================================
--- pypy/dist/pypy/translator/driver.py (original)
+++ pypy/dist/pypy/translator/driver.py Thu Oct 19 00:21:43 2006
@@ -508,12 +508,12 @@
'Generating CLI source')
def task_compile_cli(self):
- from pypy.translator.cli.support import patch_os
+ from pypy.translator.cli.support import unpatch
from pypy.translator.cli.test.runtest import CliFunctionWrapper
filename = self.gen.build_exe()
self.c_entryp = CliFunctionWrapper(filename)
# restore original os values
- patch_os(self.old_os_defs)
+ unpatch(*self.old_cli_defs)
self.log.info("Compiled %s" % filename)
task_compile_cli = taskdef(task_compile_cli, ['source_cli'],
@@ -550,8 +550,8 @@
# have the same value on every platform.
backend, ts = driver.get_backend_and_type_system()
if backend == 'cli':
- from pypy.translator.cli.support import patch_os
- driver.old_os_defs = patch_os()
+ from pypy.translator.cli.support import patch
+ driver.old_cli_defs = patch()
target = targetspec_dic['target']
spec = target(driver, args)
More information about the pypy-svn
mailing list