[pypy-svn] r76309 - in pypy/branch/avm/pypy/translator: avm1/test avm2 avm2/intrinsic avm2/test
magcius at codespeak.net
magcius at codespeak.net
Thu Jul 22 02:36:41 CEST 2010
Author: magcius
Date: Thu Jul 22 02:36:39 2010
New Revision: 76309
Removed:
pypy/branch/avm/pypy/translator/avm2/intrinsic/
Modified:
pypy/branch/avm/pypy/translator/avm1/test/harness.py
pypy/branch/avm/pypy/translator/avm2/__init__.py
pypy/branch/avm/pypy/translator/avm2/class_.py
pypy/branch/avm/pypy/translator/avm2/conftest.py
pypy/branch/avm/pypy/translator/avm2/constant.py
pypy/branch/avm/pypy/translator/avm2/database.py
pypy/branch/avm/pypy/translator/avm2/entrypoint.py
pypy/branch/avm/pypy/translator/avm2/function.py
pypy/branch/avm/pypy/translator/avm2/genavm.py
pypy/branch/avm/pypy/translator/avm2/library.py
pypy/branch/avm/pypy/translator/avm2/metavm.py
pypy/branch/avm/pypy/translator/avm2/opcodes.py
pypy/branch/avm/pypy/translator/avm2/record.py
pypy/branch/avm/pypy/translator/avm2/runtime.py
pypy/branch/avm/pypy/translator/avm2/test/browsertest.py
pypy/branch/avm/pypy/translator/avm2/test/entrypoint.py
pypy/branch/avm/pypy/translator/avm2/test/runtest.py
pypy/branch/avm/pypy/translator/avm2/test/test_int.py
pypy/branch/avm/pypy/translator/avm2/test/test_string.py
pypy/branch/avm/pypy/translator/avm2/types_.py
Log:
Fix a lot more testcases
Modified: pypy/branch/avm/pypy/translator/avm1/test/harness.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm1/test/harness.py (original)
+++ pypy/branch/avm/pypy/translator/avm1/test/harness.py Thu Jul 22 02:36:39 2010
@@ -1,20 +1,23 @@
-from pypy.translator.avm1.test import browsertest as b
-from mech.fusion.swf import swfdata as s, tags as t, records as r
-from mech.fusion import avm1 as a
+from pypy.translator.avm1.test.browsertest import browsertest
+from mech.fusion.swf.swfdata import SwfData
+from mech.fusion.swf.records import Rect, RGBA
+from mech.fusion.swf import tags
+from mech.fusion.avm1.avm1gen import AVM1Gen
+from mech.fusion.avm1.actions import ActionGetURL2
class TestHarness(object):
def __init__(self, name):
self.testname = name
- self.swf = s.SwfData()
- self.swf.add_tag(t.SetBackgroundColor(0x333333))
- self.swf.add_tag(t.DefineEditText(r.Rect(0, 0, 0, 0), "txt",
- "Testing %s." % (name,), color=r.RGBA(0xFFFFFF)))
- self.swf.add_tag(t.PlaceObject2(1, 2))
- self.actions = g.AVM1Gen(t.DoAction())
+ self.swf = SwfData()
+ self.swf.add_tag(tags.SetBackgroundColor(0x333333))
+ self.swf.add_tag(tags.DefineEditText(Rect(0, 0, 0, 0), "txt",
+ "Testing %s." % (name,), color=RGBA(0xFFFFFF)))
+ self.swf.add_tag(tags.PlaceObject2(1, 1))
+ self.actions = AVM1Gen(tags.DoAction())
self.swf.add_tag(self.actions.block)
- self.swf.add_tag(t.ShowFrame())
- self.swf.add_tag(t.End())
+ self.swf.add_tag(tags.ShowFrame())
+ self.swf.add_tag(tags.End())
self.start_test()
def print_text(self, text):
@@ -54,9 +57,9 @@
self.actions.set_variable()
self.print_var("Got: ", "result")
self.actions.push_const("/test.result", "") # URL, target
- self.actions.action(a.ActionGetURL2("POST", True, True))
+ self.actions.action(ActionGetURL2("POST", True, True))
self.actions.push_const("javascript:window.close()", "") # Close the window.
- self.actions.action(a.ActionGetURL2(""))
+ self.actions.action(ActionGetURL2(""))
def do_test(self, debug=False):
self.finish_test()
@@ -65,4 +68,4 @@
f = open("test.swf", "w")
f.write(self.swf.serialize())
f.close()
- return b.browsertest(self.testname, self.swf)
+ return browsertest(self.testname, self.swf)
Modified: pypy/branch/avm/pypy/translator/avm2/__init__.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/__init__.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/__init__.py Thu Jul 22 02:36:39 2010
@@ -1 +0,0 @@
-
Modified: pypy/branch/avm/pypy/translator/avm2/class_.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/class_.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/class_.py Thu Jul 22 02:36:39 2010
@@ -1,56 +1,63 @@
+
+from py.builtin import set
+
from pypy.rpython.ootypesystem import ootype
-from pypy.translator.cli.node import Node
+from pypy.translator.avm2.node import ClassNodeBase
+from pypy.translator.avm2.types_ import types
from pypy.translator.oosupport.constant import push_constant
-from mech.fusion.avm2 import constants, traits
-from pypy.translator.avm2 import types_ as types
-
-try:
- set
-except NameError:
- from sets import Set as set
+from mech.fusion.avm2.constants import QName, packagedQName
+from mech.fusion.avm2.interfaces import IMultiname
-class Class(Node):
+class Class(ClassNodeBase):
def __init__(self, db, INSTANCE, namespace, name):
self.db = db
self.cts = db.genoo.TypeSystem(db)
self.INSTANCE = INSTANCE
+ print INSTANCE, INSTANCE._superclass
self.exception = ootype.isSubclass(self.INSTANCE, self.db.genoo.EXCEPTION)
self.namespace = namespace
self.name = name
- def dependencies(self):
- if not self.is_root(self.INSTANCE):
- self.db.pending_class(self.INSTANCE._superclass)
-
def __hash__(self):
return hash(self.INSTANCE)
def __eq__(self, other):
- return self.INSTANCE == other.INSTANCE
+ return isinstance(other, type(self)) and self.INSTANCE == other.INSTANCE
def __ne__(self, other):
return not self == other
- def is_root(INSTANCE):
- return INSTANCE._superclass is None
- is_root = staticmethod(is_root)
+ def __repr__(self):
+ return '<Class %s>' % self.name
+
+ def dependencies(self):
+ if self.INSTANCE._superclass._superclass:
+ self.db.pending_class(self.INSTANCE._superclass)
+
+ def get_fields(self):
+ return self.INSTANCE._fields.iteritems()
def get_name(self):
return self.name
- def __repr__(self):
- return '<Class %s>' % self.name
+ def get_full_name(self):
+ if self.namespace is None:
+ return self.name
+ else:
+ return '%s::%s' % (self.namespace, self.name)
+
+ def get_type(self):
+ return packagedQName(self.namespace, self.name)
def get_base_class(self):
base_class = self.INSTANCE._superclass
if self.INSTANCE is self.db.genoo.EXCEPTION:
- return constants.QName("Error")
- if self.is_root(base_class):
- return constants.QName("Object")
- else:
+ return QName("Error")
+ elif self.INSTANCE._superclass._superclass:
ns, name = self.db.class_name(base_class).rsplit('::', 1)
- return constants.packagedQName(ns, name)
+ return packagedQName(ns, name)
+ return QName("Object")
def is_abstract(self):
return False # XXX
@@ -75,22 +82,25 @@
return False
- def render(self, ilasm):
- if self.is_root(self.INSTANCE):
- return
-
- self.ilasm = ilasm
-
- ilasm.begin_class(constants.packagedQName(self.namespace, self.name), self.get_base_class())
- for f_name, (f_type, f_default) in self.INSTANCE._fields.iteritems():
- cts_type = self.cts.lltype_to_cts(f_type)
+ def render_ctor(self, ilasm):
+ ilasm.begin_constructor()
+ # set default values for fields
+ default_values = self.INSTANCE._fields.copy()
+ default_values.update(self.INSTANCE._overridden_defaults)
+ for f_name, (F_TYPE, f_default) in default_values.iteritems():
+ if getattr(F_TYPE, '_is_value_type', False):
+ continue # we can't set it to null
+ # INSTANCE_DEF, _ = self.INSTANCE._lookup_field(f_name)
+ cts_type = self.cts.lltype_to_cts(F_TYPE)
f_name = self.cts.escape_name(f_name)
- if cts_type != types.types.void:
- ilasm.context.add_instance_trait(traits.AbcSlotTrait(constants.QName(f_name), cts_type.multiname()))
-
- self._ctor()
- self._toString()
+ if cts_type != types.void:
+ ilasm.push_this()
+ push_constant(self.db, F_TYPE, f_default, ilasm)
+ # class_name = self.db.class_name(INSTANCE_DEF)
+ ilasm.set_field(f_name)
+ ilasm.end_constructor()
+ def render_methods(self, ilasm):
for m_name, m_meth in self.INSTANCE._methods.iteritems():
if hasattr(m_meth, 'graph'):
# if the first argument's type is not a supertype of
@@ -119,40 +129,25 @@
if ARG is not ootype.Void]
returntype = self.cts.lltype_to_cts(METH.RESULT)
ilasm.begin_method(m_name, arglist, returntype)
- ilasm.emit('findpropstrict', constants.QName("Error"))
- ilasm.push_const("Abstract method %s::%s called" % (self.name, m_name))
- ilasm.emit('constructprop', constants.QName("Error"), 1)
+ ilasm.emit('findpropstrict', QName("Error"))
+ ilasm.load("Abstract method %s::%s called" % (self.name, m_name))
+ ilasm.emit('constructprop', QName("Error"), 1)
ilasm.throw()
ilasm.exit_context()
- ilasm.exit_context()
-
- def _ctor(self):
- self.ilasm.begin_constructor()
- # set default values for fields
- default_values = self.INSTANCE._fields.copy()
- default_values.update(self.INSTANCE._overridden_defaults)
- for f_name, (F_TYPE, f_default) in default_values.iteritems():
- if getattr(F_TYPE, '_is_value_type', False):
- continue # we can't set it to null
- # INSTANCE_DEF, _ = self.INSTANCE._lookup_field(f_name)
- cts_type = self.cts.lltype_to_cts(F_TYPE)
- f_name = self.cts.escape_name(f_name)
- if cts_type != types.types.void:
- self.ilasm.push_this()
- push_constant(self.db, F_TYPE, f_default, self.gen)
- # class_name = self.db.class_name(INSTANCE_DEF)
- self.ilasm.set_field(f_name)
- self.ilasm.end_constructor()
+ self.render_getName(ilasm)
- def _toString(self):
- if self.is_root(self.INSTANCE._superclass):
- override = False
- else:
- override = True
- print self.exception
+ def render_toString(self, ilasm):
+ override = self.INSTANCE._superclass._superclass is not None
wrapper = "Exception" if self.exception else "Instance"
- self.ilasm.begin_method('toString', [], types.types.string, override=override)
- self.ilasm.load("%sWrapper('%s')" % (wrapper, self.name))
- self.ilasm.return_value()
- self.ilasm.end_method()
+ ilasm.begin_method('toString', [], types.string, override=override)
+ ilasm.load("%sWrapper('%s')" % (wrapper, self.name))
+ ilasm.return_value()
+ ilasm.end_method()
+
+ def render_getName(self, ilasm):
+ override = self.INSTANCE._superclass._superclass is not None
+ ilasm.begin_method('getName', [], types.string, override=override)
+ ilasm.load(self.name)
+ ilasm.return_value()
+ ilasm.end_method()
Modified: pypy/branch/avm/pypy/translator/avm2/conftest.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/conftest.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/conftest.py Thu Jul 22 02:36:39 2010
@@ -1,8 +1,8 @@
def pytest_addoption(parser):
group = parser.getgroup("pypy-tamarin options")
- group.addoption('--swf', action="store_const", const="swf", dest="tamtarget", default="swf",
+ group.addoption('--swf', action="store_true", dest="browsertest", default=False,
help="generate a .swf and .abc and use a browsertest and Flash Player to run")
- group.addoption('--tamarin', action="store_const", const="tamarin", dest="tamtarget",
+ group.addoption('--tamarin', action="store", dest="tamexec", default="avmshell",
help="generate an abc that uses Tamarin")
group.addoption('--no-mf-optimize', action="store_false", default=True, dest="mf_optim",
help="don't do simple MF optimizations")
Modified: pypy/branch/avm/pypy/translator/avm2/constant.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/constant.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/constant.py Thu Jul 22 02:36:39 2010
@@ -7,9 +7,14 @@
from pypy.translator.avm2 import types_ as types
from pypy.rpython.lltypesystem import lltype
-from mech.fusion.avm2 import constants, traits
+from mech.fusion.avm2.traits import AbcConstTrait
+from mech.fusion.avm2.constants import QName, packagedQName
+from mech.fusion.avm2.interfaces import IMultiname
-CONST_CLASS = constants.packagedQName("pypy.runtime", "Constants")
+from zope.interface import implementer
+from zope.component import adapter, provideAdapter
+
+CONST_CLASS = packagedQName("pypy.runtime", "Constants")
# ______________________________________________________________________
# Constant Generators
@@ -41,11 +46,11 @@
self.ilasm.exit_context()
def _declare_const(self, gen, const):
- self.ctx.add_static_trait(traits.AbcConstTrait(constants.QName(const.name), const.get_type().multiname()))
+ self.ctx.add_static_trait(AbcConstTrait(IMultiname(const.name), IMultiname(const)))
def downcast_constant(self, gen, const, EXPECTED_TYPE):
type = self.cts.lltype_to_cts(EXPECTED_TYPE)
- gen.emit('coerce', type.multiname())
+ gen.emit('coerce', IMultiname(type))
def _get_key_for_const(self, value):
if isinstance(value, ootype._view) and isinstance(value._inst, ootype._record):
@@ -54,22 +59,23 @@
def push_constant(self, gen, const):
gen.emit('getlex', CONST_CLASS)
- gen.emit('getproperty', constants.QName(const.name))
+ gen.emit('getproperty', IMultiname(const.name))
def _push_constant_during_init(self, gen, const):
gen.push_this()
- gen.emit('getproperty', constants.QName(const.name))
+ gen.emit('getproperty', IMultiname(const.name))
def _pre_store_constant(self, gen, const):
gen.push_this()
def _store_constant(self, gen, const):
- gen.emit('initproperty', constants.QName(const.name))
+ gen.emit('initproperty', IMultiname(const.name))
def _initialize_data(self, gen, all_constants):
""" Iterates through each constant, initializing its data. """
for const in all_constants:
- self._consider_step(gen)
+ if const._do_not_initialize():
+ continue
self._push_constant_during_init(gen, const)
self.current_const = const
if not const.initialize_data(self, gen):
@@ -113,6 +119,13 @@
assert self.is_null()
gen.ilasm.push_null()
+ at adapter(Avm2BaseConstMixin)
+ at implementer(IMultiname)
+def _adapter(self):
+ return IMultiname(self.get_type())
+
+provideAdapter(_adapter)
+
# class Avm2DictMixin(Avm2BaseConstMixin):
# def _check_for_void_dict(self, gen):
# KEYTYPE = self.value._TYPE._KEYTYPE
@@ -153,9 +166,8 @@
# the generator interface in Tamarin.
class Avm2RecordConst(Avm2BaseConstMixin, RecordConst):
- def create_pointer(self, gen):
- self.db.const_count.inc('Record')
- super(Avm2RecordConst, self).create_pointer(gen)
+ def _do_not_initialize(self):
+ return False
def initialize_data(self, constgen, gen):
assert not self.is_null()
@@ -168,10 +180,8 @@
gen.set_field(f_name)
class Avm2InstanceConst(Avm2BaseConstMixin, InstanceConst):
- def create_pointer(self, gen):
- self.db.const_count.inc('Instance')
- self.db.const_count.inc('Instance', self.OOTYPE())
- super(Avm2InstanceConst, self).create_pointer(gen)
+ def _do_not_initialize(self):
+ return not self.value._TYPE._fields
def initialize_data(self, constgen, gen):
assert not self.is_null()
@@ -198,49 +208,52 @@
def is_inline(self):
return True
+ def _do_not_initialize(self):
+ return True
+
def push_inline(self, gen, EXPECTED_TYPE):
if not self.is_null():
- if hasattr(self.value, '_FUNC'):
- FUNC = self.value._FUNC
- classname = self.db.record_delegate(FUNC)
- else:
- INSTANCE = self.value._INSTANCE
- classname = self.db.class_name(INSTANCE)
- ns, name = classname.rsplit('::', 1)
- gen.emit('getlex', constants.packagedQName(ns, name))
- return
- super(Avm2ClassConst, self).push_inline(gen, EXPECTED_TYPE)
+ INSTANCE = self.value._INSTANCE
+ classname = self.cts.instance_to_qname(INSTANCE)
+ return gen.load(classname)
+class Avm2ArrayListConst(Avm2BaseConstMixin):
+ def get_value(self):
+ pass
-class Avm2ArrayListConst(Avm2BaseConstMixin, ListConst):
+ def get_length(self):
+ return len(self.get_value())
def _do_not_initialize(self):
# Check if it is a list of all zeroes:
try:
- if self.value._list == [0] * len(self.value._list):
- return True
+ return self.get_value() == [0] * self.get_length()
except:
- pass
- return super(Avm2ListConst, self)._do_not_initialize()
-
+ return False
+
def create_pointer(self, gen):
- llen = len(self.value._list)
- self.db.const_count.inc('List')
- self.db.const_count.inc('List', self.value._TYPE.ITEM)
- self.db.const_count.inc('List', llen)
- gen.oonewarray(self.value._TYPE, llen)
+ gen.oonewarray(self.value._TYPE, self.get_length())
def initialize_data(self, constgen, gen):
assert not self.is_null()
-
+ ITEM = self.value._TYPE.ITEM
+
# check for special cases and avoid initialization
if self._do_not_initialize():
return
-
- for idx, item in enumerate(self.value._array):
+
+ for idx, item in enumerate(self.get_value()):
gen.dup()
- gen.emit('setproperty', constants.Multiname(
- str(idx), constants.PROP_NAMESPACE_SET))
+ push_constant(self.db, ITEM, item, gen)
+ gen.set_field(idx)
+
+class Avm2ListConst (Avm2ArrayListConst, ListConst):
+ def get_value(self):
+ return self.value._list
+
+class Avm2ArrayConst(Avm2ArrayListConst, ArrayConst):
+ def get_value(self):
+ return self.value._array
# class CLIDictConst(CLIDictMixin, DictConst):
# def create_pointer(self, gen):
Modified: pypy/branch/avm/pypy/translator/avm2/database.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/database.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/database.py Thu Jul 22 02:36:39 2010
@@ -1,7 +1,6 @@
import string
-#from pypy.translator.avm.class_ import Class
from pypy.rpython.ootypesystem import ootype
-from pypy.translator.avm2 import runtime, types_ as types, class_ as c, record
+from pypy.translator.avm2 import types_ as types, class_ as c, record
from pypy.translator.oosupport.database import Database as OODatabase
try:
@@ -30,7 +29,7 @@
def __init__(self, genoo):
OODatabase.__init__(self, genoo)
self._pending_nodes = []
- self.classes = {} # INSTANCE --> class_name
+ self.classes = {} # INSTANCE --> class nodes
self.classnames = set() # (namespace, name)
self.functions = {} # graph --> function_name
self.methods = {} # graph --> method_name
@@ -82,24 +81,20 @@
def pending_class(self, INSTANCE):
try:
- return self.classes[INSTANCE]
+ return self.pending_node(self.classes[INSTANCE]).get_full_name()
except KeyError:
pass
-
- if isinstance(INSTANCE, runtime.NativeInstance):
+
+ if 0: #isinstance(INSTANCE, runtime.NativeInstance):
self.classes[INSTANCE] = INSTANCE._name
return INSTANCE._name
else:
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 = c.Class(self, INSTANCE, namespace, name)
self.pending_node(cls)
- return full_name
+ self.classes[INSTANCE] = cls
+ return cls.get_full_name()
def record_function(self, graph, name):
self.functions[graph] = name
@@ -124,23 +119,28 @@
NATIVE_INSTANCE = INSTANCE._hints['NATIVE_INSTANCE']
return NATIVE_INSTANCE._name
except KeyError:
- return self.classes[INSTANCE]
+ return self.classes[INSTANCE].get_full_name()
- def record_delegate(self, TYPE):
- try:
- return self.delegates[TYPE]
- except KeyError:
- name = 'StaticMethod__%d' % len(self.delegates)
- self.delegates[TYPE] = name
- self.pending_node(Delegate(self, TYPE, name))
- return name
-
+ ## def record_delegate(self, TYPE):
+ ## try:
+ ## return self.delegates[TYPE]
+ ## except KeyError:
+ ## name = 'StaticMethod__%d' % len(self.delegates)
+ ## self.delegates[TYPE] = name
+ ## self.pending_node(Delegate(self, TYPE, name))
+ ## return name
+
def pending_node(self, node):
""" Adds a node to the worklist, so long as it is not already there
and has not already been rendered. """
- assert not self.locked # sanity check
- if node in self._pending_nodes or node in self._rendered_nodes:
- return
+ # assert not self.locked # sanity check
+ if node in self._rendered_nodes:
+ return node
+ # sometimes a dependency will already
+ # be there, but needs to be rendered
+ # before others
+ if node in self._pending_nodes:
+ self._pending_nodes.remove(node)
self._pending_nodes.append(node)
node.dependencies()
-
+ return node
Modified: pypy/branch/avm/pypy/translator/avm2/entrypoint.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/entrypoint.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/entrypoint.py Thu Jul 22 02:36:39 2010
@@ -1,7 +1,7 @@
from pypy.translator.avm2.types_ import Avm2TypeSystem
from pypy.translator.avm2.database import LowLevelDatabase
-from pypy.translator.cli.node import Node
+from pypy.translator.avm2.node import Node
from pypy.rpython.ootypesystem import ootype
def get_entrypoint(graph):
@@ -16,7 +16,9 @@
return TestEntryPoint(graph)
class BaseEntryPoint(Node):
-
+ def create_assembler(self, gen):
+ pass
+
def set_db(self, db):
self.db = db
self.cts = Avm2TypeSystem(db)
@@ -28,28 +30,23 @@
"""
def __init__(self, graph_to_call):
- self.graph = graph_to_call
+ self._graph = graph_to_call
def get_name(self):
return 'main'
def render(self, ilasm):
try:
- ARG0 = self.graph.getargs()[0].concretetype
+ ARG0 = self._graph.getargs()[0].concretetype
except IndexError:
ARG0 = None
assert isinstance(ARG0, ootype.List) and ARG0.ITEM is ootype.String,\
'Wrong entry point signature: List(String) expected'
- qname = self.cts.graph_to_qname(self.graph)
+ qname = self.cts.graph_to_qname(self._graph)
ilasm.emit('findpropstrict', qname)
ilasm.emit('callpropvoid', qname, 0)
- ## ilasm.opcode('pop') # XXX: return this value, if it's an int32
-
- ## ilasm.call('void [pypylib]pypy.runtime.DebugPrint::close_file()')
- ## ilasm.opcode('ret')
- ## ilasm.end_function()
- self.db.pending_function(self.graph)
+ self.db.pending_function(self._graph)
class LibraryEntryPoint(BaseEntryPoint):
def __init__(self, name, graphs):
Modified: pypy/branch/avm/pypy/translator/avm2/function.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/function.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/function.py Thu Jul 22 02:36:39 2010
@@ -1,17 +1,25 @@
-from functools import partial
+from itertools import chain
+
+from py.builtin import set
from pypy.objspace.flow import model as flowmodel
from pypy.rpython.ootypesystem import ootype
from pypy.rpython.lltypesystem.lltype import Void
from pypy.translator.oosupport.function import Function as OOFunction
-from pypy.translator.cli.node import Node
+
+from pypy.translator.avm2.node import Node
from mech.fusion.avm2 import constants
-class Function(OOFunction, Node):
+class CompiledABCNode(Node):
+ def __init__(self, abc):
+ self.abc = abc
- auto_propagate_exceptions = True
+ def render(self, ilasm):
+ ilasm.abc.merge(self.abc)
+class Function(OOFunction, Node):
+ auto_propagate_exceptions = True
def __init__(self, db, graph, name=None, is_method=False, is_entrypoint=False):
OOFunction.__init__(self, db, graph, name, is_method, is_entrypoint)
@@ -58,12 +66,12 @@
self.generator.begin_method(self.name, self.args, returntype, static=not self.is_method, override=self.override)
- self.declare_locals()
+ # self.declare_locals()
def end_render(self):
+ self.generator.end_method()
if self.classname:
- self.generator.exit_context()
- self.generator.exit_context()
+ self.generator.end_class()
def render_return_block(self, block):
return_var = block.inputargs[0]
@@ -76,13 +84,39 @@
def set_label(self, label):
return self.generator.set_label(label)
- def declare_locals(self):
- for TYPE, name in set(self.locals):
- TYPE.load_default(self.generator)
- self.generator.store_var(name)
+ def get_block_locals(self, block, exits=False):
+ if not block.operations:
+ return set()
+ all_locals = set(arg.name for op in block.operations for arg in op.args if isinstance(arg, flowmodel.Variable))
+ all_locals |= set(op.result.name for op in block.operations)
+ all_locals -= set(arg.name for arg in self.graph.getargs() if isinstance(arg, flowmodel.Variable))
+ if exits:
+ all_locals -= set(arg.name for exit in block.exits
+ for arg in exit.args + exit.target.inputargs
+ if isinstance(arg, flowmodel.Variable))
+ if isinstance(block.exitswitch, flowmodel.Variable) and block.exitswitch.name in all_locals:
+ all_locals.remove(block.exitswitch.name)
+ return all_locals
+
+ def get_block_links_args(self, link):
+ return set(arg.name for exit in link.prevblock.exits for arg in exit.args if arg not in link.args if isinstance(arg, flowmodel.Variable))
+
+ def end_block(self, block):
+ L = self.get_block_locals(block, True)
+ for var in self.get_block_locals(block, True):
+ if self.generator.HL(var):
+ self.generator.KL(var)
+
+ def __eq__(self, other):
+ return type(self) == type(other) and self.graph == other.graph
+
+ ## def declare_locals(self):
+ ## for TYPE, name in set(self.locals):
+ ## TYPE.load_default(self.generator)
+ ## self.generator.store_var(name)
def _trace_enabled(self):
- return True
+ return False
def _trace(self, s, writeline=False):
print "TRACE:", s
@@ -94,33 +128,36 @@
print "Rendering op:", op
super(Function, self)._render_op(op)
- ## def _setup_link(self, link):
- ## target = link.target
- ## linkvars = []
- ## for to_load, to_store in zip(link.args, target.inputargs):
- ## if isinstance(to_load, flowmodel.Variable) and to_load.name == to_store.name:
- ## continue
- ## if to_load.concretetype is ootype.Void:
- ## continue
- ## linkvars.append((to_load, to_store))
-
- ## # after SSI_to_SSA it can happen to have to_load = [a, b] and
- ## # to_store = [b, c]. If we store each variable sequentially,
- ## # 'b' would be overwritten before being read. To solve, we
- ## # first load all the values on the stack, then store in the
- ## # appropriate places.
-
- ## if self._trace_enabled():
- ## self._trace('link', writeline=True)
- ## for to_load, to_store in linkvars:
- ## self._trace_value('%s <-- %s' % (to_store, to_load), to_load)
- ## self._trace('', writeline=True)
+ def _setup_link(self, link):
+ target = link.target
+ linkvars = []
+ locals = self.get_block_locals(link.prevblock) | self.get_block_links_args(link)
+ for to_load, to_store in zip(link.args, target.inputargs):
+ if isinstance(to_load, flowmodel.Variable) and to_load.name == to_store.name:
+ continue
+ if to_load.concretetype is ootype.Void:
+ continue
+ linkvars.append((to_load, to_store))
+
+ # after SSI_to_SSA it can happen to have to_load = [a, b] and
+ # to_store = [b, c]. If we store each variable sequentially,
+ # 'b' would be overwritten before being read. To solve, we
+ # first load all the values on the stack, then store in the
+ # appropriate places.
+
+ if self._trace_enabled():
+ self._trace('link', writeline=True)
+ for to_load, to_store in linkvars:
+ self._trace_value('%s <-- %s' % (to_store, to_load), to_load)
+ self._trace('', writeline=True)
+
+ for to_load, to_store in linkvars:
+ self.generator.load(to_load)
+ if isinstance(to_load, flowmodel.Variable) and to_load.name in locals:
+ self.generator.KL(to_load.name)
- ## for to_load, to_store in linkvars:
- ## self.generator.load(to_load)
-
- ## for to_load, to_store in reversed(linkvars):
- ## self.generator.store(to_store)
+ for to_load, to_store in reversed(linkvars):
+ self.generator.store(to_store)
def begin_try(self, cond):
if cond:
@@ -134,7 +171,7 @@
def begin_catch(self, llexitcase):
ll_meta_exc = llexitcase
ll_exc = ll_meta_exc._INSTANCE
- self.ilasm.begin_catch(ll_exc)
+ self.ilasm.begin_catch(self.cts.instance_to_qname(ll_exc))
def end_catch(self, target_label):
self.ilasm.end_catch()
@@ -150,20 +187,67 @@
# the exception value is on the stack, use it as the 2nd target arg
assert len(link.args) == 2
assert len(link.target.inputargs) == 2
- self.store(link.target.inputargs[1])
+ self.generator.store(link.target.inputargs[1])
else:
# the exception value is on the stack, store it in the proper place
if isinstance(link.last_exception, flowmodel.Variable):
- self.ilasm.opcode('dup')
- self.store(link.last_exc_value)
- self.ilasm.emit('convert_o')
- self.ilasm.get_field('prototype')
- self.ilasm.get_field('constructor')
- self.store(link.last_exception)
+ self.generator.emit('dup')
+ self.generator.store(link.last_exc_value)
+ self.generator.emit('convert_o')
+ self.generator.get_field('prototype')
+ self.generator.get_field('constructor')
+ self.generator.store(link.last_exception)
else:
- self.store(link.last_exc_value)
+ self.generator.store(link.last_exc_value)
self._setup_link(link)
+ def render_normal_block(self, block):
+ for op in block.operations:
+ self._render_op(op)
+
+ self.end_block(block)
+
+ if block.exitswitch is None:
+ assert len(block.exits) == 1
+ link = block.exits[0]
+ target_label = self._get_block_name(link.target)
+ self._setup_link(link)
+ self.generator.branch_unconditionally(target_label)
+ elif block.exitswitch.concretetype is ootype.Bool:
+ self.render_bool_switch(block)
+ elif block.exitswitch.concretetype in (ootype.Signed, ootype.SignedLongLong,
+ ootype.Unsigned, ootype.UnsignedLongLong,
+ ootype.Char, ootype.UniChar):
+ self.render_numeric_switch(block)
+ else:
+ assert False, 'Unknonw exitswitch type: %s' % block.exitswitch.concretetype
+
+ def render_bool_switch(self, block):
+ assert len(block.exits) == 2
+ for link in block.exits:
+ if link.exitcase:
+ link_true = link
+ else:
+ link_false = link
+
+ true_label = self.next_label('link_true')
+ self.generator.load(block.exitswitch)
+ self.generator.KL(block.exitswitch.name, True)
+ self.generator.branch_conditionally(True, true_label)
+ self._follow_link(link_false) # if here, the exitswitch is false
+ self.set_label(true_label)
+ self._follow_link(link_true) # if here, the exitswitch is true
+
+ def _follow_link(self, link):
+ target_label = self._get_block_name(link.target)
+ allowed = self.get_block_locals(link.prevblock) | self.get_block_links_args(link)
+ for arg in chain(*(exit.args for exit in link.prevblock.exits)):
+ if isinstance(arg, flowmodel.Variable) and arg.name in allowed and arg not in link.args and self.generator.HL(arg.name):
+ self.generator.KL(arg.name)
+ self._setup_link(link)
+ self.generator.branch_unconditionally(target_label)
+
+
# def render_numeric_switch(self, block):
# if block.exitswitch.concretetype in (ootype.SignedLongLong, ootype.UnsignedLongLong):
# # TODO: it could be faster to check is the values fit in
@@ -189,16 +273,5 @@
# for link, lbl in cases.itervalues():
# self.render_switch_case(link, lbl)
- # def call_oostring(self, ARGTYPE):
- # if isinstance(ARGTYPE, ootype.Instance):
- # argtype = self.cts.types.object
- # else:
- # argtype = self.cts.lltype_to_cts(ARGTYPE)
- # self.call_signature('string [pypylib]pypy.runtime.Utils::OOString(%s, int32)' % argtype)
-
- # def call_oounicode(self, ARGTYPE):
- # argtype = self.cts.lltype_to_cts(ARGTYPE)
- # self.call_signature('string [pypylib]pypy.runtime.Utils::OOUnicode(%s)' % argtype)
-
# Those parts of the generator interface that are function
# specific
Modified: pypy/branch/avm/pypy/translator/avm2/genavm.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/genavm.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/genavm.py Thu Jul 22 02:36:39 2010
@@ -1,18 +1,20 @@
import py
from mech.fusion.avm2.abc_ import AbcFile
+from pypy.conftest import option
from pypy.translator.oosupport.genoo import GenOO
-from pypy.translator.avm2.avm2gen import PyPyAvm2ilasm
-from pypy.translator.avm2.constant import Avm2ConstGenerator, Avm2ClassConst, Avm2InstanceConst, Avm2RecordConst, Avm2ArrayListConst
+from pypy.translator.avm2.codegen import PyPyCodeGenerator
+from pypy.translator.avm2.constant import (Avm2ConstGenerator, Avm2ClassConst,
+ Avm2InstanceConst, Avm2RecordConst, Avm2ListConst, Avm2ArrayConst)
from pypy.translator.avm2.database import LowLevelDatabase
-from pypy.translator.avm2.function import Function as TamarinFunction
+from pypy.translator.avm2.function import Function
from pypy.translator.avm2.opcodes import opcodes
from pypy.translator.avm2.types_ import Avm2TypeSystem
class GenAVM2(GenOO):
opcodes = opcodes
- Function = TamarinFunction
+ Function = Function
Database = LowLevelDatabase
TypeSystem = Avm2TypeSystem
@@ -21,14 +23,16 @@
ClassConst = Avm2ClassConst
InstanceConst = Avm2InstanceConst
RecordConst = Avm2RecordConst
- ListConst = Avm2ArrayListConst
- ArrayConst = Avm2ArrayListConst
+ ListConst = Avm2ListConst
+ ArrayConst = Avm2ArrayConst
def __init__(self, tmpdir, translator, entrypoint, config=None, exctrans=False):
GenOO.__init__(self, tmpdir, translator, entrypoint, config, exctrans)
self.const_stat = str(tmpdir.join('const_stat'))
self.ilasm = None
self.abc = None
+
+ # Get the base exception type for conversion.
rtyper = translator.rtyper
bk = rtyper.annotator.bookkeeper
clsdef = bk.getuniqueclassdef(Exception)
@@ -37,7 +41,7 @@
def create_assembler(self):
self.abc = AbcFile()
- return PyPyAvm2ilasm(self.db, self.abc, True)
+ return PyPyCodeGenerator(self.db, self.abc, option.mf_optim)
def generate_source(self):
if self.ilasm is None:
Modified: pypy/branch/avm/pypy/translator/avm2/library.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/library.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/library.py Thu Jul 22 02:36:39 2010
@@ -1,80 +1,59 @@
+import functools
+
from pypy.rpython.ootypesystem import ootype
-from mech.fusion.avm2.constants import QName, packagedQName, TYPE_MULTINAME_TypeName
-from mech.fusion.avm2.query import ClassDesc
-from mech.fusion.avm2.library import Library
-from mech.fusion.avm2.playerglobal.flash.utils import Vector
-
-from pypy.translator.avm2.types_ import vec_qname
-
-## Monkey Patching!
-
-ClassDesc._nativeclass = None
-
-class PyPyLibrary(Library):
- def resolve_class(self, TYPE):
- if self.has_type(TYPE):
- return self.get_type(TYPE)
- if playerglobal_lib.has_type(TYPE):
- return self.get_type(TYPE)
- if TYPE.KIND == TYPE_MULTINAME_TypeName and TYPE.name == vec_qname:
- assert len(TYPE.types) == 1
- return Vector[TYPE.types[0]]
- if getattr(TYPE, "multiname", None):
- return TYPE.multiname()
-
- def convert_classdesc(self, classdesc):
- resolve = self.resolve_class
- from pypy.translator.avm2.runtime import NativeClass, NativeInstance
- from pypy.translator.avm2.runtime import _overloaded_static_meth, _static_meth
-
- if classdesc._nativeclass is not None:
- return classdesc._nativeclass
-
- TYPE = NativeInstance(classdesc.Package, classdesc.ShortName, None, {}, {})
- Class = NativeClass(TYPE, {}, {})
- classdesc._nativeclass = Class
- if classdesc.FullName == QName('Object'):
- TYPE._set_superclass(ootype.ROOT)
- else:
- BASETYPE = resolve(classdesc.BaseType)
- TYPE._set_superclass(BASETYPE)
-
- TYPE._isArray = classdesc.IsArray
- if classdesc.IsArray:
- TYPE._ELEMENT = resolve(classdesc.ElementType)
-
- # add both static and instance methods, and static fields
- static_meths = self.group_methods(classdesc.StaticMethods,
- _overloaded_static_meth, _static_meth, ootype.StaticMethod)
- meths = self.group_methods(classdesc.Methods, ootype.overload,
- ootype.meth, ootype.Meth)
- Class._add_methods(static_meths)
- Class._add_static_fields(dict((name,
- resolve(t)) for name, t in classdesc.StaticFields]))
- Class._add_static_fields(dict((name,
- resolve(t)) for name, t, g, s in classdesc.StaticProperties))
- TYPE._add_methods(meths)
- TYPE._add_fields(dict((name, resolve(t)) for name, t in classdesc.Fields))
- TYPE._add_fields(dict((name, resolve(t)) for name, t, g, s in classdesc.Properties))
- return Class
-
- def group_methods(self, methods, overload, meth, Meth):
- from pypy.translator.avm2.runtime import OverloadingResolver
- groups = {}
- for name, args, result, AS3 in methods:
- groups[name] = args, result, AS3
-
- res = {}
- attrs = dict(resolver=OverloadingResolver)
- for name, methlist in groups.iteritems():
- meths = [meth(Meth([self.resolve_class(arg) for arg in args],
- self.resolve_class(result))) for (args, result) in methlist]
- res[name] = overload(*meths, **attrs)
- return res
+from mech.fusion.avm2 import playerglobal
+from mech.fusion.avm2.interfaces import IMultiname
+from mech.fusion.avm2.constants import QName, TypeName, undefined
+from mech.fusion.avm2.library import make_package
+
+from pypy.translator.avm2.runtime import AVM2Class, AVM2Instance, _static_meth
+
+def ClassDescConverter(classdesc, _cache={}):
+ T = classdesc.Library.get_type
+ C = lambda t: ClassDescConverter(t)._INSTANCE
+ def resolve(TYPE):
+ if TYPE in classdesc.Library:
+ return C(T(TYPE))
+
+ if type(TYPE) == object or TYPE in (undefined, None): # interfaces and root objects
+ return ootype.ROOT
+ name = IMultiname(TYPE)
+
+ if isinstance(name, TypeName):
+ return C(T(name.name).specialize(name.types))
+
+ return name
+
+ def create_methods(methods, meth, Meth):
+ return dict((name, meth(Meth([resolve(arg) for arg in args], resolve(result))))
+ for name, args, result in methods)
+
+ if classdesc in _cache:
+ return _cache[classdesc]
+
+ TYPE = AVM2Instance(classdesc.Package, classdesc.ShortName, None)
+ Class = AVM2Class(TYPE, {}, {})
+ _cache[classdesc] = Class
+
+ if classdesc.FullName == QName('Object'):
+ TYPE._set_superclass(ootype.ROOT)
+ else:
+ TYPE._set_superclass(resolve(classdesc.BaseType))
+
+ # add both static and instance methods, and static fields
+ static_meths = create_methods(classdesc.StaticMethods, _static_meth, ootype.StaticMethod)
+ meths = create_methods(classdesc.Methods, ootype.meth, ootype.Meth)
+ Class._add_methods(static_meths)
+ Class._add_static_fields(dict((t[0], resolve(t[1])) for t in
+ classdesc.StaticFields + classdesc.StaticProperties))
+
+ TYPE._add_methods(meths)
+ TYPE._add_fields(dict((t[0], resolve(t[1])) for t in
+ classdesc.Fields + classdesc.Properties if not TYPE._has_field(t[0])))
-from mech.fusion.avm2.library import get_playerglobal
+ return Class
-playerglobal_lib = get_playerglobal(Library=PyPyLibrary)
-playerglobal_lib.install_global(__name__.rpartition(".")[0]+".playerglobal")
+convert_package = functools.partial(make_package, Interface=ClassDescConverter)
+get_playerglobal = functools.partial(make_package, playerglobal, ClassDescConverter)
Modified: pypy/branch/avm/pypy/translator/avm2/metavm.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/metavm.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/metavm.py Thu Jul 22 02:36:39 2010
@@ -1,19 +1,37 @@
+
from pypy.rpython.ootypesystem import ootype
-from pypy.translator.oosupport.metavm import MicroInstruction, PushAllArgs, \
- StoreResult, GetField, SetField, DownCast, _Call as _OOCall, \
- get_primitive_name
-from pypy.translator.avm2.runtime import _static_meth, NativeInstance
-from pypy.translator.avm2 import types_ as types
-from mech.fusion.avm2 import constants
-
-STRING_HELPER_CLASS = '[pypylib]pypy.runtime.String'
-
-def functype_to_cts(cts, FUNC):
- ret_type = cts.lltype_to_cts(FUNC.RESULT)
- arg_types = [cts.lltype_to_cts(arg).typename()
- for arg in FUNC.ARGS
- if arg is not ootype.Void]
- return ret_type, arg_types
+from pypy.objspace.flow.model import Constant
+from pypy.translator.oosupport.metavm import MicroInstruction, _Call as _OOCall
+from pypy.translator.avm2.runtime import _static_meth
+from pypy.translator.avm2.rlib import RLib
+from pypy.translator.avm2.types_ import types
+
+from mech.fusion.avm2.interfaces import IMultiname
+
+class AddSub(MicroInstruction):
+ def __init__(self, int, add):
+ if int:
+ if add:
+ self.p1, self.n1 = 'increment_i', 'decrement_i'
+ else:
+ self.p1, self.n1 = 'decrement_i', 'increment_i'
+ else:
+ if add:
+ self.p1, self.n1 = 'increment', 'decrement'
+ else:
+ self.p1, self.n1 = 'decrement', 'increment'
+
+ def render(self, generator, op):
+ if isinstance(op.args[1], Constant):
+ if op.args[1].value == 1:
+ generator.load(op.args[0])
+ generator.emit(self.p1)
+ elif op.args[1].value == -1:
+ generator.load(op.args[0])
+ generator.emit(self.n1)
+ for arg in op.args:
+ generator.load(arg)
+ generator.emit('add')
class _Call(_OOCall):
def render(self, generator, op):
@@ -24,58 +42,47 @@
generator.call_graph(op.args[0].value.graph, op.args[1:])
def _render_static_function(self, generator, funcdesc, args):
- import pdb; pdb.set_trace()
- for func_arg in args[1:]: # push parameters
- self._load_arg_or_null(generator, func_arg)
cts = generator.cts
+ generator.load(*args[1:])
generator.emit()
- def _load_arg_or_null(self, generator, *args):
- for arg in args:
- if arg.concretetype is ootype.Void:
- if arg.value is None:
- generator.ilasm.push_null() # special-case: use None as a null value
- else:
- assert False, "Don't know how to load this arg"
- else:
- generator.load(arg)
-
-
class _CallMethod(_Call):
- DISPATCH = {
- ootype.Array : {
- "ll_setitem_fast": lambda gen: gen.array_setitem(),
- "ll_getitem_fast": lambda gen: gen.array_getitem(),
- "ll_length": lambda gen: gen.get_field("length", types.types.int),
- },
- ootype.AbstractString : {
- "ll_append": lambda gen: gen.emit('add'),
- "ll_stritem_nonneg": lambda gen: gen.call_method("charAt", 1, types.types.string),
- "ll_strlen": lambda gen: gen.get_field("length", types.types.int),
- },
+ donothing = object()
+ ONELINER = {
+ "list_ll_length": lambda gen,a: gen.get_field("length", types.int),
+
+ "str_ll_append": lambda gen,a: gen.emit('add'),
+ "str_ll_strlen": lambda gen,a: gen.get_field("length", types.int),
+ "str_ll_stritem_nonneg": lambda gen,a: gen.call_method("charAt", 1, types.string),
+ "str_ll_strconcat": lambda gen,a: gen.emit('add'),
+ "str_ll_streq": lambda gen,a: gen.emit('equals'),
+ "str_ll_strcmp": lambda gen,a: gen.call_method("localeCompare", 1, types.int),
+
+ "stringbuilder_ll_allocate": donothing,
+ "stringbuilder_ll_build": donothing,
}
def render(self, generator, op):
method = op.args[0]
self._render_method(generator, method.value, op.args[1:])
def _render_method(self, generator, method_name, args):
- this = args[0]
- native = isinstance(this.concretetype, NativeInstance)
- if native:
- self._load_arg_or_null(generator, *args)
- else:
+ DISPATCH, meth = self.ONELINER, args[0].concretetype.oopspec_name+'_'+method_name
+ if meth in DISPATCH:
generator.load(*args)
-
- for TYPE, D in self.DISPATCH.iteritems():
- if isinstance(this.concretetype, TYPE):
- D[method_name](generator)
- break
+ if DISPATCH[meth] is not self.donothing:
+ DISPATCH[meth](generator, args)
+ elif getattr(generator, meth, None):
+ getattr(generator, meth)(args)
+ elif meth in RLib:
+ RLib[meth](generator, *args)
else:
- generator.call_method(method_name, len(args)-1)
+ # storeresult expects something on the stack
+ generator.push_null()
class _IndirectCall(_CallMethod):
def render(self, generator, op):
# discard the last argument because it's used only for analysis
+ assert False
self._render_method(generator, 'Invoke', op.args[:-1])
class ConstCall(MicroInstruction):
@@ -84,8 +91,7 @@
self.__args = args
def render(self, generator, op):
- generator.load(*self.__args)
- generator.call_method(self.__method, len(self.__args))
+ generator.call_method_constargs(self.__method, None, *self.__args)
class ConstCallArgs(MicroInstruction):
def __init__(self, method, numargs):
@@ -103,32 +109,52 @@
class _OOString(MicroInstruction):
def render(self, generator, op):
- if op.args[1] == -1:
- generator.emit('findpropstrict', types.str_qname)
- generator.load(op.args[0])
- generator.emit('callproperty', types.str_qname, 1)
+ obj, base = op.args
+ if base == -1 or (isinstance(base, Constant) and base.value == -1):
+ if isinstance(obj.concretetype, ootype.Instance):
+ generator.load("<")
+ generator.call_method_constargs('getName', obj)
+ generator.emit('add')
+ generator.load(" object>")
+ generator.emit('add')
+ else:
+ generator.call_method_constargs('toString', obj)
else:
- generator.load(*op.args)
- generator.emit('callproperty', constants.QName("toString"), 1)
+ generator.call_method_constargs('toString', obj, base)
class _OOParseInt(MicroInstruction):
def render(self, generator, op):
- generator.load(*op.args)
- generator.emit('getglobalscope')
- generator.emit('callproperty', constants.QName("parseInt"), 2)
+ generator.call_function_constargs('parseInt', *op.args)
class _OOParseFloat(MicroInstruction):
def render(self, generator, op):
- generator.load(*op.args)
- generator.emit('getglobalscope')
- generator.emit('callproperty', constants.QName("parseFloat"), 1)
+ generator.call_function_constargs('parseFloat', *op.args)
+
+class _SetField(MicroInstruction):
+ def render(self, generator, op):
+ this, field, value = op.args
+ if value.concretetype is ootype.Void:
+ return
+ generator.load(this)
+ generator.load(value)
+ generator.set_field(field.value)
+
+class _GetField(MicroInstruction):
+ def render(self, generator, op):
+ # OOType produces void values on occassion that can safely be ignored
+ if op.result.concretetype is ootype.Void:
+ return
+ this, field = op.args
+ generator.load(this)
+ generator.get_field(field.value)
+
class PushClass(MicroInstruction):
def __init__(self, classname):
- self.__class = constants.QName(classname)
+ self.__class = IMultiname(classname)
def render(self, generator, op):
- generator.emit('getlex', constants.QName(self.__class))
+ generator.load(self.__class)
# class _NewCustomDict(MicroInstruction):
# def render(self, generator, op):
@@ -220,33 +246,8 @@
class _TypeOf(MicroInstruction):
def render(self, generator, op):
- c_type, = op.args
- assert c_type.concretetype is ootype.Void
- if isinstance(c_type.value, ootype.StaticMethod):
- FUNC = c_type.value
- fullname = generator.cts.lltype_to_cts(FUNC)
- else:
- cliClass = c_type.value
- fullname = cliClass._INSTANCE._name
generator.gettype()
-class _EventHandler(MicroInstruction):
- def render(self, generator, op):
- cts = generator.cts
- v_obj, c_methname = op.args
- assert c_methname.concretetype is ootype.Void
- TYPE = v_obj.concretetype
- classname = TYPE._name
- methname = 'o' + c_methname.value # XXX: do proper mangling
- _, meth = TYPE._lookup(methname)
- METH = ootype.typeOf(meth)
- ret_type, arg_types = functype_to_cts(cts, METH)
- arg_list = ', '.join(arg_types)
- generator.load(v_obj)
- desc = '%s class %s::%s(%s)' % (ret_type, classname, methname, arg_list)
- generator.ilasm.opcode('ldftn instance', desc)
- generator.ilasm.opcode('newobj', 'instance void class [mscorlib]System.EventHandler::.ctor(object, native int)')
-
class _GetStaticField(MicroInstruction):
def render(self, generator, op):
cts_class = op.args[0].value
@@ -262,17 +263,6 @@
generator.ilasm.swap()
generator.ilasm.set_field(fldname)
-class _FieldInfoForConst(MicroInstruction):
- def render(self, generator, op):
- from pypy.translator.cli.constant import CONST_CLASS
- llvalue = op.args[0].value
- constgen = generator.db.constant_generator
- const = constgen.record_const(llvalue)
- generator.ilasm.opcode('ldtoken', CONST_CLASS)
- generator.ilasm.call('class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)')
- generator.ilasm.opcode('ldstr', '"%s"' % const.name)
- generator.ilasm.call_method('class [mscorlib]System.Reflection.FieldInfo class [mscorlib]System.Type::GetField(string)', virtual=True)
-
# OOTYPE_TO_MNEMONIC = {
# ootype.Bool: 'i1',
@@ -300,11 +290,11 @@
GetArrayElem = _GetArrayElem()
SetArrayElem = _SetArrayElem()
TypeOf = _TypeOf()
-EventHandler = _EventHandler()
GetStaticField = _GetStaticField()
SetStaticField = _SetStaticField()
-FieldInfoForConst = _FieldInfoForConst()
OOString = _OOString()
OOParseInt = _OOParseInt()
OOParseFloat = _OOParseFloat()
# CastPrimitive = _CastPrimitive()
+GetField = _GetField()
+SetField = _SetField()
Modified: pypy/branch/avm/pypy/translator/avm2/opcodes.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/opcodes.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/opcodes.py Thu Jul 22 02:36:39 2010
@@ -1,16 +1,18 @@
from pypy.translator.avm2.metavm import Call, CallMethod, \
- IndirectCall, GetField, SetField, DownCast, \
- NewArray, GetArrayElem, SetArrayElem, OOParseInt, OOParseFloat, \
- TypeOf, EventHandler, GetStaticField, SetStaticField, \
- FieldInfoForConst, OOString, ConstCall, ConstCallArgs, PushClass
-from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\
- New, RuntimeNew, CastTo, PushPrimitive, OONewArray
+ IndirectCall, GetField, SetField, AddSub, \
+ NewArray, OOParseInt, OOParseFloat, \
+ TypeOf, GetStaticField, SetStaticField, \
+ OOString, ConstCall, ConstCallArgs, PushClass
+from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, \
+ StoreResult, InstructionList, New, RuntimeNew, CastTo, PushPrimitive, \
+ OONewArray, DownCast
from pypy.translator.cli.cts import WEAKREF
from pypy.rpython.ootypesystem import ootype
# some useful instruction patterns
Not = ['not']
DoNothing = [PushAllArgs]
+DontStoreResult = object()
Ignore = []
def _not(op):
@@ -45,8 +47,10 @@
# 'cli_setstaticfield': [SetStaticField],
# 'cli_fieldinfo_for_const': [FieldInfoForConst],
'oois': 'strictequals',
- 'oononnull': [PushAllArgs, 'pushnull', 'equals', 'not'],
- 'classof': [PushAllArgs, 'callvirt instance class [mscorlib]System.Type object::GetType()'],
+# 'oononnull': [PushAllArgs, 'pushnull', 'equals', 'not'],
+ 'oononnull': [PushAllArgs, 'convert_b'],
+ 'ooisnull': [PushAllArgs, 'pushnull', 'equals'],
+ 'classof': [PushAllArgs, TypeOf],
'instanceof': [CastTo],
'subclassof': [CastTo],
'ooidentityhash': [PushAllArgs, 'callvirt instance int32 object::GetHashCode()'],
@@ -134,12 +138,16 @@
'char_gt': 'greaterthan',
'char_ge': 'greaterequals',
- 'unichar_eq': 'ceq',
- 'unichar_ne': _not('ceq'),
+ 'unichar_eq': 'equals',
+ 'unichar_ne': _not('equals'),
'int_add': 'add_i',
+ 'int_add_ovf': 'add_i',
+ 'int_add_nonneg_ovf': 'add_i',
'int_sub': 'subtract_i',
+ 'int_sub_ovf': 'subtract_i',
'int_mul': 'multiply_i',
+ 'int_mul_ovf': 'multiply_i',
'int_floordiv': [PushAllArgs, 'divide', 'convert_i'],
# 'int_floordiv_zer': _check_zer('div'),
'int_mod': 'modulo',
@@ -155,7 +163,7 @@
'int_rshift': 'rshift',
'int_xor': 'bitxor',
# 'int_add_ovf': _check_ovf('add.ovf'),
-# 'int_add_nonneg_ovf': _check_ovf('add.ovf'),
+
# 'int_sub_ovf': _check_ovf('sub.ovf'),
# 'int_mul_ovf': _check_ovf('mul.ovf'),
'int_floordiv_ovf': 'divide', # these can't overflow!
@@ -253,7 +261,9 @@
if type(value) is str:
value = InstructionList([PushAllArgs, value, StoreResult])
elif value is not None:
- if value is not Ignore and StoreResult not in value:
+ if DontStoreResult in value:
+ value.remove(DontStoreResult)
+ elif value is not Ignore and StoreResult not in value:
value.append(StoreResult)
value = InstructionList(value)
Modified: pypy/branch/avm/pypy/translator/avm2/record.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/record.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/record.py Thu Jul 22 02:36:39 2010
@@ -1,10 +1,11 @@
+
from pypy.rpython.ootypesystem import ootype
-from pypy.translator.cli.node import Node
+from pypy.translator.avm2.node import ClassNodeBase
-from mech.fusion.avm2 import constants as c, traits
-from pypy.translator.avm2 import types_ as types
+from mech.fusion.avm2.constants import QName
+from mech.fusion.avm2.interfaces import IMultiname
-class Record(Node):
+class Record(ClassNodeBase):
def __init__(self, db, record, name):
self.db = db
self.cts = db.genoo.TypeSystem(db)
@@ -15,55 +16,55 @@
return hash(self.record)
def __eq__(self, other):
- return self.record == other.record
+ return type(self) == type(other) and self.record == other.record
def __ne__(self, other):
return not self == other
+ def __repr__(self):
+ return '<Record %s>' % self.name
+
+ def get_type(self):
+ return QName(self.name)
+
def get_name(self):
return self.name
def get_base_class(self):
- return c.QName("Object")
+ return QName("Object")
- def render(self, ilasm):
- self.ilasm = ilasm
- ilasm.begin_class(c.QName(self.name))
- for f_name, (FIELD_TYPE, f_default) in self.record._fields.iteritems():
- f_name = self.cts.escape_name(f_name)
- cts_type = self.cts.lltype_to_cts(FIELD_TYPE)
- if cts_type != types.types.void:
- ilasm.context.add_instance_trait(traits.AbcSlotTrait(c.QName(f_name), cts_type.multiname()))
- self._toString()
- #self._getHashCode()
- ilasm.exit_context()
-
- def _toString(self):
- # only for testing purposes, and only if the Record represents a tuple
- from pypy.translator.cli.test.runtest import format_object
+ def get_fields(self):
+ return self.record._fields.iteritems()
+
+ def _fieldToString(self, ilasm, fieldnum):
+ f_name = 'item%d' % (fieldnum,)
+ FIELD_TYPE, f_default = self.record._fields[f_name]
+ if FIELD_TYPE is ootype.Void:
+ return True
+ ilasm.push_this()
+ ilasm.emit('getproperty', IMultiname(f_name))
+ ilasm.emit('convert_s')
+ def render_toString(self, ilasm):
for f_name in self.record._fields:
if not f_name.startswith('item'):
return # it's not a tuple
- self.ilasm.begin_method('toString', [], c.QName("String"))
- self.ilasm.push_const("(")
- for i in xrange(len(self.record._fields)):
- f_name = 'item%d' % i
- FIELD_TYPE, f_default = self.record._fields[f_name]
- if FIELD_TYPE is ootype.Void:
+ ilasm.begin_method('toString', [], QName("String"))
+ ilasm.load("(")
+ fieldlen = len(self.record._fields)-1
+ for i in xrange(fieldlen):
+ if self._fieldToString(ilasm, i):
continue
- self.ilasm.push_this()
- #self.ilasm.get_field((f_type, self.name, f_name))
- self.ilasm.emit('getproperty', c.QName(f_name))
- self.ilasm.emit('callproperty', c.Multiname("toString", c.PROP_NAMESPACE_SET), 0)
- self.ilasm.emit('add')
- self.ilasm.push_const(", ")
- self.ilasm.emit('add')
- self.ilasm.push_const(")")
- self.ilasm.emit('add')
- self.ilasm.emit('returnvalue')
- self.ilasm.exit_context()
+ ilasm.emit('add')
+ ilasm.load(", ")
+ ilasm.emit('add')
+ self._fieldToString(ilasm, fieldlen)
+ ilasm.emit('add')
+ ilasm.load(")")
+ ilasm.emit('add')
+ ilasm.emit('returnvalue')
+ ilasm.exit_context()
# def _equals(self):
# # field by field comparison
Modified: pypy/branch/avm/pypy/translator/avm2/runtime.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/runtime.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/runtime.py Thu Jul 22 02:36:39 2010
@@ -3,10 +3,9 @@
from pypy.tool.pairtype import pair, pairtype
from pypy.annotation.model import SomeObject, SomeInstance, SomeOOInstance, SomeInteger, s_None,\
s_ImpossibleValue, lltype_to_annotation, annotation_to_lltype, SomeChar, SomeString
-# from pypy.annotation.unaryop import immutablevalue
-# from pypy.annotation.binaryop import _make_none_union
+
from pypy.annotation import model as annmodel
-# from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong
+
from pypy.rpython.error import TyperError
from pypy.rpython.extregistry import ExtRegistryEntry
from pypy.rpython.rmodel import Repr
@@ -17,17 +16,16 @@
## Annotation model
-class SomeNativeClass(SomeObject):
+class SomeAVM2Class(SomeObject):
def getattr(self, s_attr):
assert self.is_constant()
assert s_attr.is_constant()
nativeclass = self.const
attrname = s_attr.const
if attrname in nativeclass._static_fields:
- TYPE = nativeclass._static_fields[attrname]
- return OverloadingResolver.lltype_to_annotation(TYPE)
+ return nativeclass._static_fields[attrname]
elif attrname in nativeclass._static_methods:
- return SomeNativeStaticMethod(nativeclass, attrname)
+ return SomeAVM2StaticMethod(nativeclass, attrname)
else:
return s_ImpossibleValue
@@ -45,13 +43,13 @@
return SomeOOInstance(self.const._INSTANCE)
def rtyper_makerepr(self, rtyper):
- return NativeClassRepr(self.const)
+ return AVM2ClassRepr(self.const)
def rtyper_makekey(self):
return self.__class__, self.const
-class SomeNativeStaticMethod(SomeObject):
+class SomeAVM2StaticMethod(SomeObject):
def __init__(self, native_class, meth_name):
self.native_class = native_class
self.meth_name = meth_name
@@ -60,7 +58,7 @@
return self.native_class._ann_static_method(self.meth_name, args_s)
def rtyper_makerepr(self, rtyper):
- return NativeStaticMethodRepr(self.native_class, self.meth_name)
+ return AVM2StaticMethodRepr(self.native_class, self.meth_name)
def rtyper_makekey(self):
return self.__class__, self.native_class, self.meth_name
@@ -96,7 +94,7 @@
## Rtyper model
-class NativeClassRepr(Repr):
+class AVM2ClassRepr(Repr):
lowleveltype = ootype.Void
def __init__(self, native_class):
@@ -122,14 +120,13 @@
return hop.genop("setstaticfield", [c_class, c_name, v_value], resulttype=hop.r_result.lowleveltype)
def rtype_simple_call(self, hop):
- # TODO: resolve constructor overloading
INSTANCE = hop.args_r[0].native_class._INSTANCE
cINST = hop.inputconst(ootype.Void, INSTANCE)
vlist = hop.inputargs(*hop.args_r)[1:] # discard the first argument
hop.exception_is_here()
return hop.genop("new", [cINST]+vlist, resulttype=hop.r_result.lowleveltype)
-class NativeStaticMethodRepr(Repr):
+class AVM2StaticMethodRepr(Repr):
lowleveltype = ootype.Void
def __init__(self, native_class, meth_name):
@@ -153,15 +150,11 @@
class __extend__(pairtype(OOInstanceRepr, IntegerRepr)):
def rtype_getitem((r_inst, r_int), hop):
- if not r_inst.lowleveltype._isArray:
- raise TyperError("getitem() on a non-array instance")
v_array, v_index = hop.inputargs(r_inst, ootype.Signed)
hop.exception_is_here()
return hop.genop('getelem', [v_array, v_index], hop.r_result.lowleveltype)
def rtype_setitem((r_inst, r_int), hop):
- if not r_inst.lowleveltype._isArray:
- raise TyperError("setitem() on a non-array instance")
vlist = hop.inputargs(*hop.args_r)
hop.exception_is_here()
return hop.genop('setelem', vlist, hop.r_result.lowleveltype)
@@ -176,50 +169,17 @@
hop.exception_cannot_occur()
return hop.genop('arraylength', vlist, hop.r_result.lowleveltype)
- def rtype_simple_call(self, hop):
- TYPE = self.lowleveltype
- _, meth = TYPE._lookup('Invoke')
- assert isinstance(meth, ootype._overloaded_meth)
- ARGS = tuple([repr.lowleveltype for repr in hop.args_r[1:]])
- desc = meth._get_desc('Invoke', ARGS)
- cname = hop.inputconst(ootype.Void, desc)
- vlist = hop.inputargs(self, *hop.args_r[1:])
- hop.exception_is_here()
- return hop.genop("oosend", [cname]+vlist,
- resulttype = hop.r_result.lowleveltype)
+ ## def rtype_simple_call(self, hop):
+ ## TYPE = self.lowleveltype
+ ## ARGS = tuple([repr.lowleveltype for repr in hop.args_r[1:]])
+ ## vlist = hop.inputargs(self, *hop.args_r[1:])
+ ## hop.exception_is_here()
+ ## return hop.genop("oosend", [cname]+vlist,
+ ## resulttype = hop.r_result.lowleveltype)
## OOType model
-class OverloadingResolver(ootype.OverloadingResolver):
-
- def _can_convert_from_to(self, ARG1, ARG2):
- if ARG1 is ootype.Void and isinstance(ARG2, NativeInstance):
- return True # ARG1 could be None, that is always convertible to a NativeInstance
- else:
- return ootype.OverloadingResolver._can_convert_from_to(self, ARG1, ARG2)
-
- def annotation_to_lltype(cls, ann):
- if isinstance(ann, SomeChar):
- return ootype.Char
- elif isinstance(ann, SomeString):
- return ootype.String
- else:
- return annotation_to_lltype(ann)
- annotation_to_lltype = classmethod(annotation_to_lltype)
-
- def lltype_to_annotation(cls, TYPE):
- if isinstance(TYPE, NativeInstance):
- return SomeOOInstance(TYPE)
- elif TYPE is ootype.Char:
- return SomeChar()
- elif TYPE is ootype.String:
- return SomeString(can_be_None=True)
- else:
- return lltype_to_annotation(TYPE)
- lltype_to_annotation = classmethod(lltype_to_annotation)
-
-
class _static_meth(object):
def __init__(self, TYPE):
@@ -233,22 +193,7 @@
#assert ARGS == self._TYPE.ARGS
return self
-class _overloaded_static_meth(object):
- def __init__(self, *overloadings, **attrs):
- resolver = attrs.pop('resolver', OverloadingResolver)
- assert not attrs
- self._resolver = resolver(overloadings)
-
- def _set_attrs(self, cls, name):
- for meth in self._resolver.overloadings:
- meth._set_attrs(cls, name)
-
- def _get_desc(self, ARGS):
- meth = self._resolver.resolve(ARGS)
- assert isinstance(meth, _static_meth)
- return meth._get_desc(ARGS)
-
-class NativeInstance(ootype.Instance):
+class AVM2Instance(ootype.Instance):
def __init__(self, namespace, name, superclass,
fields={}, methods={}, _is_root=False, _hints = {}):
fullname = '%s.%s' % (namespace, name)
@@ -258,11 +203,9 @@
ootype.Instance.__init__(self, fullname, superclass, fields, methods, _is_root, _hints)
-
-
## RPython interface definition
-class NativeClass(object):
+class AVM2Class(object):
def __init__(self, INSTANCE, static_methods, static_fields):
self._name = INSTANCE._name
self._INSTANCE = INSTANCE
@@ -294,10 +237,10 @@
class Entry(ExtRegistryEntry):
- _type_ = NativeClass
+ _type_ = AVM2Class
def compute_annotation(self):
- return SomeNativeClass()
+ return SomeAVM2Class()
def compute_result_annotation(self):
return SomeOOInstance(self.instance._INSTANCE)
@@ -325,7 +268,7 @@
def specialize_call(self, hop):
c_type, v_length = hop.inputargs(*hop.args_r)
hop.exception_cannot_occur()
- return hop.genop('avm2_newvector', [c_type, v_length], hop.r_result.lowleveltype)
+ return hop.genop('newvector', [c_type, v_length], hop.r_result.lowleveltype)
class Entry(ExtRegistryEntry):
@@ -500,10 +443,6 @@
# def compute_annotation(self):
# return SomeOOInstance(CLR.System.Reflection.FieldInfo._INSTANCE)
-from pypy.translator.avm2.query import NativeNamespace
-playerglobal = NativeNamespace(None)
-playerglobal._buildtree()
-
# known_delegates = {
# ootype.StaticMethod([ootype.Signed], ootype.Signed): CLR.pypy.test.DelegateType_int__int_1,
# ootype.StaticMethod([ootype.Signed] * 2, ootype.Signed): CLR.pypy.test.DelegateType_int__int_2,
Modified: pypy/branch/avm/pypy/translator/avm2/test/browsertest.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/test/browsertest.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/test/browsertest.py Thu Jul 22 02:36:39 2010
@@ -23,11 +23,11 @@
<allow-access-from domain="*" secure="false"/>
</cross-domain-policy>"""
-class InstanceWrapper:
+class InstanceWrapper(Exception):
def __init__(self, class_name):
self.class_name = class_name
-class ExceptionWrapper:
+class ExceptionWrapper(Exception):
def __init__(self, class_name):
self.class_name = class_name
Modified: pypy/branch/avm/pypy/translator/avm2/test/entrypoint.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/test/entrypoint.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/test/entrypoint.py Thu Jul 22 02:36:39 2010
@@ -1,103 +1,107 @@
+
import py
+import subprocess
+
from pypy.conftest import option
+from pypy.rpython.ootypesystem import ootype
from pypy.translator.avm2.test.browsertest import browsertest
-from pypy.translator.avm2.avm2gen import PyPyAvm2ilasm
+from pypy.translator.avm2.codegen import PyPyCodeGenerator
+from pypy.translator.avm2.entrypoint import BaseEntryPoint
+from mech.fusion.swf import tags
from mech.fusion.swf.swfdata import SwfData
-from mech.fusion.swf.tags import FileAttributes, SetBackgroundColor, \
- DefineEditText, SymbolClass, PlaceObject2, DoABC, ShowFrame, End
from mech.fusion.swf.records import Rect, RGBA
from mech.fusion.avm2.abc_ import AbcFile
-from mech.fusion.avm2.constants import QName, packagedQName
+from mech.fusion.avm2.constants import QName, packagedQName, MultinameL
from mech.fusion.avm2.traits import AbcSlotTrait
-class BaseTestEntryPoint(object):
- def __init__(self, name, gen, wrap_exceptions):
- self.excwrap = wrap_exceptions
+class BaseTestEntryPoint(BaseEntryPoint):
+ def __init__(self, name, graph, excwrap):
self.name = name
- self.swf = SwfData()
- self.swf.add_tag(FileAttributes())
- self.swf.add_tag(SetBackgroundColor(0x333333))
- self.swf.add_tag(DefineEditText(Rect(0, 0, 600, 400), "", ('''
-Running test %s.
-If no text saying "Go:" appears below, the test probably had an error.
-======================================================================
-'''.strip() % (name,)), color=RGBA(0xFFFFFF)))
- self.swf.add_tag(PlaceObject2(1, 2, name="edittext"))
- self.abc = DoABC("PyPy Main")
- self.actions = PyPyAvm2ilasm(gen.db, self.abc, option.mf_optim)
-
- self.swf.add_tag(self.abc)
- self.swf.add_tag(SymbolClass({0:"PyPyTest_EntryPoint"}))
- self.swf.add_tag(ShowFrame())
- self.swf.add_tag(End())
-
- def update_text(self):
- pass
-
- def print_text(self, text):
- self.actions.push_const(text)
- self.actions.store_var('text')
- self.update_text()
-
- def print_var(self, prefix, varname):
- self.actions.push_const(prefix)
- self.actions.push_var(varname)
- self.actions.emit('add')
- self.actions.store_var('text')
- self.update_text()
-
- def print_stack(self, prefix, dup=False):
- if dup:
- self.actions.dup()
- self.actions.store_var('text')
- self.update_text()
+ self.graph = graph
+ self.excwrap = excwrap
+ self.maincls_name = packagedQName("PyPyTest", name)
+
+ def get_name(self):
+ return self.name
+
+ def dependencies(self):
+ self.db.pending_function(self.graph)
+
+ def render(self, ilasm):
+ self.actions = ilasm
+ self.prologue()
+ self.start_test()
+ self.call_test()
+ self.finish_test()
- def start_test_maincls(self):
+ def prologue(self):
pass
- def start_test(self):
- self.start_test_maincls()
+ def call_test(self):
+ qname = self.actions.cts.graph_to_qname(self.graph)
if self.excwrap:
self.actions.begin_try()
+ self.actions.emit('findpropstrict', qname)
+ self.gather_arguments()
+ self.actions.emit('callproperty', qname, len(self.graph.getargs()))
def finish_test(self):
- # WHHEEEEEEE!
+ # WHHEEEEEEEE!
if self.excwrap:
self.actions.end_try()
- self.actions.emit('convert_s')
self.actions.branch_unconditionally("PyPy::ExceptionWrapLabel")
self.actions.begin_catch(QName("Error"))
self.actions.push_exception()
self.actions.emit('convert_s')
self.actions.end_catch()
self.actions.set_label("PyPy::ExceptionWrapLabel")
- self.actions.store_var('result')
- self.print_var("Got: ", 'result')
self.publish_test()
+ self.actions.exit_until_type("script")
+
+ def publish_test(self):
+ pass
+
+ def gather_arguments(self):
+ pass
+
+ def finish_compiling(self):
self.epilogue()
self.actions.finish()
+ self.save_test()
- def do_test(self):
+ def epilogue(self):
pass
- def epilogue(self):
+ def save_test(self):
pass
- def publish_test(self):
+ def run_test(self, args):
pass
class SWFTestEntryPoint(BaseTestEntryPoint):
- def do_test(self):
- self.finish_test()
- f = open("%s.flash.swf" % (self.name,), "wb")
- f.write(self.swf.serialize())
- f.close()
- f = open("%s.flash.abc" % (self.name,), "wb")
- f.write(AbcFile.serialize(self.abc))
- f.close()
-
+ def prologue(self):
+ self.swf = SwfData()
+ self.swf.add_tag(tags.FileAttributes())
+ self.swf.add_tag(tags.SetBackgroundColor(0x333333))
+ self.swf.add_tag(tags.DefineEditText(Rect(0, 0, 600, 400), "", ('''
+Running test %s. If no text saying "Got: "
+appears below, the test probably had an error.
+==================================================
+'''.strip() % (self.name,)), color=RGBA(0xFFFFFF)))
+ self.swf.add_tag(tags.PlaceObject2(1, 1, name="edittext"))
+ self.swf.add_tag(tags.DoABC("PyPy Main", self.actions.abc))
+ self.swf.add_tag(tags.SymbolClass({0:"PyPyTest::" + self.name}))
+ self.swf.add_tag(tags.ShowFrame())
+ self.swf.add_tag(tags.End())
+
+ def save_test(self):
+ barename = py.path.local(self.name + ".flash")
+ barename.new(ext=".swf").write(self.swf.serialize(), mode="wb")
+ barename.new(ext=".abc").write(self.actions.abc.serialize(), mode="wb")
+
+ def run_test(self, args):
return browsertest(self.name, self.swf)
def get_edittext(self):
@@ -109,23 +113,27 @@
def update_text(self):
self.get_edittext()
- self.actions.push_const("\n")
+ self.actions.load("\n")
self.actions.push_var('text')
self.actions.emit('add')
self.actions.emit('callpropvoid', QName("appendText"), 1)
- def start_test_maincls(self):
- self.maincls = self.actions.begin_class(QName("PyPyTest_EntryPoint"), packagedQName("flash.display", "Sprite"))
+ def start_test(self):
+ self.maincls = self.actions.begin_class(self.maincls_name,
+ packagedQName("flash.display", "Sprite"))
self.maincls.make_iinit()
- self.maincls.add_instance_trait(AbcSlotTrait(QName("edittext"), packagedQName("flash.text", "TextField")))
+ self.maincls.add_instance_trait(AbcSlotTrait(QName("edittext"),
+ packagedQName("flash.text", "TextField")))
def publish_test(self):
+ self.actions.store_var('text')
+ self.update_text()
self.actions.emit('findpropstrict', packagedQName("flash.net", "URLRequest"))
- self.actions.push_const('./test.result')
+ self.actions.load('./test.result')
self.actions.emit('constructprop', packagedQName("flash.net", "URLRequest"), 1)
self.actions.store_var('request')
self.actions.push_var('request')
- self.actions.push_const('POST')
+ self.actions.load('POST')
self.actions.set_field('method')
self.actions.push_var('request')
self.actions.emit('findpropstrict', packagedQName("flash.net", "URLVariables"))
@@ -140,32 +148,50 @@
self.actions.emit('callpropvoid', packagedQName("flash.net", "sendToURL"), 1)
self.actions.emit('findpropstrict', packagedQName("flash.net", "navigateToURL"))
self.actions.emit('findpropstrict', packagedQName("flash.net", "URLRequest"))
- self.actions.push_const('javascript: self.close()')
+ self.actions.load('javascript: self.close()')
self.actions.emit('constructprop', packagedQName("flash.net", "URLRequest"), 1)
- self.actions.push_const('_self')
+ self.actions.load('_self')
self.actions.emit('callpropvoid', packagedQName("flash.net", "navigateToURL"), 2)
class TamarinTestEntryPoint(BaseTestEntryPoint):
- def do_test(self):
- self.finish_test()
- f = open("%s.tamarin.abc" % (self.name,), "wb")
- f.write(AbcFile.serialize(self.abc))
- f.close()
- asdf
+ def save_test(self):
+ abc = py.path.local(self.name+".tamarin.abc")
+ abc.write(AbcFile.serialize(self.actions.abc), "wb")
+
+ def run_test(self, args):
+ procargs = [option.tamexec, self.name + ".tamarin.abc", "--"] + map(str, args)
+ testproc = subprocess.Popen(procargs, stdout=subprocess.PIPE)
+ return testproc.stdout.read()
- def update_text(self):
+ def publish_test(self):
self.actions.emit('findpropstrict', QName("print"))
- self.actions.push_const("\n")
- self.actions.push_var('text')
- self.actions.emit('add')
+ self.actions.swap()
self.actions.emit('callpropvoid', QName("print"), 1)
+ def gather_arguments(self):
+ self.actions.load(dict(False=False, True=True))
+ self.actions.store_var("booltable")
+ self.actions.load(packagedQName("avmplus", "System"))
+ self.actions.get_field("argv")
+ for index, arg in enumerate(self.graph.getargs()):
+ if arg.concretetype is not ootype.Void:
+ self.actions.dup()
+ if arg.concretetype is ootype.Bool:
+ self.actions.get_field(str(index))
+ self.actions.push_var("booltable")
+ self.actions.swap()
+ self.actions.emit('getproperty', MultinameL())
+ else:
+ self.actions.get_field(str(index), arg.concretetype)
+ self.actions.swap()
+ self.actions.pop()
+
def epilogue(self):
self.actions.exit_until_type("script")
self.actions.context.make_init()
- self.actions.push_var('this')
- self.actions.emit('constructprop', QName("PyPyTest_EntryPoint"), 0)
+ self.actions.push_this()
+ self.actions.emit('constructprop', self.maincls_name, 0)
- def start_test_maincls(self):
- self.maincls = self.actions.begin_class(QName("PyPyTest_EntryPoint"))
+ def start_test(self):
+ self.maincls = self.actions.begin_class(self.maincls_name)
self.maincls.make_iinit()
Modified: pypy/branch/avm/pypy/translator/avm2/test/runtest.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/test/runtest.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/test/runtest.py Thu Jul 22 02:36:39 2010
@@ -15,47 +15,53 @@
from pypy.translator.avm2.test.browsertest import ExceptionWrapper, InstanceWrapper
from pypy.translator.avm2.genavm import GenAVM2
-ENTRY_POINTS = dict(swf=SWFTestEntryPoint, tamarin=TamarinTestEntryPoint)
+class UnparsableResult(Exception):
+ pass
def parse_result(string):
string = string.strip()
+ if string.startswith("Got:"):
+ return parse_result_raw(string[4:].strip())
+ elif string.startswith("ExceptionWrapper"):
+ return eval(string.splitlines()[0])
+ raise UnparsableResult(string)
+
+def parse_result_raw(string):
+ if string == "":
+ return ""
if string == "true":
return True
- elif string == "false":
+ if string == "false":
return False
- elif string == "undefined" or string == "null":
+ if string == "undefined" or string == "null":
return None
- elif all(c in "123456789-" for c in string):
+ if string[0] + string[-1] in ('()', '[]'):
+ res = [parse_result_raw(s) for s in string[1:-1].split(",")]
+ return tuple(res) if string[0] == '(' else res
+ try:
return int(string)
- elif "," in string:
- if string.startswith("(") and string.endswith(")"):
- return tuple(parse_result(s) for s in string[1:-1].split(","))
- return [parse_result(s) for s in string.split(",")]
- elif string.startswith("ExceptionWrapper"):
- return eval(string)
- else:
- try:
- return float(string)
- except ValueError:
- pass
+ except ValueError:
+ pass
+ try:
+ return float(string)
+ except ValueError:
+ pass
return string
-def compile_function(func, name, annotation=[], backendopt=True,
+def compile_function(func, name, annotation, backendopt=True,
exctrans=False, annotatorpolicy=None, wrapexc=False):
olddefs = patch_os()
- gen = _build_gen(func, annotation, backendopt, exctrans, annotatorpolicy)
- entry_point = ENTRY_POINTS[option.tamtarget](name, gen, wrapexc)
- gen.ilasm = entry_point.actions
+ gen = _build_gen(func, name, annotation, backendopt,
+ exctrans, annotatorpolicy, wrapexc)
gen.generate_source()
+ gen.entrypoint.finish_compiling()
unpatch_os(olddefs) # restore original values
- return entry_point, gen
+ return gen
+
+def _build_gen(func, name, annotation, backendopt=True,
+ exctrans=False, annotatorpolicy=None, wrapexc=False):
+ func = getattr(func, "im_func", func)
-def _build_gen(func, annotation, backendopt=True, exctrans=False,
- annotatorpolicy=None):
- try:
- func = func.im_func
- except AttributeError:
- pass
t = TranslationContext()
ann = t.buildannotator(policy=annotatorpolicy)
ann.build_types(func, annotation)
@@ -70,15 +76,21 @@
tmpdir = py.path.local('.')
- return GenAVM2(tmpdir, t, None, exctrans)
+ if option.browsertest:
+ entry = SWFTestEntryPoint
+ else:
+ entry = TamarinTestEntryPoint
+ ep = entry(name, t.graphs[0], wrapexc)
+
+ return GenAVM2(tmpdir, t, ep, exctrans)
class AVM2Test(BaseRtypingTest, OORtypeMixin):
def __init__(self):
self._func = None
self._ann = None
- self._harness = None
+ self._entry_point = None
- def _compile(self, fn, args, ann=None, backendopt=True, exctrans=False, wrapexc=False):
+ def _compile(self, fn, ann=None, backendopt=True, exctrans=False, wrapexc=False):
frame = sys._getframe()
while frame:
name = frame.f_code.co_name
@@ -88,14 +100,13 @@
else:
name = "test_unknown"
- if ann is None:
- ann = [lltype_to_annotation(typeOf(x)) for x in args]
-
- self._entry_point = compile_function(fn, "%s.%s" % (type(self).__name__, name),
+ if fn == self._func and self._ann == ann:
+ return self._gen
+ self._gen = compile_function(fn, "%s.%s" % (type(self).__name__, name),
ann, backendopt=backendopt, exctrans=exctrans, wrapexc=wrapexc)
self._func = fn
self._ann = ann
- return self._entry_point
+ return self._gen
def _skip_win(self, reason):
if platform.system() == 'Windows':
@@ -116,11 +127,11 @@
def interpret(self, fn, args, annotation=None, backendopt=None,
exctrans=False, wrapexc=False):
backendopt = self._get_backendopt(backendopt)
- entry_point, gen = self._compile(fn, args, annotation,
- backendopt, exctrans, wrapexc)
- entry_point.start_test()
- entry_point.actions.call_graph(gen.translator.graphs[0], args)
- result = parse_result(entry_point.do_test())
+ if annotation is None:
+ annotation = [lltype_to_annotation(typeOf(x)) for x in args]
+ gen = self._compile(fn, annotation,
+ backendopt, exctrans, wrapexc)
+ result = parse_result(gen.entrypoint.run_test(args))
if isinstance(result, ExceptionWrapper):
raise result
return result
Modified: pypy/branch/avm/pypy/translator/avm2/test/test_int.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/test/test_int.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/test/test_int.py Thu Jul 22 02:36:39 2010
@@ -1,10 +1,8 @@
-import autopath
-import py
-from pypy.translator.avm1.test.runtest import AVM1Test
+
+from pypy.translator.avm2.test.runtest import AVM2Test
from pypy.rpython.test.test_rint import BaseTestRint
-from pypy.rlib.rarithmetic import r_longlong
-class TestAVM1Int(AVM1Test, BaseTestRint):
+class TestAVM2Int(AVM2Test, BaseTestRint):
def test_char_constant(self):
def dummyfn(i):
return chr(i)
@@ -17,34 +15,4 @@
pass # it doesn't make sense here
div_mod_iteration_count = 20
-
- def test_div_mod(self):
- import random
-
- for inttype in (int, r_longlong):
-
- # def d(x, y):
- # return x/y
- # for i in range(self.div_mod_iteration_count):
- # x = inttype(random.randint(-100000, 100000))
- # y = inttype(random.randint(-100000, 100000))
- # if not y: continue
- # res = self.interpret(d, [x, y])
- # print "x:", x, "y:", y, "result in Flash:", res, "result in Python:", d(x, y)
- # assert res == d(x, y)
-
- def m(x, y):
- return x%y
-
- for i in range(self.div_mod_iteration_count):
- x = inttype(random.randint(-100000, 100000))
- y = inttype(random.randint(-100000, 100000))
- if not y: continue
- res = self.interpret(m, [x, y])
- print "x:", x, "y:", y, "result in Flash:", res, "result in Python:", m(x, y)
- assert res == m(x, y)
-
-
-if __name__=="__main__":
- TestAVM1Int().test_div_mod()
Modified: pypy/branch/avm/pypy/translator/avm2/test/test_string.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/test/test_string.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/test/test_string.py Thu Jul 22 02:36:39 2010
@@ -7,7 +7,7 @@
EMPTY_STRING_HASH = 0
def test_unichar_const(self):
- py.test.skip("CLI interpret doesn't support unicode for input arguments")
+ py.test.skip("Tamarin interpret doesn't support unicode for input arguments")
test_unichar_eq = test_unichar_const
test_unichar_ord = test_unichar_const
test_unichar_hash = test_unichar_const
@@ -15,11 +15,11 @@
test_char_unichar_eq_2 = test_unichar_const
def test_upper(self):
- py.test.skip("CLI doens't support backquotes inside string literals")
+ py.test.skip("Tamarin doesn't support backquotes inside string literals")
test_lower = test_upper
def test_hlstr(self):
- py.test.skip("CLI tests can't have string as input arguments")
+ py.test.skip("Tamarin tests can't have string as input arguments")
test_inplace_add = test_hlstr
Modified: pypy/branch/avm/pypy/translator/avm2/types_.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm2/types_.py (original)
+++ pypy/branch/avm/pypy/translator/avm2/types_.py Thu Jul 22 02:36:39 2010
@@ -1,71 +1,42 @@
"""
-bTranslate between PyPy ootypesystem and .NET Common Type System
+Translate between PyPy ootypesystem and the Tamarin Type System.
"""
-import exceptions
-
-from py.builtin import set
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.ootypesystem import ootype
-from pypy.translator.cli import oopspec
-from pypy.translator.cli.option import getoption
-from mech.fusion.avm2 import constants
+from py.builtin import set
-from pypy.tool.ansi_print import ansi_log
+from mech.fusion.avm2.constants import packagedQName, QName, TypeName, null
+from mech.fusion.avm2.interfaces import IMultiname
-vec_qname = constants.packagedQName("__AS3__.vec", "Vector")
-str_qname = constants.QName("String")
-arr_qname = constants.QName("Array")
+from zope.component import adapter, provideAdapter
+from zope.interface import implementer
class Avm2Type(object):
- def typename(self):
- raise NotImplementedError
+ def __init__(self, multiname, default):
+ self.multiname = IMultiname(multiname)
+ self.default = default
+
+ @classmethod
+ def from_string(cls, name, default=None):
+ ns, _, name = name.rpartition('::')
+ return cls(packagedQName(ns, name), default)
def load_default(self, asm):
- raise NotImplementedError
+ asm.load(self.default)
def __str__(self):
- return str(self.multiname())
-
- def __hash__(self):
- return hash(self.multiname())
+ return str(self.multiname)
- def __eq__(self, other):
- return isinstance(other, type(self)) and self.multiname() == other.multiname()
-
- def __ne__(self, other):
- return not self == other
-
-class Avm2PrimitiveType(Avm2Type):
- def __init__(self, name, default):
- self.name, self.default = name, default
-
- def load_default(self, gen):
- gen.load(self.default)
+ at adapter(Avm2Type)
+ at implementer(IMultiname)
+def _adapter(self):
+ return self.multiname
- def typename(self):
- return self.name
+provideAdapter(_adapter)
- def multiname(self):
- return constants.QName(self.typename())
-
-class Avm2NamespacedType(Avm2Type):
- nstype = constants.TYPE_NAMESPACE_PackageNamespace
- def __init__(self, name, namespace=''):
- if '::' in name and namespace == '':
- self.ns, self.name = name.rsplit('::', 1)
- else:
- self.name = name
- self.ns = namespace
-
- def typename(self):
- return "%s::%s" % (self.ns, self.name)
-
- def multiname(self):
- return constants.QName(self.name, constants.Namespace(self.nstype, self.ns))
-
-class Avm2ArrayType(Avm2Type):
+class Avm2VectorType(object):
def __init__(self, itemtype):
self.ITEM = itemtype
@@ -73,25 +44,27 @@
gen.oonewarray(self, 0)
def __str__(self):
- return "%s.<%s>" % (vec_qname, constants.QName(self.ITEM))
+ return "Vector.<%s>" % (IMultiname(self.ITEM))
+
+ at adapter(Avm2VectorType)
+ at implementer(IMultiname)
+def _adapter(self):
+ return TypeName(packagedQName("__AS3__.vec", "Vector"), IMultiname(self.ITEM))
- def multiname(self):
- return constants.TypeName(vec_qname, constants.QName(self.ITEM))
+provideAdapter(_adapter)
-T = Avm2PrimitiveType
-# N = Avm2NamespacedType
+T = Avm2Type
class types:
- void = T('void', constants.null)
+ void = T('*', null)
int = T('int', -1)
uint = T('uint', 0)
bool = T('Boolean', False)
float = T('Number', float('nan'))
string = T('String', "")
- type = T('Class', constants.QName('Class'))
+ type = T('Class', QName('Class'))
object = T('Object', {})
- list = Avm2ArrayType
+ list = Avm2VectorType
dict = T('Object', {})
-# sb = N('StringBuilder', 'pypy.lib')
del T
_lltype_to_cts = {
@@ -106,9 +79,9 @@
ootype.UniChar: types.string,
ootype.Class: types.type,
ootype.String: types.string,
-# ootype.StringBuilder: types.sb,
+ ootype.StringBuilder: types.string,
ootype.Unicode: types.string,
-# ootype.UnicodeBuilder: types.sb,
+ ootype.UnicodeBuilder: types.string,
# maps generic types to their ordinal
ootype.List.SELFTYPE_T: types.list,
@@ -129,22 +102,22 @@
elif isinstance(t, ootype.Instance):
NATIVE_INSTANCE = t._hints.get('NATIVE_INSTANCE', None)
if NATIVE_INSTANCE:
- return Avm2NamespacedType(NATIVE_INSTANCE._name)
+ return Avm2Type.from_string(NATIVE_INSTANCE._name)
else:
name = self.db.pending_class(t)
- return Avm2NamespacedType(name)
+ return Avm2Type.from_string(name)
elif isinstance(t, ootype.Record):
name = self.db.pending_record(t)
- return Avm2NamespacedType(name)
+ return Avm2Type.from_string(name)
elif isinstance(t, ootype.StaticMethod):
delegate = self.db.record_delegate(t)
- return Avm2NamespacedType(delegate)
+ return Avm2Type.from_string(delegate)
elif isinstance(t, (ootype.Array, ootype.List)):
item_type = self.lltype_to_cts(t.ITEM)
return types.list(item_type)
elif isinstance(t, ootype.Dict):
- key_type = self.lltype_to_cts(t._KEYTYPE)
- value_type = self.lltype_to_cts(t._VALUETYPE)
+ #key_type = self.lltype_to_cts(t._KEYTYPE)
+ #value_type = self.lltype_to_cts(t._VALUETYPE)
return types.dict
## elif isinstance(t, ootype.DictItemsIterator):
## key_type = self.lltype_to_cts(t._KEYTYPE)
@@ -170,9 +143,14 @@
func_name = graph.name
namespace = getattr(graph, '_namespace_', None)
if namespace:
- return constants.packagedQName(namespace, func_name)
+ return packagedQName(namespace, func_name)
else:
- return constants.QName(func_name)
+ return QName(func_name)
+
+ def instance_to_qname(self, instance):
+ classname = self.db.class_name(instance)
+ ns, name = classname.rsplit('::', 1)
+ return packagedQName(ns, name)
# def ctor_name(self, t):
# return 'instance void %s::.ctor()' % self.lltype_to_cts(t)
@@ -258,10 +236,10 @@
# else:
# assert False
-def dict_of_void_ll_copy_hack(TYPE, ret_type):
- # XXX: ugly hack to make the ll_copy signature correct when
- # CustomDict is special-cased to DictOfVoid.
- if isinstance(TYPE, ootype.CustomDict) and TYPE._VALUETYPE is ootype.Void:
- return ret_type.typename().replace('Dict`2', 'DictOfVoid`2')
- else:
- return ret_type
+## def dict_of_void_ll_copy_hack(TYPE, ret_type):
+## # XXX: ugly hack to make the ll_copy signature correct when
+## # CustomDict is special-cased to DictOfVoid.
+## if isinstance(TYPE, ootype.CustomDict) and TYPE._VALUETYPE is ootype.Void:
+## return ret_type.typename().replace('Dict`2', 'DictOfVoid`2')
+## else:
+## return ret_type
More information about the Pypy-commit
mailing list