[pypy-svn] r25494 - in pypy/dist/pypy/translator/cli: . test
antocuni at codespeak.net
antocuni at codespeak.net
Fri Apr 7 15:11:38 CEST 2006
Author: antocuni
Date: Fri Apr 7 15:11:23 2006
New Revision: 25494
Added:
pypy/dist/pypy/translator/cli/database.py (contents, props changed)
Modified:
pypy/dist/pypy/translator/cli/class_.py
pypy/dist/pypy/translator/cli/cts.py
pypy/dist/pypy/translator/cli/function.py
pypy/dist/pypy/translator/cli/gencli.py
pypy/dist/pypy/translator/cli/metavm.py
pypy/dist/pypy/translator/cli/test/compile.py
pypy/dist/pypy/translator/cli/test/runtest.py
pypy/dist/pypy/translator/cli/test/test_oo.py
Log:
Added support for unbound methods
Modified: pypy/dist/pypy/translator/cli/class_.py
==============================================================================
--- pypy/dist/pypy/translator/cli/class_.py (original)
+++ pypy/dist/pypy/translator/cli/class_.py Fri Apr 7 15:11:23 2006
@@ -3,7 +3,8 @@
from pypy.translator.cli import cts
class Class(Node):
- def __init__(self, classdef):
+ def __init__(self, db, classdef):
+ self.db = db
self.classdef = classdef
self.namespace, self.name = cts.split_class_name(classdef._name)
@@ -30,9 +31,8 @@
self._ctor()
for m_name, m_meth in self.classdef._methods.iteritems():
- # TODO: handle static, class and unbound methods
- # TODO: should __init__ be rendered as a constructor?
- f = Function(m_meth.graph, m_name, is_method = True)
+ # TODO: handle class and unbound methods
+ f = Function(self.db, m_meth.graph, m_name, is_method = True)
f.render(ilasm)
ilasm.end_class()
Modified: pypy/dist/pypy/translator/cli/cts.py
==============================================================================
--- pypy/dist/pypy/translator/cli/cts.py (original)
+++ pypy/dist/pypy/translator/cli/cts.py Fri Apr 7 15:11:23 2006
@@ -47,10 +47,10 @@
def lltype_to_cts(t):
if isinstance(t, Instance):
- name = t._name.replace('__main__.', '') # TODO: modules
- if name in ('Object_meta', 'Object'):
+ name = t._name
+ if 'Object_meta' in name or 'Object' in name: # TODO
return 'object'
-
+
return 'class %s' % name
return _get_from_dict(_lltype_to_cts, t, 'Unknown type %s' % t)
Added: pypy/dist/pypy/translator/cli/database.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/cli/database.py Fri Apr 7 15:11:23 2006
@@ -0,0 +1,18 @@
+try:
+ set
+except NameError:
+ from sets import Set as set
+
+
+class LowLevelDatabase(object):
+ def __init__(self):
+ self.classes = set()
+ self.pending_graphs = []
+ self.functions = {} # graph --> function_name
+ self.methods = {} # graph --> method_name
+
+ def record_function(self, graph, name):
+ self.functions[graph] = name
+
+ def function_name(self, graph):
+ return self.functions.get(graph, None)
Modified: pypy/dist/pypy/translator/cli/function.py
==============================================================================
--- pypy/dist/pypy/translator/cli/function.py (original)
+++ pypy/dist/pypy/translator/cli/function.py Fri Apr 7 15:11:23 2006
@@ -18,13 +18,13 @@
py.log.setconsumer("cli", ansi_log)
class Function(Node, Generator):
- def __init__(self, graph, name = None, is_method = False, is_entrypoint = False):
+ def __init__(self, db, graph, name = None, is_method = False, is_entrypoint = False):
+ self.db = db
self.graph = graph
self.name = name or graph.name
self.is_method = is_method
self.is_entrypoint = is_entrypoint
self.blocknum = {}
- self.classdefs = set()
self._set_args()
self._set_locals()
@@ -130,6 +130,10 @@
self.ilasm.opcode('ret')
self.ilasm.end_function()
+ if self.is_method:
+ pass # TODO
+ else:
+ self.db.record_function(self.graph, self.name)
def _setup_link(self, link):
target = link.target
@@ -197,7 +201,7 @@
lltype = arg.value
if isinstance(lltype, Instance):
- self.classdefs.add(lltype)
+ self.db.classes.add(lltype)
def _render_op(self, op):
@@ -225,8 +229,9 @@
def function_signature(self, graph):
return cts.graph_to_signature(graph, False)
- def method_signature(self, graph, name):
- return cts.graph_to_signature(graph, True, name)
+ def method_signature(self, graph, class_name, name):
+ full_name = '%s::%s' % (class_name, name)
+ return cts.graph_to_signature(graph, True, full_name)
def class_name(self, ooinstance):
return ooinstance._name
@@ -234,7 +239,8 @@
def emit(self, instr, *args):
self.ilasm.opcode(instr, *args)
- def call(self, func_name):
+ def call(self, graph, func_name):
+ self.db.pending_graphs.append(graph)
self.ilasm.call(func_name)
def new(self, obj):
@@ -248,10 +254,10 @@
def call_method(self, obj, name):
owner, meth = obj._lookup(name)
- full_name = '%s::%s' % (self.class_name(obj), 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(self.method_signature(meth.graph, full_name))
+ self.ilasm.call_method(signature)
def load(self, v):
if isinstance(v, flowmodel.Variable):
@@ -265,8 +271,9 @@
self.ilasm.opcode('ldloc', repr(v.name))
elif isinstance(v, flowmodel.Constant):
- iltype, ilvalue = cts.llconst_to_ilasm(v)
- self.ilasm.opcode('ldc.' + iltype, ilvalue)
+ if v.concretetype != Void:
+ iltype, ilvalue = cts.llconst_to_ilasm(v)
+ self.ilasm.opcode('ldc.' + iltype, ilvalue)
else:
assert False
Modified: pypy/dist/pypy/translator/cli/gencli.py
==============================================================================
--- pypy/dist/pypy/translator/cli/gencli.py (original)
+++ pypy/dist/pypy/translator/cli/gencli.py Fri Apr 7 15:11:23 2006
@@ -1,8 +1,3 @@
-try:
- set
-except NameError:
- from sets import Set as set
-
import sys
from types import MethodType
@@ -11,6 +6,7 @@
from pypy.translator.cli.function import Function
from pypy.translator.cli.class_ import Class
from pypy.translator.cli.option import getoption
+from pypy.translator.cli.database import LowLevelDatabase
class Tee(object):
@@ -31,7 +27,7 @@
self.tmpdir = tmpdir
self.translator = translator
self.entrypoint = entrypoint
- self.classdefs = set()
+ self.db = LowLevelDatabase()
if entrypoint is None:
self.assembly_name = self.translator.graphs[0].name
@@ -46,41 +42,41 @@
out = Tee(sys.stdout, out)
self.ilasm = IlasmGenerator(out, self.assembly_name)
- self.gen_all_functions()
+ self.gen_entrypoint()
self.find_superclasses()
self.gen_classes()
+ self.gen_functions()
out.close()
return self.tmpfile.strpath
- def gen_all_functions(self):
+ def gen_entrypoint(self):
if self.entrypoint:
- self.entrypoint.render(self.ilasm)
-
- # generate code for all 'global' functions, i.e., those who are not methods.
- for graph in self.translator.graphs:
+ self.db.pending_graphs += self.entrypoint.render(self.ilasm)
+ else:
+ self.db.pending_graphs.append(self.translator.graphs[0])
- # TODO: remove this test
- if graph.name.startswith('ll_'):
- continue
+ self.gen_functions()
- if '.' not in graph.name: # it's not a method
- f = Function(graph)
+ def gen_functions(self):
+ while self.db.pending_graphs:
+ graph = self.db.pending_graphs.pop()
+ if self.db.function_name(graph) is None:
+ f = Function(self.db, graph)
f.render(self.ilasm)
- self.classdefs.update(f.classdefs)
def find_superclasses(self):
- classdefs = set()
- pendings = self.classdefs
+ classes = set()
+ pendings = self.db.classes
while pendings:
classdef = pendings.pop()
- if classdef not in classdefs and classdef is not None:
- classdefs.add(classdef)
+ if classdef not in classes and classdef is not None:
+ classes.add(classdef)
pendings.add(classdef._superclass)
- self.classdefs = classdefs
+ self.db.classes = classes
def gen_classes(self):
- for classdef in self.classdefs:
- c = Class(classdef)
+ for classdef in self.db.classes:
+ c = Class(self.db, classdef)
c.render(self.ilasm)
Modified: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/cli/metavm.py (original)
+++ pypy/dist/pypy/translator/cli/metavm.py Fri Apr 7 15:11:23 2006
@@ -50,13 +50,32 @@
class _Call(MicroInstruction):
def render(self, generator, op):
- func_sig = generator.function_signature(op.args[0].value.graph)
+ graph = op.args[0].value.graph
+ cls = getattr(graph.func, 'class_', None)
- # push parameters
- for func_arg in op.args[1:]:
+ 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)
- generator.call(func_sig)
+ # 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)
+ for func_arg in args[1:]: # push parameters
+ generator.load(func_arg)
+ generator.call(graph, func_sig)
class _New(MicroInstruction):
def render(self, generator, op):
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 Fri Apr 7 15:11:23 2006
@@ -27,10 +27,15 @@
self.x = x
class Derived(Base):
- pass
+ def __init__(self, x):
+ Base.__init__(self, x)
+
+def foo(x):
+ return x+1
def bar(x, y):
- a = Derived(42)
+ a = Derived(x)
+ return a.x
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 Fri Apr 7 15:11:23 2006
@@ -54,6 +54,7 @@
ilasm.call('void class [mscorlib]System.Console::WriteLine(%s)' % ret_type)
ilasm.opcode('ret')
ilasm.end_function()
+ return [self.graph]
def __convert_method(self, arg_type):
_conv = {
Modified: pypy/dist/pypy/translator/cli/test/test_oo.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_oo.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_oo.py Fri Apr 7 15:11:23 2006
@@ -19,10 +19,13 @@
def compute_and_multiply(self, factor):
return self.compute() * factor
+ def static_meth(x, y):
+ return x*y
+ static_meth = staticmethod(static_meth)
+
class MyDerivedClass(MyClass):
def __init__(self, x, y):
- self.x = x
- self.y = y
+ MyClass.__init__(self, x, y)
def compute(self):
return self.x - self.y
@@ -46,3 +49,10 @@
base = MyClass(x, y)
derived = MyDerivedClass(x, y)
return helper(base) + helper(derived)
+
+def oo_static_method(x, y):
+ base = MyClass(x, y)
+ derived = MyDerivedClass(x, y)
+ return base.static_meth(x,y) + derived.static_meth(x, y)\
+ + MyClass.static_meth(x, y) + MyDerivedClass.static_meth(x, y)
+
More information about the Pypy-commit
mailing list