[pypy-svn] r76356 - in pypy/branch/avm/pypy/translator/avm2: . test

magcius at codespeak.net magcius at codespeak.net
Tue Jul 27 00:14:12 CEST 2010


Author: magcius
Date: Tue Jul 27 00:14:11 2010
New Revision: 76356

Added:
   pypy/branch/avm/pypy/translator/avm2/codegen.py   (contents, props changed)
   pypy/branch/avm/pypy/translator/avm2/node.py
   pypy/branch/avm/pypy/translator/avm2/playerglobal.py
   pypy/branch/avm/pypy/translator/avm2/rlib.py   (contents, props changed)
Removed:
   pypy/branch/avm/pypy/translator/avm2/_playerglobal.py
   pypy/branch/avm/pypy/translator/avm2/avm2gen.py
   pypy/branch/avm/pypy/translator/avm2/query.py
   pypy/branch/avm/pypy/translator/avm2/test/bootstrap.py
   pypy/branch/avm/pypy/translator/avm2/test/simpletest.py
   pypy/branch/avm/pypy/translator/avm2/test/test_script.py
Log:
Clean up and get stuff working

Added: pypy/branch/avm/pypy/translator/avm2/codegen.py
==============================================================================
--- (empty file)
+++ pypy/branch/avm/pypy/translator/avm2/codegen.py	Tue Jul 27 00:14:11 2010
@@ -0,0 +1,134 @@
+""" backend generator routines
+"""
+
+import re
+
+from pypy.objspace.flow.model import Variable, Constant
+from pypy.rpython.ootypesystem import ootype
+from pypy.translator.avm2 import types_ as types
+from pypy.translator.oosupport.metavm import Generator
+from pypy.translator.oosupport.treebuilder import SubOperation
+from pypy.translator.oosupport.constant import push_constant
+from pypy.translator.oosupport.function import render_sub_op
+
+from mech.fusion.avm2 import instructions, codegen
+from mech.fusion.avm2.constants import MultinameL
+from mech.fusion.avm2.interfaces import LoadableAdapter, IMultiname
+
+from zope.interface import implementer
+from zope.component import provideAdapter, adapter
+
+ at adapter(Variable)
+class VariableLoadable(LoadableAdapter):
+    def load(self, generator):
+        v = self.value
+        if v.concretetype is ootype.Void:
+            generator.push_null()
+        else:
+            generator.push_local(v)
+
+provideAdapter(VariableLoadable)
+
+ at adapter(Constant)
+class ConstantLoadable(LoadableAdapter):
+    def load(self, generator):
+        v = self.value
+        push_constant(generator.db, v.concretetype, v.value, generator)
+
+provideAdapter(ConstantLoadable)
+
+ at adapter(SubOperation)
+class SubOpLoadable(LoadableAdapter):
+    def load(self, generator):
+        render_sub_op(self.value, generator.db, generator)
+
+provideAdapter(SubOpLoadable)
+
+class PyPyCodeGenerator(codegen.CodeGenerator, Generator):
+    def __init__(self, db, abc, optimize=False):
+        super(PyPyCodeGenerator, self).__init__(abc, optimize=optimize)
+        self.db  = db
+        self.cts = db.genoo.TypeSystem(db)
+
+    def _get_type(self, TYPE):
+        t = self.cts.lltype_to_cts(TYPE)
+        if t:
+            return IMultiname(t)
+        return super(PyPyCodeGenerator, self)._get_type(TYPE)
+
+    def oonewarray(self, TYPE, length=1):
+        super(PyPyCodeGenerator, self).new_vector(TYPE.ITEM, length)
+
+    def store(self, v):
+        """
+        Pop a value off the stack and store it in the variable.
+        """
+        self.store_var(v.name)
+
+    def push_local(self, v):
+        """
+        Get the local occupied to "name" and push it to the stack.
+        """
+        if self.HL(v.name):
+            self.push_var(v.name)
+        else:
+            self.push_null()
+
+    def push_primitive_constant(self, TYPE, value):
+        if TYPE is ootype.Void:
+            self.push_null()
+        elif TYPE is ootype.String:
+            if value._str is None:
+                self.push_null()
+                self.downcast(types.types.string)
+            else:
+                self.load(value._str)
+        else:
+            self.load(value)
+
+    def call_graph(self, graph, args=[]):
+        """
+        Call a graph.
+        """
+        self.db.pending_function(graph)
+        qname = self.cts.graph_to_qname(graph)
+        self.emit('findpropstrict', qname)
+        args = [a for a in args if a.concretetype is not ootype.Void]
+        self.load(*args)
+        self.emit('callproperty', qname, len(args))
+
+    def new(self, TYPE):
+        # XXX: assume no args for now
+        self.load(self._get_type(TYPE))
+        self.I(instructions.construct(0))
+
+    def stringbuilder_ll_append(self, args):
+        self.load(*args)
+        self.I(instructions.add())
+        self.store(args[0])
+        self.push_null()
+
+    stringbuilder_ll_append_char = stringbuilder_ll_append
+
+    def list_ll_setitem_fast(self, args):
+        list, index, value = args
+        self.load(list)
+        if isinstance(index, Constant):
+            self.load(value)
+            self.set_field(index.value)
+        else:
+            self.load(index)
+            self.load(value)
+            self.set_field(MultinameL())
+        # XXX: oosend expects a value to send to StoreResult
+        # We don't generate one, push a null.
+        self.push_null()
+
+    def list_ll_getitem_fast(self, args):
+        list, index = args
+        self.load(list)
+        if isinstance(index, Constant):
+            self.get_field(index.value, list.concretetype.ITEM)
+        else:
+            self.load(index)
+            self.get_field(MultinameL(), list.concretetype.ITEM)

Added: pypy/branch/avm/pypy/translator/avm2/node.py
==============================================================================
--- (empty file)
+++ pypy/branch/avm/pypy/translator/avm2/node.py	Tue Jul 27 00:14:11 2010
@@ -0,0 +1,57 @@
+
+from pypy.translator.avm2 import types_ as types
+
+from mech.fusion.avm2.traits import AbcSlotTrait
+from mech.fusion.avm2.constants import packagedQName
+from mech.fusion.avm2.interfaces import IMultiname
+
+from zope.interface import implementer
+from zope.component import adapter, provideAdapter
+
+class Node(object):
+    def get_name(self):
+        pass
+
+    def dependencies(self):
+        pass
+
+    def render(self, ilasm):
+        pass
+
+class ClassNodeBase(Node):
+    def get_fields(self):
+        pass
+
+    def get_base_class(self):
+        pass
+
+    def render(self, ilasm):
+        ilasm.begin_class(IMultiname(self), self.get_base_class())
+        for f_name, (f_type, f_default) in self.get_fields():
+            cts_type = self.cts.lltype_to_cts(f_type)
+            f_name = self.cts.escape_name(f_name)
+            if cts_type != types.types.void:
+                slot = AbcSlotTrait(IMultiname(f_name), IMultiname(cts_type))
+                ilasm.context.add_instance_trait(slot)
+
+        self.render_ctor(ilasm)
+        self.render_toString(ilasm)
+        self.render_methods(ilasm)
+        ilasm.exit_context()
+
+    def render_ctor(self, ilasm):
+        pass
+
+    def render_toString(self, ilasm):
+        pass
+
+    def render_methods(self, ilasm):
+        pass
+
+
+ at implementer(IMultiname)
+ at adapter(ClassNodeBase)
+def _adapter(self):
+    return IMultiname(self.get_type())
+
+provideAdapter(_adapter)

Added: pypy/branch/avm/pypy/translator/avm2/playerglobal.py
==============================================================================
--- (empty file)
+++ pypy/branch/avm/pypy/translator/avm2/playerglobal.py	Tue Jul 27 00:14:11 2010
@@ -0,0 +1,4 @@
+import sys
+from pypy.translator.avm2.library import get_playerglobal
+playerglobal = get_playerglobal()
+sys.modules[__name__] = playerglobal

Added: pypy/branch/avm/pypy/translator/avm2/rlib.py
==============================================================================
--- (empty file)
+++ pypy/branch/avm/pypy/translator/avm2/rlib.py	Tue Jul 27 00:14:11 2010
@@ -0,0 +1,139 @@
+
+import inspect
+import re
+
+from mech.fusion.avm2.codegen import Argument
+from mech.fusion.avm2 import constants
+
+from pypy.rpython.ootypesystem import ootype
+from pypy.objspace.flow import model as flowmodel
+from pypy.translator.avm2.node import Node
+from pypy.translator.avm2 import types_ as types
+
+from types import MethodType
+
+ESCAPE_FOR_REGEX = re.compile(r"([{}\(\)\^$&.\*\?\/\+\|\[\\\\]|\]|\-)")
+
+class FunctionNode(Node):
+    INSTANCE = None
+    def render(self, generator):
+        generator.begin_method(self.name, self.argspec, self.rettype)
+        self.fn(self.cls, generator, *[Argument(name) for t, name in self.argspec])
+        if self.rettype != constants.QName("void"):
+            generator.return_value()
+        generator.end_method()
+
+def make_node(cls, fn, name, argtypes, rettype):
+    if getattr(fn, "node", None):
+        return fn.node
+    fn.node = node = FunctionNode()
+    node.cls = cls
+    node.fn = fn
+    node.name = name
+    node.argspec = zip(argtypes, inspect.getargspec(fn).args[2:])
+    node.rettype = rettype
+    return node
+
+def export(argtypes, rettype):
+    def inner(fn):
+        def inner_(cls, asm, *args):
+            name = constants.packagedQName(cls.PACKAGE, fn.func_name)
+            asm.db.pending_node(make_node(cls, fn, name, argtypes, rettype))
+            asm.emit('findpropstrict', name)
+            asm.load(*args)
+            asm.emit('callproperty', name, len(args))
+        return classmethod(inner_)
+    return inner
+
+class RString(object):
+    WRAPPING = ootype.AbstractString
+    PACKAGE  = "pypy.lib.str"
+
+    @export(['String', 'String', 'int', 'int'], 'int')
+    def ll_find(cls, asm, string, substr, start, end):
+        asm.load(start, string)
+        asm.get_field("length")
+        asm.branch_if_greater_than("return -1")
+        asm.load(string, 0, end)
+        asm.call_method("slice", 2)
+        asm.load(substr, start)
+        asm.call_method("indexOf", 2)
+        asm.return_value()
+        asm.set_label("return -1")
+        asm.load(-1)
+
+    ll_find_char = ll_find
+
+    @export(['String', 'String', 'int', 'int'], 'int')
+    def ll_rfind(cls, asm, string, substr, start, end):
+        asm.load(start, string)
+        asm.get_field("length")
+        asm.branch_if_greater_than("return -1")
+        asm.load(string, start, end)
+        asm.call_method("slice", 2)
+        asm.load(substr)
+        asm.call_method("lastIndexOf", 1)
+        asm.dup()
+        asm.load(-1)
+        asm.branch_if_not_equal("return value")
+        asm.pop()
+        asm.set_label("return -1")
+        asm.load(-1)
+        asm.return_value()
+        asm.set_label("return value")
+        asm.load(start)
+        asm.emit('add_i')
+        asm.return_value()
+
+    ll_rfind_char = ll_rfind
+
+    @classmethod
+    def escape_for_regex(cls, asm, string):
+        if isinstance(string, flowmodel.Constant):
+            asm.load(ESCAPE_FOR_REGEX.sub(r"\\\1", string.value))
+        else:
+            asm.emit('findpropstrict', constants.QName("RegExp"))
+            asm.load(string, ESCAPE_FOR_REGEX.pattern, "g")
+            asm.emit('constructprop', constants.QName("RegExp"), 2)
+            asm.load(r"\$1")
+            asm.call_method("replace", 2)
+
+    @export(['String', 'String', 'int', 'int'], 'int')
+    def ll_count(cls, asm, string, substr, start, end):
+        asm.emit('findpropstrict', constants.QName("RegExp"))
+        cls.escape_for_regex(substr)
+        asm.load("g")
+        asm.emit('constructprop', constants.QName("RegExp"), 2)
+        asm.load(string, start, end)
+        asm.call_method("slice", 2)
+        asm.call_method("exec", 1)
+        asm.get_field("length")
+
+    ll_count_char = ll_count
+
+    @export(['String', 'String'], 'Boolean')
+    def ll_endswith(cls, asm, string, substr):
+        asm.load(substr, string, substr, substr)
+        asm.branch_if_false("rettrue")
+        asm.get_field("length")
+        asm.emit('negate_i')
+        asm.call_method("slice", 1)
+        asm.emit('equals')
+        asm.return_value()
+        asm.set_label("rettrue")
+        asm.load(True)
+
+    @export(['String', 'String'], 'Boolean')
+    def ll_startswith(cls, asm, string, substr):
+        asm.load(substr, string, 0, substr)
+        asm.get_field("length")
+        asm.call_method("slice", 2)
+        asm.emit('equals')
+
+RLib = {}
+
+for cls in [RString]:
+    for name in dir(cls):
+        meth = getattr(cls, name)
+        if isinstance(meth, MethodType):
+            RLib[cls.WRAPPING.oopspec_name+'_'+name] = meth



More information about the Pypy-commit mailing list