Commits

Jean-Philippe St. Pierre  committed d34a380

I forgot the avm1 module.

  • Participants
  • Parent commits 2b1fcc2
  • Branches avm

Comments (0)

Files changed (76)

File pypy/translator/avm1/.ropeproject/config.py

+# The default ``config.py``
+
+
+def set_prefs(prefs):
+    """This function is called before opening the project"""
+
+    # Specify which files and folders to ignore in the project.
+    # Changes to ignored resources are not added to the history and
+    # VCSs.  Also they are not returned in `Project.get_files()`.
+    # Note that ``?`` and ``*`` match all characters but slashes.
+    # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
+    # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
+    # '.svn': matches 'pkg/.svn' and all of its children
+    # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
+    # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
+    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
+                                  '.hg', '.svn', '_svn', '.git']
+
+    # Specifies which files should be considered python files.  It is
+    # useful when you have scripts inside your project.  Only files
+    # ending with ``.py`` are considered to be python files by
+    # default.
+    #prefs['python_files'] = ['*.py']
+
+    # Custom source folders:  By default rope searches the project
+    # for finding source folders (folders that should be searched
+    # for finding modules).  You can add paths to that list.  Note
+    # that rope guesses project source folders correctly most of the
+    # time; use this if you have any problems.
+    # The folders should be relative to project root and use '/' for
+    # separating folders regardless of the platform rope is running on.
+    # 'src/my_source_folder' for instance.
+    #prefs.add('source_folders', 'src')
+
+    # You can extend python path for looking up modules
+    #prefs.add('python_path', '~/python/')
+
+    # Should rope save object information or not.
+    prefs['save_objectdb'] = True
+    prefs['compress_objectdb'] = False
+
+    # If `True`, rope analyzes each module when it is being saved.
+    prefs['automatic_soa'] = True
+    # The depth of calls to follow in static object analysis
+    prefs['soa_followed_calls'] = 0
+
+    # If `False` when running modules or unit tests "dynamic object
+    # analysis" is turned off.  This makes them much faster.
+    prefs['perform_doa'] = True
+
+    # Rope can check the validity of its object DB when running.
+    prefs['validate_objectdb'] = True
+
+    # How many undos to hold?
+    prefs['max_history_items'] = 32
+
+    # Shows whether to save history across sessions.
+    prefs['save_history'] = True
+    prefs['compress_history'] = False
+
+    # Set the number spaces used for indenting.  According to
+    # :PEP:`8`, it is best to use 4 spaces.  Since most of rope's
+    # unit-tests use 4 spaces it is more reliable, too.
+    prefs['indent_size'] = 4
+
+    # Builtin and c-extension modules that are allowed to be imported
+    # and inspected by rope.
+    prefs['extension_modules'] = []
+
+    # Add all standard c-extensions to extension_modules list.
+    prefs['import_dynload_stdmods'] = True
+
+    # If `True` modules with syntax errors are considered to be empty.
+    # The default value is `False`; When `False` syntax errors raise
+    # `rope.base.exceptions.ModuleSyntaxError` exception.
+    prefs['ignore_syntax_errors'] = False
+
+    # If `True`, rope ignores unresolvable imports.  Otherwise, they
+    # appear in the importing namespace.
+    prefs['ignore_bad_imports'] = False
+
+
+def project_opened(project):
+    """This function is called after opening the project"""
+    # Do whatever you like here!

File pypy/translator/avm1/.ropeproject/globalnames

+�}qUavm1q]q(UActionStringEqualsqUActionDefineLocalqUActionMultiplyqUActionCallFunctionqUActionShiftLeftqUActionSetVariableq	UActionAsciiToCharq
+UActionGetPropertyq
+ActionStopqU	ActionAndqUBranchingActionBaseqU
+ActionLessq
+ActionJumpq$UActionNewObjectq%U	Undefinedq&UActionCallMethodq'UActionMBCharToAsciiq(U
+ActionWithqPU
+ActionSwapqQU
+ActionPushqcUActionToIntegerqdUActionTypedEqualsqeU
+ActionCallqfUActionStringLessqgUActionSetMemberqhU
+ActionPlayqiU	DataTypesqjUActionStringLengthqkU

File pypy/translator/avm1/.ropeproject/history

+�]q(]q]qe.

File pypy/translator/avm1/.ropeproject/objectdb

+�}qUavm1.pyq}qUBlock.__init__qcrope.base.oi.memorydb
+ScopeInfo
+q)�q}qUinstanceqUdefinedq	hUActionDefineFunction2q
+��Uunknown�q

File pypy/translator/avm1/__init__.py

Empty file added.

File pypy/translator/avm1/authoring.py

+
+from pypy.translator.avm.tags import ShapeWithStyle
+from pypy.translator.avm.records import StyleChangeRecord, CurvedEdgeRecord, StraightEdgeRecord
+
+class Circle(object):
+
+    def __init__(self, x, y, radius, linestyle, fillstyle0, fillstyle1):
+        self.x = x
+        self.y = y
+        self.radius = radius
+        self.linestyle = linestyle
+        self.fillstyle0 = fillstyle0
+        self.fillstyle1 = fillstyle1
+
+    def to_shape(self):
+        shape = ShapeWithStyle()
+
+        if self.linestyle: shape.add_line_style(self.linestyle)
+        if self.fillstyle0: shape.add_fill_style(self.fillstyle0)
+        if self.fillstyle1: shape.add_fill_style(self.fillstyle1)
+
+        # Precalculated:
+        # math.tan(math.radians(22.5)) = 0.41421356237309503
+        # math.sin(math.radians(45))   = 0.70710678118654746
+        
+        c = self.radius * 0.41421356237309503
+        a = self.radius * 0.70710678118654746 - c
+
+        shape.add_shape_record(StyleChangeRecord(self.x + self.radius, self.y, self.linestyle, self.fillstyle0, self.fillstyle1))
+        # 0 to PI/2
+        shape.add_shape_record(CurvedEdgeRecord(0, -c, -a, -a))
+        shape.add_shape_record(CurvedEdgeRecord(-a, -a, -c, 0))
+
+        # PI/2 to PI
+        shape.add_shape_record(CurvedEdgeRecord(-c, 0, -a, a))
+        shape.add_shape_record(CurvedEdgeRecord(-a, a, 0, c))
+
+        # PI to 3PI/2
+        shape.add_shape_record(CurvedEdgeRecord(0, c, a, a))
+        shape.add_shape_record(CurvedEdgeRecord(a, a, c, 0))
+
+        # 3PI/2 to 2PI
+        shape.add_shape_record(CurvedEdgeRecord(c, 0, a, -a))
+        shape.add_shape_record(CurvedEdgeRecord(a, -a, 0, -c))
+
+        return shape

File pypy/translator/avm1/avm1.py

+
+# AVM1 = ActionScript Virtual Machine 1
+# Used for ActionScript 1 and 2
+
+from pypy.translator.avm1.util import BitStream
+from collections import namedtuple
+import struct
+
+DataType = namedtuple("DataType", "id name size")
+
+STRING      = DataType(0, "string", "Z")
+FLOAT       = DataType(1, "float", "f")
+NULL        = DataType(2, "null", "!")
+UNDEFINED   = DataType(3, "undefined", "!")
+REGISTER    = DataType(4, "register", "B")
+BOOLEAN     = DataType(5, "boolean", "B")
+DOUBLE      = DataType(6, "double", "d")
+INTEGER     = DataType(7, "integer", "l")
+CONSTANT8   = DataType(8, "constant 8", "B")
+CONSTANT16  = DataType(9, "constant 16", "H")
+
+preload = dict(this="preload_this",
+               arguments="preload_args",
+               super="preload_super",
+               _root="preload_root",
+               _parent="preload_parent",
+               _global="preload_global")
+
+class Action(object):
+    
+    ACTION_NAME = "NotImplemented"
+    ACTION_ID = 0x00
+
+    offset = 0
+    label_name = ""
+    
+    def serialize(self):
+        inner_data = self.gen_data()
+        outer_data = self.gen_outer_data()
+        header = struct.pack("<BH", self.ACTION_ID, len(inner_data))
+        return header + inner_data + outer_data
+    
+    def __len__(self):
+        return 6 + len(self.gen_data()) + len(self.gen_outer_data())
+    
+    def gen_data(self):
+        return ""
+
+    def gen_outer_data(self):
+        return ""
+    
+    def get_block_props_early(self, block):
+        pass
+
+    def get_block_props_late(self, block):
+        pass
+
+class RegisterError(IndexError):
+    pass
+
+class SealedBlockError(Exception):
+    pass
+
+class ActionConstantPool(Action):
+    ACTION_NAME = "ActionConstantPool"
+    ACTION_ID = 0x88
+
+    def __init__(self, *args):
+        self.pool = []
+        for string in args:
+            if not string in self.pool:
+                self.pool.append(args)
+
+    def add_constant(self, string):
+        if not string in self.pool:
+            self.pool.append(string)
+            return len(self.pool)-1
+        return self.pool.index(string)
+
+    def serialize(self):
+        if len(self.pool) == 0:
+            return ""
+        else:
+            return super(ActionConstantPool, self).serialize()
+    
+    def gen_data(self):
+        return struct.pack("H", len(self.pool)) + "\0".join(self.pool) + "\0"
+
+class Block(object):
+
+    AUTO_LABEL_TEMPLATE = "label%d"
+    MAX_REGISTERS = 4
+    FUNCTION_TYPE = 0
+    
+    def __init__(self, toplevel, insert_end=False):
+        if toplevel:
+            self.constants = toplevel.constants
+            self.registers = toplevel.registers
+        else:
+            self.constants = ActionConstantPool()
+            self.registers = []
+        
+        self.code = ""
+        self._sealed = False
+        self.insert_end = insert_end
+        
+        self.labels = {}
+        self.branch_blocks = []
+        self.actions = []
+        
+        self.current_offset = 0
+        self.label_count = 0
+    
+    def get_free_register(self):
+        if None in self.registers:
+            return self.registers.index(None)
+        elif len(self.registers) < self.MAX_REGISTERS:
+            self.registers.append(None)
+            return len(self.registers)-1
+        else:
+            raise RegisterError("maximum number of registers in use")
+
+    def store_register(self, value, index=-1):
+        if value in self.registers:
+            index = self.registers.index(value)
+            return index
+        if index < 1:
+            index = self.get_free_register()
+        self.registers[index] = value
+        return index
+    
+    def find_register(self, value):
+        if value in self.registers:
+            return self.registers.index(value)
+        return -1
+    
+    def free_register(self, index):
+        self.registers[index] = None
+    
+    def __len__(self):
+        return self.current_offset + (2 if self.insert_end else 0)
+
+    def seal(self):
+        self._sealed = True
+        return len(self)
+
+    @property
+    def sealed(self):
+        return self._sealed
+    
+    def add_action(self, action):
+        if self._sealed:
+            raise SealedBlockError("Block is sealed. Cannot add new actions")
+
+        assert isinstance(action, Action)
+        
+        self.code = "" # Dirty the code.
+        action.offset = self.current_offset
+        action.get_block_props_early(self)
+        
+        # Do some early optimizations. Combine two pushes into one.
+        if len(self.actions) > 0 and action.ACTION_NAME == "ActionPush" and self.actions[-1].ACTION_NAME == "ActionPush":
+            old_action = self.actions[-1]
+            old_len = len(old_action)
+            self.actions[-1].values.extend(action.values)
+            self.current_offset += len(old_action) - old_len
+            return old_action
+
+        # Two nots negate. Take them out.
+        if len(self.actions) > 0 and action.ACTION_NAME == "ActionNot" and self.actions[-1].ACTION_NAME == "ActionNot":
+            self.actions.pop()
+            self.current_offset -= 1 # len(ShortAction) is 1
+            return None
+            
+        if not isinstance(action, Block): # Don't add block length until we've finalized.
+            self.current_offset += len(action)
+        
+        self.actions.append(action)
+        return action
+    
+    def serialize(self):
+        if not self._sealed:
+            raise SealedBlockError("Block must be sealed before it can be serialized")
+        if len(self.code) > 0:
+            return self.code
+        bytes = []
+        block_offset = 0
+        for action in self.actions:
+            if isinstance(action, Block):
+                block_offset += len(action)
+            action.offset += block_offset
+            action.get_block_props_late(self)
+            bytes += action.serialize()
+        if self.insert_end:
+            bytes += "\0"
+        self.code = "".join(bytes)
+        return self.code
+
+    def new_label(self):
+        self.label_count += 1
+        name = Block.AUTO_LABEL_TEMPLATE % self.label_count
+        self.labels[name] = -1
+        return name
+        
+    def set_label_here(self, name):
+        self.labels[name] = self.current_offset
+
+    def new_label_here(self):
+        name = self.new_label()
+        self.labels[name] = self.current_offset
+        return name
+
+class ActionCall(Action):
+    ACTION_NAME = "ActionCall"
+    ACTION_ID = 0x9e
+
+class ActionDefineFunction(Action, Block):
+    ACTION_NAME = "ActionDefineFunction"
+    ACTION_ID = 0x9b
+    FUNCTION_TYPE = 1
+
+    def __init__(self, toplevel, name, parameters):
+        Block.__init__(self, toplevel, False)
+        self.function_name = name
+        self.params = parameters
+
+    def gen_data(self):
+        self.block_data = Block.serialize(self)
+        bytes = [self.function_name, "\0", struct.pack("H", len(self.params))]
+        bytes += [p + "\0" for p in self.params]
+        bytes += struct.pack("H", len(self.block_data))
+        return "".join(bytes)
+
+    def gen_outer_data(self):
+        return self.block_data
+
+class ActionDefineFunction2(Action, Block):
+    ACTION_NAME = "ActionDefineFunction2"
+    ACTION_ID = 0x8e
+    MAX_REGISTERS = 256
+    FUNCTION_TYPE = 2
+
+    def __init__(self, toplevel, name, parameters):
+        Block.__init__(self, toplevel, False)
+        self.function_name = name
+        self.params = parameters
+        self.preload_register_count = 1 # Start at 1.
+        
+        # Flags
+        self.registers        = [None]
+        self.preload_parent   = False
+        self.preload_root     = False
+        self.suppress_super   = True
+        self.preload_super    = False
+        self.suppress_args    = True
+        self.preload_args     = False
+        self.suppress_this    = True
+        self.preload_this     = False
+        self.preload_global   = False
+        self.eval_flags()
+
+        for name in parameters:
+            self.registers.append(name)
+        
+    def eval_flags(self):
+        
+        # According to the docs, this is the order of register allocation.
+        if self.preload_this and "this" not in self.registers:
+            self.suppress_this = False
+            self.registers.insert(1, "this")
+            
+        if self.preload_args and "arguments" not in self.registers:
+            self.suppress_args = False
+            self.registers.insert(2, "arguments")
+            
+        if self.preload_super and "super" not in self.registers:
+            self.suppress_super = False
+            self.registers.insert(3, "super")
+            
+        if self.preload_root and "_root" not in self.registers:
+            self.registers.insert(4, "_root")
+            
+        if self.preload_parent and "_parent" not in self.registers:
+            self.registers.insert(5, "_parent")
+        
+        if self.preload_global and "_global" not in self.registers:
+            self.registers.insert(6, "_global")
+        
+    def gen_data(self):
+
+        bits = BitStream()
+        bits.write_bit(self.preload_parent)
+        bits.write_bit(self.preload_root)
+        bits.write_bit(self.suppress_super)
+        bits.write_bit(self.preload_super)
+        bits.write_bit(self.suppress_args)
+        bits.write_bit(self.preload_args)
+        bits.write_bit(self.suppress_this)
+        bits.write_bit(self.preload_this)
+        bits.zero_fill(7) # skip over 7 Reserved bits
+        bits.write_bit(self.preload_global)
+        
+        self.block_data = Block.serialize(self)
+        bytes = [self.function_name, "\0",
+                 struct.pack("HB", len(self.params), len(self.registers)),
+                 bits.serialize()]
+        
+        for name in self.params:
+            bytes += [chr(self.registers.index(name)), name, "\0"]
+        
+        bytes += [struct.pack("H", len(self.block_data))]
+        return "".join(bytes)
+
+    def gen_outer_data(self):
+        return self.block_data
+
+class ActionGetURL(Action):
+    ACTION_NAME = "ActionGetURL"
+    ACTION_ID = 0x83
+
+    def __init__(self, url, target=""):
+        self.url = url
+        self.target = target
+
+    def gen_data(self):
+        return "%s\0%s\0" % (self.url, self.target)
+
+class ActionGetURL2(Action):
+    ACTION_NAME = "ActionGetURL2"
+    ACTION_ID = 0x9a
+
+    METHODS = {"": 0, "GET": 1, "POST": 2}
+
+    def __init__(self, method, load_target=False, load_variables=False):
+        self.method = method
+        self.load_target = load_target
+        self.load_variables = load_variables
+
+    def gen_data(self):
+        # The SWF 10 spec document is incorrect.
+        # method goes at the low end
+        # and the flags at the high end
+        bits = BitStream()
+        bits.write_bit(self.load_variables)
+        bits.write_bit(self.load_target)
+        bits.zero_fill(4)
+        bits.write_int_value(self.METHODS[self.method.upper()], 2)
+        return bits.serialize()
+
+class ActionGotoFrame(Action):
+    ACTION_NAME = "ActionGotoFrame"
+    ACTION_ID = 0x81
+
+    def __init__(self, index):
+        self.index = index
+
+    def gen_data(self):
+        return struct.pack("H", self.index)
+
+class ActionGotoFrame2(Action):
+    ACTION_NAME = "ActionGotoFrame2"
+    ACTION_ID = 0x9f
+
+    def __init__(self, play=False, scene_bias=0):
+        self.play = play
+        self.scene_bias = scene_bias
+
+    def gen_data(self):
+        bits = BitStream()
+        bits.zero_fill(6)
+        bits.write_bit(self.scene_bias > 0)
+        bits.write_bit(self.play)
+
+        if self.scene_bias > 0:
+            return bits.serialize() + struct.pack("<H", self.scene_bias)
+
+        return bits.serialize()
+
+class ActionGotoLabel(Action):
+    ACTION_NAME = "ActionGotoLabel"
+    ACTION_ID = 0x81
+
+    def __init__(self, label_name):
+        self.label_name = label_name
+
+    def serialize(self):
+        return self.label_name + "\0"
+
+class BranchingActionBase(Action):
+
+    def __init__(self, branch):
+        if isinstance(branch, str):
+            self.branch_label = branch
+            self.branch_offset = 0
+        elif isinstance(branch, int):
+            self.branch_label = None
+            self.branch_offset = branch
+
+    def get_block_props_late(self, block):
+        if len(self.branch_label) > 0:
+            print "BRANCH:", self.branch_label, block.labels[self.branch_label], self.offset
+            self.branch_offset = block.labels[self.branch_label] - self.offset - len(self)
+
+    def gen_data(self):
+        return struct.pack("h", self.branch_offset)
+
+class ActionJump(BranchingActionBase):
+    ACTION_NAME = "ActionJump"
+    ACTION_ID = 0x99
+
+class ActionIf(BranchingActionBase):
+    ACTION_NAME = "ActionIf"
+    ACTION_ID = 0x9d
+
+class ActionPush(Action):
+    ACTION_NAME = "ActionPush"
+    ACTION_ID = 0x96
+
+    USE_CONSTANTS = False
+    
+    def __init__(self, *args):
+        self.values = []
+        self.add_element(*args)
+    
+    def add_element(self, element):
+        if hasattr(element, "__iter__") and not isinstance(element, (basestring, tuple)):
+            for t in element:
+                self.add_element(t)
+        else:
+            if element in (NULL, UNDEFINED):
+                element = (None, element)
+            assert isinstance(element, tuple)
+            self.values.append(element)
+        
+    def get_block_props_early(self, block):
+        if not ActionPush.USE_CONSTANTS: return
+        for index, (value, type) in enumerate(self.values):
+            if type == STRING:
+                constant_index = block.constants.add_constant(value)
+                self.values[index] = (constant_index, CONSTANT8 if constant_index < 256 else CONSTANT16)
+    
+    def gen_data(self):
+        bytes = []
+        for value, type in self.values:
+            bytes += chr(type.id)
+            if type.size == "Z":
+                bytes += [value, "\0"]
+            elif type.size != "!":
+                bytes += struct.pack("<"+type.size, value)
+        return "".join(bytes)
+
+class ActionSetTarget(Action):
+    ACTION_NAME = "ActionSetTarget"
+    ACTION_ID = 0x8b
+
+    def __init__(self, target):
+        self.target = target
+
+    def gen_data(self):
+        return self.target + "\0"
+
+class ActionStoreRegister(Action):
+    ACTION_NAME = "ActionStoreRegister"
+    ACTION_ID = 0x87
+
+    def __init__(self, index):
+        self.index = index
+
+    def gen_data(self):
+        return chr(self.index)
+
+class ActionTry(Action):
+    ACTION_NAME = "ActionTry"
+    ACTION_ID = 0x8f
+
+    def __init__(self, catch_object, try_block=None, catch_block=None, finally_block=None):
+
+        self.catch_object = catch_object
+        
+        self.try_block = try_block or Block()
+        self.catch_block = catch_block or Block()
+        self.finally_block = finally_block or Block()
+
+    def gen_data(self):
+        has_catch_block = len(self.catch_block.actions) > 0
+        bits = BitStream()
+        bits.zero_fill(5)
+        bits.write_bit(isinstance(self.catch_object, int))
+        bits.write_bit(len(self.finally_block.actions) > 0)
+        bits.write_bit(has_catch_block)
+        bytes = [bits.serialize()]
+        bytes += [struct.pack("3H",
+                              len(self.try_block) + 5 if has_catch_block else 0,
+                              len(self.catch_block),
+                              len(self.finally_block))]
+        bytes += [self.catch_object, "" if isinstance(self.catch_object, int) else "\0"]
+        return bytes
+
+    def gen_outer_data(self):
+        bytes = [self.try_block.serialize()]
+        if len(self.catch_block.actions) > 0:
+            bytes += ActionJump(len(self.catch_block)).serialize()
+            bytes += self.catch_block.serialize()
+        bytes += self.finally_block.serialize()
+
+class ActionWaitForFrame(Action):
+    ACTION_NAME = "ActionWaitForFrame"
+    ACTION_ID = 0x8a
+
+    def __init__(self, index, skip_count=0):
+        self.index = index
+        self.skip_count = skip_count
+
+    def gen_data(self):
+        return struct.pack("HB", self.index, self.skip_count)
+    
+class ActionWaitForFrame2(Action):
+    ACTION_NAME = "ActionWaitForFrame2"
+    ACTION_ID = 0x8d
+
+    def __init__(self, skip_count=0):
+        self.skip_count = skip_count
+
+    def gen_data(self):
+        return chr(self.skip_count)
+
+class ActionWith(Action):
+    ACTION_NAME = "ActionWith"
+    ACTION_ID = 0x94
+    
+    def __init__(self, with_block):
+        self.block = with_block or Block()
+    
+    def gen_data(self):
+        return struct.pack("H", len(self.block)) + self.block.serialize()
+
+SHORT_ACTIONS = {}
+
+# turns NextFrame into next_frame
+def make_underlined(name):
+    return ''.join('_' + c.lower() if c.isupper() else c for c in name)[1:]
+
+def make_short_action(value, name, push_count=0):
+    
+    def __len__(self):
+        return 1 # 1 (Action ID)
+    
+    def serialize(self):
+        return chr(self.ACTION_ID)
+    
+    act = type(name, (Action,), dict(ACTION_ID=value, ACTION_NAME=name, push_count=push_count,
+                                     __len__=__len__, serialize=serialize))
+
+    SHORT_ACTIONS[name[6:].lower()] = act
+    SHORT_ACTIONS[make_underlined(name[6:])] = act
+
+    return act
+
+ActionNextFrame           = make_short_action(0x04, "ActionNextFrame")
+ActionPreviousFrame       = make_short_action(0x05, "ActionPreviousFrame")
+ActionPlay                = make_short_action(0x06, "ActionPlay")
+ActionStop                = make_short_action(0x07, "ActionStop")
+ActionToggleQuality       = make_short_action(0x08, "ActionToggleQuality")
+ActionStopSounds          = make_short_action(0x09, "ActionStopSounds")
+ActionAdd                 = make_short_action(0x0a, "ActionAdd", -1)
+ActionSubtract            = make_short_action(0x0b, "ActionSubtract", -1)
+ActionMultiply            = make_short_action(0x0c, "ActionMultiply", -1)
+ActionDivide              = make_short_action(0x0d, "ActionDivide", -1)
+ActionEquals              = make_short_action(0x0e, "ActionEquals", -1)
+ActionLess                = make_short_action(0x0f, "ActionLess", -1)
+ActionAnd                 = make_short_action(0x10, "ActionAnd", -1)
+ActionOr                  = make_short_action(0x11, "ActionOr", -1)
+ActionNot                 = make_short_action(0x12, "ActionNot")
+ActionStringEquals        = make_short_action(0x13, "ActionStringEquals", -1)
+ActionStringLength        = make_short_action(0x14, "ActionStringLength")
+ActionStringExtract       = make_short_action(0x15, "ActionStringExtract")
+ActionPop                 = make_short_action(0x17, "ActionPop", -1)
+ActionToInteger           = make_short_action(0x18, "ActionToInteger")
+ActionGetVariable         = make_short_action(0x1c, "ActionGetVariable")
+ActionSetVariable         = make_short_action(0x1d, "ActionSetVariable", -2)
+ActionSetTarget2          = make_short_action(0x20, "ActionSetTarget2")
+ActionStringAdd           = make_short_action(0x21, "ActionStringAdd", -1)
+ActionGetProperty         = make_short_action(0x22, "ActionGetProperty", -1)
+ActionSetProperty         = make_short_action(0x23, "ActionSetProperty", -3)
+ActionCloneSprite         = make_short_action(0x24, "ActionCloneSprite")
+ActionRemoveSprite        = make_short_action(0x25, "ActionRemoveSprite")
+ActionTrace               = make_short_action(0x26, "ActionTrace", -1)
+ActionStartDrag           = make_short_action(0x27, "ActionStartDrag")
+ActionEndDrag             = make_short_action(0x28, "ActionEndDrag")
+ActionStringLess          = make_short_action(0x29, "ActionStringLess")
+ActionThrow               = make_short_action(0x2a, "ActionThrow")
+ActionCastOp              = make_short_action(0x2b, "ActionCastOp")
+ActionImplementsOp        = make_short_action(0x2c, "ActionImplementsOp")
+ActionRandomNumber        = make_short_action(0x30, "ActionRandomNumber")
+ActionMBStringLength      = make_short_action(0x31, "ActionMBStringLength")
+ActionCharToAscii         = make_short_action(0x32, "ActionCharToAscii")
+ActionAsciiToChar         = make_short_action(0x33, "ActionAsciiToChar")
+ActionGetTime             = make_short_action(0x34, "ActionGetTime")
+ActionMBStringExtract     = make_short_action(0x35, "ActionMBStringExtract")
+ActionMBCharToAscii       = make_short_action(0x36, "ActionMBCharToAscii")
+ActionMBAsciiToChar       = make_short_action(0x37, "ActionMBAsciiToChar")
+ActionDelVar              = make_short_action(0x3a, "ActionDelVar")
+ActionDelThreadVars       = make_short_action(0x3b, "ActionDelThreadVars")
+ActionDefineLocalVal      = make_short_action(0x3c, "ActionDefineLocalVal")
+ActionCallFunction        = make_short_action(0x3d, "ActionCallFunction")
+ActionReturn              = make_short_action(0x3e, "ActionReturn")
+ActionModulo              = make_short_action(0x3f, "ActionModulo", -1)
+ActionNewObject           = make_short_action(0x40, "ActionNewObject")
+ActionDefineLocal         = make_short_action(0x41, "ActionDefineLocal")
+ActionInitArray           = make_short_action(0x42, "ActionInitArray")
+ActionInitObject          = make_short_action(0x43, "ActionInitObject")
+ActionTypeof              = make_short_action(0x44, "ActionTypeof")
+ActionGetTargetPath       = make_short_action(0x45, "ActionGetTargetPath")
+ActionEnumerate           = make_short_action(0x46, "ActionEnumerate")
+ActionTypedAdd            = make_short_action(0x47, "ActionTypedAdd", -1)
+ActionTypedLess           = make_short_action(0x48, "ActionTypedLess", -1)
+ActionTypedEquals         = make_short_action(0x49, "ActionTypedEquals", -1)
+ActionConvertToNumber     = make_short_action(0x4a, "ActionConvertToNumber")
+ActionConvertToString     = make_short_action(0x4b, "ActionConvertToString")
+ActionDuplicate           = make_short_action(0x4c, "ActionDuplicate", 1)
+ActionSwap                = make_short_action(0x4d, "ActionSwap")
+ActionGetMember           = make_short_action(0x4e, "ActionGetMember", -1)
+ActionSetMember           = make_short_action(0x4f, "ActionSetMember", -3)
+ActionIncrement           = make_short_action(0x50, "ActionIncrement")
+ActionDecrement           = make_short_action(0x51, "ActionDecrement")
+ActionCallMethod          = make_short_action(0x52, "ActionCallMethod")
+ActionCallNewMethod       = make_short_action(0x53, "ActionCallNewMethod")
+ActionBitAnd              = make_short_action(0x60, "ActionBitAnd", -1)
+ActionBitOr               = make_short_action(0x61, "ActionBitOr", -1)
+ActionBitXor              = make_short_action(0x62, "ActionBitXor", -1)
+ActionShiftLeft           = make_short_action(0x63, "ActionShiftLeft", -1)
+ActionShiftRight          = make_short_action(0x64, "ActionShiftRight", -1)
+ActionShiftUnsigned       = make_short_action(0x65, "ActionShiftUnsigned", -1)
+ActionStrictEquals        = make_short_action(0x66, "ActionStrictEquals", -1)
+ActionGreater             = make_short_action(0x67, "ActionGreater", -1)
+ActionStringGreater       = make_short_action(0x68, "ActionStringGreater", -1)
+ActionExtends             = make_short_action(0x69, "ActionExtends")

File pypy/translator/avm1/avm1gen.py

+
+""" backend generator routines
+"""
+
+from pypy.objspace.flow import model as flowmodel
+from pypy.rpython.ootypesystem import ootype
+from pypy.translator.avm1 import avm1, types_ as types
+from pypy.translator.oosupport.treebuilder import SubOperation
+from pypy.translator.oosupport.metavm import Generator as OOGenerator, InstructionList
+from pypy.translator.oosupport.constant import push_constant
+from collections import namedtuple
+
+ClassName = namedtuple("ClassName", "namespace classname")
+Scope = namedtuple("Scope", "block parent callback islabel")
+
+def render_sub_op(sub_op, db, generator):
+    op = sub_op.op
+    instr_list = db.genoo.opcodes.get(op.opname, None)
+    assert instr_list is not None, 'Unknown opcode: %s ' % op
+    assert isinstance(instr_list, InstructionList)
+    # Don't do that, please
+    #assert instr_list[-1] is StoreResult, "Cannot inline an operation that doesn't store the result"
+
+    # record that we know about the type of result and args
+    db.cts.lltype_to_cts(op.result.concretetype)
+    for v in op.args:
+        db.cts.lltype_to_cts(v.concretetype)
+
+    instr_list = InstructionList(instr_list[:-1]) # leave the value on the stack if this is a sub-op
+    instr_list.render(generator, op)
+    # now the value is on the stack
+
+def make_variable(name):
+    if isinstance(name, Variable):
+        return name
+    return Variable(name)
+
+class StackDummy(object):
+    def __init__(self, name):
+        self.name = name
+
+class Variable(StackDummy):
+    def __str__(self):
+        return 'Variable(name="%s")' % self.name
+    __repr__ = __str__
+
+    def __add__(self, other):
+        if isinstance(other, StackDummy):
+            other = other.name
+        return Variable("ADD %r %r" % (self.name, other))
+
+    def __radd__(self, other):
+        return other + self
+
+class ScriptObject(StackDummy):
+    pass
+    
+class Function(StackDummy):
+    pass
+
+class AVM1Gen(OOGenerator):
+    """ AVM1 'assembler' generator routines """
+    
+    def __init__(self, block=None):
+        self.stack = []
+        self.namespaces = {}
+        self.block = block or avm1.Block(None, True)
+        self.scope = Scope(self.block, None, None, False)
+        self.action(self.block.constants)
+        self.ilasm = self
+    
+    def new_label(self):
+        return self.fn_block.new_label()
+
+    def push_stack(self, *values):
+        print "PUSHSTACK:", values
+        for element in values:
+            self.stack.append(element)
+
+    @property
+    def fn_block(self):
+        if self.scope.islabel:
+            return self.scope.parent.block
+        return self.scope.block
+    
+    def pop_stack(self, n=1):
+        v = [self.stack.pop() for i in xrange(n)]
+        print "POPSTACK:", v
+        return v
+    
+    def store_register(self, name, index=-1):
+        index = self.fn_block.store_register(name, index)
+        self.action(avm1.ActionStoreRegister(index))
+        return index
+    
+    def find_register(self, name):
+        print "FINDING REGISTER:", name
+        return self.fn_block.find_register(name)
+    
+    def action(self, action):
+        return self.scope.block.add_action(action)
+    
+    def set_label(self, label):
+        print "SETLABEL:", label
+        
+        if self.scope.islabel:
+            self.exit_scope()
+            
+        label, block = self._branch_start(label)
+        self.enter_scope(block, islabel=True)   
+    
+    def enter_scope(self, new_code_obj, exit_callback=None, islabel=False):
+        print "ENTERSCOPE"
+        self.scope = Scope(new_code_obj, self.scope, exit_callback, islabel)
+    
+    def in_function(self):
+        return self.fn_block.FUNCTION_TYPE
+    
+    def exit_scope(self):
+        print "EXITSCOPE"
+        block_len = self.finalize_block(self.scope.block)
+        exit_callback = self.scope.callback
+        
+        # Go up to the parent scope.
+        self.scope = self.scope.parent
+        
+        self.scope.block.current_offset += block_len
+        if exit_callback is not None:
+            exit_callback()
+
+    def finalize_block(self, block):
+        for label, branch_block in block.branch_blocks:
+            if not branch_block.sealed:
+                branch_block.seal()
+            
+            # Set the label.
+            block.labels[label] = block.current_offset
+
+            print label, block.current_offset
+            
+            # Add the actions, which updates current_offset
+            for act in branch_block.actions:
+
+                block.add_action(act)
+        return block.seal()
+
+    # def begin_namespace(self, _namespace):
+    #     n = _namespace.split('.')
+    #     namespace = self.namespaces
+    #     if n[0] not in self.namespaces:
+    #         self.namespaces[n[0]] = {}
+    #         self.push_const(n[0])
+    #         self.init_object()
+    #         self.set_variable()
+    #     self.push_var(n[0])
+    #     for ns in n[1:]:
+    #         if not ns in namespace:
+    #             namespace[ns] = {}
+    #             namespace = namespace[ns]
+    #             self.push_const(ns)
+    #             self.init_object()
+    #             self.set_member()
+    
+    def begin_function(self, name, arglist):
+        self.enter_scope(self.action(avm1.ActionDefineFunction2(self.block, name, arglist)))
+        
+    def begin_static_method(self, function_name, _class, arglist):
+        def exit_callback(block):
+            self.set_member()
+        self.load(_class)
+        self.push_const(function_name)
+        self.enter_scope(self.action(avm1.ActionDefineFunction2(self.block, "", arglist, 0)), exit_callback)
+        self.push_stack(Function(function_name))
+
+    def begin_method(self, function_name, _class, arglist):
+        def exit_callback(block):
+            self.set_member()
+        self.load(_class)
+        self.push_const("prototype")
+        self.get_member()
+        self.push_const(function_name)
+        self.enter_scope(self.action(avm1.ActionDefineFunction2(self.block, "", arglist, 0)), exit_callback)
+        self.push_stack(Function(function_name))
+    
+    def set_variable(self):
+        value, name = self.pop_stack(2)
+        print "SETVARIABLE: %r = %r" % (name, value)
+        if isinstance(name, Variable):
+            name = name.name
+        assert isinstance(name, basestring)
+        if self.find_register(name) >= 0 and self.in_function() == 2:
+            self.store_register(name)
+        self.action(avm1.ActionSetVariable())
+        
+    def get_variable(self):
+        name, = self.pop_stack()
+        print "GETVARIABLE:", name
+        self.action(avm1.ActionGetVariable())
+        self.push_stack(make_variable(name))
+    
+    def set_member(self):
+        self.action(avm1.ActionSetMember())
+        value, name, obj = self.pop_stack(3)
+        print "SETMEMBER: %s.%s = %r" % (obj, name, value)
+        
+    def get_member(self):
+        self.action(avm1.ActionGetMember())
+        name, obj = self.pop_stack(2)
+        print "GETMEMBER:", name, obj
+        self.push_stack(Variable("%s.%s" % (obj, name)))
+        
+    def push_reg_index(self, index):
+        self.action(avm1.ActionPush((index, avm1.REGISTER)))
+    
+    def push_arg(self, v):
+        assert self.in_function() > 0, "avm1gen::push_arg called while not in function scope."
+        self.push_local(v)
+    
+#    def push_value(self, v):
+#        self.action(avm1.ActionPush(v.name))
+
+    def push_var(self, v):
+        k = self.find_register(v)
+        print k
+        if k >= 0:
+            self.push_stack(Variable(v))
+            self.push_reg_index(k)
+        else:
+            if self.in_function() == 2:
+                if v in avm1.preload:
+                    setattr(self.scope.block, avm1.preload[v])
+                    self.scope.block.eval_flags()
+                    return self.push_var(v)
+            self.push_const(v)
+            self.get_variable()
+            if self.in_function() == 2:
+                self.store_register(v)
+
+    def push_this(self):
+        self.push_var("this")
+    
+    def push_local(self, v):
+        self.push_var(v.name)
+        
+    def push_const(self, *args):
+        self.push_stack(*args)
+        self.action(avm1.ActionPush(types.pytype_to_avm1(v) for v in args))
+        
+    def return_stmt(self):
+        print "RETURNSTMT"
+        self.pop_stack()
+        self.action(avm1.ActionReturn())
+
+    def swap(self):
+        a, b = self.pop_stack(2)
+        self.push_stack(b, a)
+        self.action(avm1.ActionSwap())
+    
+    def is_equal(self, value=None):
+        if value is not None:
+            self.push_const(value)
+        self.action(avm1.ActionEquals())
+        self.pop_stack(2)
+
+    def is_not_equal(self, value=None):
+        self.is_equal(value)
+        self.action(avm1.ActionNot())
+        self.pop_stack(2)
+    
+    def init_object(self, members={}):
+        self.load(members.items())
+        self.push_const(len(members))
+        self.action(avm1.ActionInitObject())
+        self.pop_stack(self.pop_stack()[0])
+        self.push_stack(ScriptObject("object"))
+
+    def init_array(self, members=[]):
+        self.load(members)
+        self.push_const(len(members))
+        self.action(avm1.ActionInitArray())
+        self.pop_stack(self.pop_stack()[0])
+        self.push_stack(ScriptObject("array"))
+
+    # Assumes the args and number of args are on the stack.
+    def call_function(self, func_name):
+        self.push_const(func_name)
+        self.action(avm1.ActionCallFunction())
+        name, nargs = self.pop_stack()
+        self.pop_stack(nargs)
+        self.push_stack(Variable("%s_RETURN" % func_name))
+    
+    def call_function_constargs(self, func_name, *args):
+        p = self.push_const(*reversed((func_name, len(args))+args))
+        self.action(avm1.ActionCallFunction())
+        self.pop_stack(2+len(args))
+        self.push_stack(Variable("%s_RETURN" % func_name))
+        
+    # Assumes the args and number of args and ScriptObject are on the stack.
+    def call_method_n(self, func_name):
+        self.load(func_name)
+        self.action(avm1.ActionCallMethod())
+        name, obj, nargs = self.pop_stack(3)
+        self.pop_stack(nargs)
+        self.push_stack(Variable("%s.%s_RETURN" % (obj.name, name)))
+
+    # Assumes the args and number of args are on the stack.
+    def call_method_constvar(self, _class, func_name):
+        self.push_var(_class)
+        self.call_method_n(func_name)
+    
+    # Assumes the value is on the stack.
+    # def set_proto_field(self, objname, member_name):
+    #     self.push_const("prototype")
+    #     self.push_var(objname)
+    #     self.get_member()
+    #     self.swap()
+    #     self.push_const(member_name)
+    #     self.swap()
+    #     self.set_member()
+
+    # Assumes the value is on the stack.
+    # def set_static_field(self, objname, member_name):
+    #     self.push_var(objname)
+    #     self.swap()
+    #     self.push_const(member_name)
+    #     self.swap()
+    #     self.set_member()
+
+    # If no args are passed then it is assumed that the args and number of args are on the stack.
+    def newobject_constthis(self, obj, *args):
+        if len(args) > 0:
+            self.load(args+(len(args), obj))
+        else:
+            self.load(obj)
+        self.newobject()
+        
+    
+    def newobject(self):
+        self.action(avm1.ActionNewObject())
+        name, nargs = self.pop_stack(2)
+        args = self.pop_stack(nargs)
+        self.push_stack(ScriptObject(name))
+        
+    # FIXME: will refactor later
+    #load_str = load_const
+    
+    def begin_switch_varname(self, varname):
+        self.push_var(varname)
+        self.switch_register = self.store_register(varname)
+    
+    def write_case(self, testee):
+        self.push_const(avm1.RegisterByIndex(self.switch_register), testee)
+        self.action(avm1.ActionStrictEquals())
+        self.pop_stack(2)
+        if len(self.case_label) < 1:
+            self.case_label, self.case_block = self.branch_if_true()
+        else:
+            self.branch_if_true(self.case_label)
+
+    def write_break(self):
+        self.exit_scope()
+        self.case_flag = False
+        self.case_block = None
+    
+    def enter_case_branch(self):
+        self.enter_scope(self.case_block)
+    
+    def throw(self): # Assumes the value to be thrown is on the stack.
+        self.action(avm1.ActionThrow())
+        self.pop_stack()
+    
+    # oosupport Generator routines
+    def emit(self, op):
+        a = avm1.SHORT_ACTIONS[op]
+        if a.push_count > 0:
+            a.push_stack(StackDummy("Generated by %r" % op))
+        elif a.push_count < 0:
+            self.pop_stack(-a.push_count)
+        self.action(a())
+    
+    def pop(self, TYPE):
+        self.action(avm1.ActionPop())
+        self.pop_stack()
+
+    def dup(self, TYPE):
+        self.action(avm1.ActionDuplicate())
+        self.push_stack(*[self.pop_stack()] * 2)
+    
+    def load(self, v):
+        if hasattr(v, "__iter__")  and not isinstance(v, basestring):
+            for i in v:
+                self.load(i)
+        elif isinstance(v, ClassName):
+            if v.namespace:
+                ns = v.namespace.split('.')
+                self.push_var(ns[0])
+                for i in ns[:0:-1]:
+                    self.push_const(i)
+                    self.get_member()
+            else:
+                self.push_var(v.classname)
+        elif isinstance(v, flowmodel.Variable):
+            if v.concretetype is ootype.Void:
+                return # ignore it
+            elif self.load_variable_hook(v):
+                return
+            else:
+                self.push_local(v)
+        elif isinstance(v, flowmodel.Constant):
+            push_constant(self.db, v.concretetype, v.value, self)
+        elif isinstance(v, SubOperation):
+            render_sub_op(v, self.db, self)
+        else:
+            self.push_const(v)
+        #self.push_var(v)
+
+    def load_variable_hook(self, v):
+        return False
+    
+    #def downcast(self, TYPE):
+    #    pass
+
+    #def getclassobject(self, OOINSTANCE):
+    #    pass
+
+    #def instantiate(self):
+    #    pass
+
+    #def instanceof(self, TYPE):
+    #    pass
+
+    def _make_label(self, label):
+        print "MAKE LABEL:", label
+        if label == "" or label is None:
+            label = self.new_label()
+
+        blocks = dict(self.fn_block.branch_blocks)
+            
+        if label in self.fn_block.branch_blocks:
+            block = blocks[label]
+        else:
+            block = avm1.Block(self.block, False)
+            self.fn_block.branch_blocks.append((label, block))
+        
+        return (label, block)
+
+    def _branch_start(self, label):
+        return self._make_label(label)
+    
+    # Boolean value should be on stack when this is called
+    def branch_unconditionally(self, label):
+        print "BRANCH TO:", label
+        label, block = self._branch_start(label)
+        self.action(avm1.ActionJump(label))
+        return label, block
+
+    def branch_conditionally(self, iftrue, label):
+        label, block = self._branch_start(label)
+        if not iftrue:
+            self.action(avm1.ActionNot())
+        self.action(avm1.ActionIf(label))
+        self.pop_stack()
+        return label, block
+
+    def branch_if_equal(self, label):
+        label, block = self._branch_start(label)
+        self.action(avm1.ActionEquals())
+        self.action(avm1.ActionIf(label))
+        self.pop_stack(2)
+        return label, block
+
+    def call_graph(self, graph):
+        self.call_function(graph.func_name)
+
+    def call_method(self, OOCLASS, method_name):
+        pass
+
+    def call_oostring(self, OOTYPE):
+        self.action(avm1.ActionConvertToString())
+
+    call_oounicode = call_oostring
+
+    def new(self, TYPE):
+        if isinstance(TYPE, ootype.List):
+            self.oonewarray(None)
+    
+    def oonewarray(self, TYPE, length=1):
+        self.newobject_constthis("Array", length)
+    
+    def push_null(self, TYPE=None):
+        self.action(avm1.ActionPush(avm1.NULL))
+        self.push_stack(avm1.NULL)
+
+    def push_undefined(self):
+        self.action(avm1.ActionPush(avm1.UNDEFINED))
+        self.push_stack(avm1.UNDEFINED)
+
+    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()
+            else:
+                self.push_const(value._str)
+        else:
+            self.push_const(value)

File pypy/translator/avm1/constant.py

+
+from pypy.translator.oosupport import constant as c
+
+CONST_OBJNAME = "PYPY_INTERNAL_CONSTANTS"
+
+DEBUG_CONST_INIT = False
+DEBUG_CONST_INIT_VERBOSE = False
+SERIALIZE = False
+
+# ______________________________________________________________________
+# Constant Generators
+#
+# Different generators implementing different techniques for loading
+# constants (Static fields, singleton fields, etc)
+
+class AVM1ConstGenerator(c.BaseConstantGenerator):
+    """
+    AVM1 constant generator.  It implements the oosupport
+    constant generator in terms of the AVM1 virtual machine.
+    """
+
+    def __init__(self, db):
+        c.BaseConstantGenerator.__init__(self, db)
+        self.cts = db.genoo.TypeSystem(db)
+
+    def _begin_gen_constants(self, gen, all_constants):
+        gen.push_const(CONST_OBJNAME)
+        gen.init_array()
+        gen.store_register(CONST_OBJNAME)
+        gen.set_variable()
+        return gen
+
+    def _end_gen_constants(self, gen, numsteps):
+        pass
+
+    def _declare_const(self, gen, const):
+        pass
+    
+    def _close_step(self, gen, stepnum):
+        pass
+    
+    # _________________________________________________________________
+    # OOSupport interface
+    
+    def push_constant(self, gen, const):
+        gen.push_var(CONST_OBJNAME)
+        gen.push_const(const.name)
+        gen.get_member()
+
+    def _create_pointers(self, gen, all_constants):
+        pass
+
+    def _initialize_data(self, gen, all_constants):
+        """ Iterates through each constant, initializing its data. """
+        # gen.add_section("Initialize Data Phase")
+        for const in all_constants:
+            # gen.add_comment("Constant: %s" % const.name)
+            const.initialize_data(self, gen)
+
+
+class AVM1ArrayListConst(c.ListConst):
+
+    NAME = 'NOT_IMPL'
+    
+    def __init__(self, db, list, count):
+        c.AbstractConst.__init__(self, db, list, count)
+        self.name = '%s__%d' % (self.NAME, count)
+
+    def create_pointer(self, gen):
+        assert False
+        
+    def initialize_data(self, constgen, gen):
+        assert not self.is_null()
+        
+        if self._do_not_initialize():
+            return
+
+        gen.push_var(CONST_OBJNAME)
+        gen.push_const(self.name)
+        gen.init_array(self.value._list)
+        gen.set_member()
+        
+        # for idx, item in enumerate(self.value._list):
+        #     gen.push_const(CONST_OBJNAME, CONST_OBJNAME)
+        #     gen.get_variable()
+        #     gen.get_variable()
+        #     gen.push_const(self.name, self.name)
+        #     gen.get_member()
+        #     gen.push_const(idx)
+        #     gen.load(item)
+        #     gen.set_member()
+        #     gen.set_member()
+
+class AVM1ArrayConst(AVM1ArrayListConst):
+    NAME = 'ARRAY'
+
+class AVM1ListConst(AVM1ArrayListConst):
+    NAME = 'LIST'
+
+class AVM1DictConst(c.DictConst):
+    def initialize_data(self, constgen, gen):
+        assert not self.is_null()
+        
+        gen.push_var(CONST_OBJNAME)
+        gen.push_const(self.name)
+        gen.init_object(self.value._dict)
+        gen.set_member()
+        
+        # for key, value in self.value._dict.iteritems():
+        #     gen.push_const(CONST_OBJNAME, CONST_OBJNAME)
+        #     gen.get_variable()
+        #     gen.get_variable()
+        #     gen.push_const(self.name, self.name)
+        #     gen.get_member()
+        #     gen.load(key)
+        #     gen.load(value)
+        #     gen.set_member()
+        #     gen.set_member()
+

File pypy/translator/avm1/database.py

+#from pypy.translator.avm.class_ import Class
+from pypy.rpython.ootypesystem import ootype
+from pypy.translator.cli.support import Counter
+from pypy.translator.oosupport.database import Database as OODatabase
+
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+class LowLevelDatabase(OODatabase):
+    def __init__(self, genoo):
+        OODatabase.__init__(self, genoo)
+        self.classes = {} # INSTANCE --> class_name
+        self.classnames = set() # (namespace, name)
+        self.functions = {} # graph --> function_name
+        self.methods = {} # graph --> method_name
+        self.consts = {}  # value --> AbstractConst
+        self.delegates = {} # StaticMethod --> type_name
+        self.const_count = Counter() # store statistics about constants
+
+    def next_count(self):
+        return self.unique()
+
+    def _default_class_name(self, INSTANCE):
+        parts = INSTANCE._name.rsplit('.', 1)
+        if len(parts) == 2:
+            return parts
+        else:
+            return None, parts[0]
+
+    def pending_function(self, graph, functype=None):
+        if functype is None:
+            function = self.genoo.Function(self, graph)
+        else:
+            function = functype(self, graph)
+        self.pending_node(function)
+        return function.get_name()
+
+    # def pending_class(self, INSTANCE):
+    #     try:
+    #         return self.classes[INSTANCE]
+    #     except KeyError:
+    #         pass
+        
+    #     if isinstance(INSTANCE, dotnet.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 = Class(self, INSTANCE, namespace, name)
+    #         self.pending_node(cls)
+    #         return full_name
+
+    def record_function(self, graph, name):
+        self.functions[graph] = name
+
+    def graph_name(self, graph):
+        # XXX: graph name are not guaranteed to be unique
+        return self.functions.get(graph, None)
+
+    def get_unique_class_name(self, namespace, name):
+        base_name = name
+        i = 0
+        while (namespace, name) in self.classnames:
+            name = '%s_%d' % (base_name, i)
+            i+= 1
+        self.classnames.add((namespace, name))            
+        return name
+
+    def class_name(self, INSTANCE):
+        #if INSTANCE is ootype.ROOT:
+        #    return types.object.classname()
+        try:
+            NATIVE_INSTANCE = INSTANCE._hints['NATIVE_INSTANCE']
+            return NATIVE_INSTANCE._name
+        except KeyError:
+            return self.classes[INSTANCE]

File pypy/translator/avm1/function.py

+from functools import partial
+
+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.avm1.node import Node
+from pypy.translator.avm1.avm1gen import ClassName
+
+def load_variable_hook(self, v):
+    if v.name in self.argset:
+        selftype, selfname = self.args[0]
+        if self.is_method and v.name == selfname:
+            self.generator.push_this() # special case for 'self'
+        else:
+            self.generator.push_arg(v)
+        return True
+    return False
+    
+
+class Function(OOFunction, Node):
+    
+    auto_propagate_exceptions = True
+
+    def __init__(self, *args, **kwargs):
+        OOFunction.__init__(self, *args, **kwargs)
+        
+        if hasattr(self.db.genoo, 'exceptiontransformer'):
+            self.auto_propagate_exceptions = False
+        
+        namespace = getattr(self.graph.func, '_namespace_', None)
+        if namespace:
+            if '.' in namespace:
+                self.namespace, self.classname = namespace.rsplit('.', 1)
+            else:
+                self.namespace = None
+                self.classname = namespace
+        else:
+            self.namespace = None
+            self.classname = None
+
+    def _create_generator(self, ilasm):
+        ilasm.db = self.db
+        ilasm.load_variable_hook = partial(load_variable_hook, self)
+        return ilasm
+    
+    def record_ll_meta_exc(self, ll_meta_exc):
+        # record the type only if it doesn't belong to a native_class
+        ll_exc = ll_meta_exc._INSTANCE
+        NATIVE_INSTANCE = ll_exc._hints.get('NATIVE_INSTANCE', None)
+        if NATIVE_INSTANCE is None:
+            OOFunction.record_ll_meta_exc(self, ll_meta_exc)
+
+    def begin_render(self):
+        self._set_args()
+        self._set_locals()
+        if self.args:
+            args = zip(*self.args)[1]
+        else:
+            args = ()
+        if self.is_method:
+            self.generator.begin_method(self.name, ClassName(self.namespace, self.classname), args[1:])
+        elif self.classname:
+            self.generator.begin_static_method(self.name, ClassName(self.namespace, self.classname), args)
+        else:
+            self.generator.begin_function(self.name, args)
+        
+    def end_render(self):
+        if self.generator.scope.islabel:
+            self.generator.exit_scope()
+        self.generator.exit_scope()
+        
+    def render_return_block(self, block):
+        print "RETURN BLOCK RENDERING"
+        return_var = block.inputargs[0]
+        if return_var.concretetype is not Void:
+            self.generator.load(return_var)
+        self.generator.return_stmt()
+
+    def set_label(self, label):
+        return self.generator.set_label(label)
+
+    # def _render_op(self, op):
+    #     #instr_list = self.db.genoo.opcodes.get(op.opname, None)
+    #     #instr_list.render(self.generator, 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)
+        
+        for to_load, to_store in linkvars:
+            self.generator.load(to_store)
+            self.generator.load(to_load)
+            self.generator.set_variable()
+
+    
+    # def begin_try(self, cond):
+    #     if cond:
+    #         self.ilasm.begin_try()
+    
+    # def end_try(self, target_label, cond):
+    #     if cond:
+    #         self.ilasm.leave(target_label)
+    #         self.ilasm.end_try()
+    #     else:
+    #         self.ilasm.branch(target_label)
+
+    # def begin_catch(self, llexitcase):
+    #     ll_meta_exc = llexitcase
+    #     ll_exc = ll_meta_exc._INSTANCE
+    #     cts_exc = self.cts.lltype_to_cts(ll_exc)
+    #     self.ilasm.begin_catch(cts_exc.classname())
+
+    # def end_catch(self, target_label):
+    #     self.ilasm.leave(target_label)
+    #     self.ilasm.end_catch()
+
+    # def render_raise_block(self, block):
+    #     exc = block.inputargs[1]
+    #     self.load(exc)
+    #     self.ilasm.opcode('throw')
+
+    # def store_exception_and_link(self, link):
+    #     if self._is_raise_block(link.target):
+    #         # 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])
+    #     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.call_method(
+    #                 'class [mscorlib]System.Type object::GetType()',
+    #                 virtual=True)
+    #             self.store(link.last_exception)
+    #         else:
+    #             self.store(link.last_exc_value)
+    #         self._setup_link(link)
+
+    # 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
+    #         # 32bit, and perform a cast in that case
+    #         self.render_numeric_switch_naive(block)
+    #         return
+
+    #     cases, min_case, max_case, default = self._collect_switch_cases(block)
+    #     is_sparse = self._is_sparse_switch(cases, min_case, max_case)
+
+    #     naive = (min_case < 0) or is_sparse
+    #     if naive:
+    #         self.render_numeric_switch_naive(block)
+    #         return
+
+    #     targets = []
+    #     for i in xrange(max_case+1):
+    #         link, lbl = cases.get(i, default)
+    #         targets.append(lbl)
+    #     self.generator.load(block.exitswitch)
+    #     self.ilasm.switch(targets)
+    #     self.render_switch_case(*default)
+    #     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

File pypy/translator/avm1/genavm.py

+
+import py
+from pypy.translator.oosupport.genoo import GenOO
+from pypy.translator.avm1.avm1gen import AVM1Gen
+from pypy.translator.avm1.constant import AVM1ConstGenerator
+from pypy.translator.avm1.database import LowLevelDatabase
+from pypy.translator.avm1.function import Function
+from pypy.translator.avm1.opcodes import opcodes
+from pypy.translator.avm1.types import AVM1TypeSystem
+
+class GenAVM1(GenOO):
+    
+    opcodes = opcodes
+    Function = Function
+    Database = LowLevelDatabase
+    TypeSystem = AVM1TypeSystem
+
+    ConstantGenerator = AVM1ConstGenerator
+    
+    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
+            
+    def create_assembler(self):
+        return AVM1Gen()
+    
+    def generate_source(self):
+        if self.ilasm is None:
+            self.ilasm = self.create_assembler()
+        self.fix_names()
+        self.gen_entrypoint()
+        self.gen_pendings()
+        self.db.gen_constants(self.ilasm)
+
+    # Don't do treebuilding stuff
+    def stack_optimization(self):
+        pass

File pypy/translator/avm1/metavm.py

+
+from pypy.rpython.ootypesystem import ootype
+from pypy.translator.oosupport.metavm import MicroInstruction
+
+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(field)
+        generator.load(value)
+        generator.set_member()
+
+class _GetField(MicroInstruction):
+    def render(self, generator, op):
+        
+        if op.result.concretetype is ootype.Void:
+            return
+        
+        this, field = op.args
+        generator.load(this)
+        generator.load(field)
+        generator.get_member()
+
+class _StoreResultStart(MicroInstruction):
+    def render(self, generator, op):
+        print "STORERESULT START:", op.result.name
+        generator.push_const(op.result.name)
+
+class _StoreResultEnd(MicroInstruction):
+    def render(self, generator, op):
+        print "STORERESULT END:", op.result.name
+        generator.set_variable()
+
+
+class _PushArgsForFunctionCall(MicroInstruction):
+    def render(self, generator, op):
+        args = op.args
+        for arg in args:
+            print arg, type(arg)
+            generator.load(arg)
+        generator.push_const(len(args))
+
+class _CallMethod(MicroInstruction):
+    def render(self, generator, op):
+        args = op.args
+        method_name = args[0].value
+        this = args[1]
+        
+        if isinstance(this.concretetype, ootype.Array):
+            for arg in args[1:]:
+                generator.load(arg)
+            if method_name == "ll_setitem_fast":
+                generator.set_member()
+                generator.push_const(False) # Spoof a method call result
+            elif method_name == "ll_getitem_fast":
+                generator.get_member()
+            elif method_name == "ll_length":
+                generator.load("length")
+                generator.get_member()
+            else:
+                assert False
+        else:
+            if len(args) > 2:
+                for arg in args[2:]:
+                    generator.load(arg)
+                generator.push_const(len(args)-2)
+            else:
+                generator.push_const(0)
+            generator.load(this)
+            generator.call_method_n(method_name)
+
+class CallConstantMethod(MicroInstruction):
+    def __init__(self, obj, func_name):
+        self.obj = obj
+        self.func_name = func_name
+
+    def render(self, generator, op):
+        generator.push_var(self.obj)
+        generator.call_method_n(self.func_name)
+
+class PushConst(MicroInstruction):
+    def __init__(self, *args):
+        self.args = args
+        
+    def render(self, generator, op):
+        generator.push_const(*self.args)
+
+PushArgsForFunctionCall = _PushArgsForFunctionCall()
+StoreResultStart        = _StoreResultStart()
+StoreResultEnd          = _StoreResultEnd()
+GetField                = _GetField()
+SetField                = _SetField()
+CallMethod              = _CallMethod()

File pypy/translator/avm1/opcodes.py

+
+from pypy.translator.oosupport import metavm as om
+from pypy.translator.avm1 import metavm as am, avm1 as a
+
+DoNothing = [om.PushAllArgs]
+
+misc_ops = {
+    'new':           [om.New],
+    'runtimenew':    [om.RuntimeNew],
+    'oosetfield':    [am.SetField],
+    'oogetfield':    [am.GetField],
+    'oonewarray':    [om.OONewArray],
+    'oosend':        [am.CallMethod],
+}
+
+unary_ops = {
+    'same_as':                DoNothing,
+    'bool_not':               'not',
+    'int_neg':                'negate',
+    'int_neg_ovf':            'negate',
+    'int_abs':                [am.PushArgsForFunctionCall, am.CallConstantMethod("Math", "abs")],
+
+    'cast_int_to_char':       [am.PushArgsForFunctionCall, am.CallConstantMethod("String", "fromCharCode")],
+    'cast_int_to_unichar':    [am.PushArgsForFunctionCall, am.CallConstantMethod("String", "fromCharCode")],
+    'cast_int_to_float':      DoNothing,
+    'cast_int_to_longlong':   DoNothing,
+    'cast_int_to_uint':       DoNothing,
+    'cast_int_to_long':       DoNothing,
+    'cast_uint_to_float':     DoNothing,
+    'cast_uint_to_longlong':  DoNothing,
+    'cast_uint_to_int' :      DoNothing,
+    'cast_uint_to_long':      DoNothing,
+
+    'cast_bool_to_int':       'convert_to_number',
+    'cast_bool_to_uint':      'convert_to_number',
+    'cast_bool_to_float':     'convert_to_number',
+
+   
+}
+
+binary_ops = {
+    'int_add':              'typed_add',
+    'int_sub':              'subtract',
+    'int_mul':              'multiply',
+    'int_floordiv':         [om.PushAllArgs, 'divide', am.PushConst(1), am.CallConstantMethod("Math", "floor")],
+    'int_mod':              'modulo',
+    'int_lt':               'typed_less',
+    'int_le':               [om.PushAllArgs, 'greater', 'not'],
+    'int_eq':               'typed_equals',
+    'int_ne':               [om.PushAllArgs, 'typed_equals', 'not'],
+    'int_gt':               'greater',
+    'int_ge':               [om.PushAllArgs, 'typed_less', 'not'],
+
+    'int_and':              'bit_and',
+    'int_or':               'bit_or',
+    'int_lshift':           'shift_left',
+    'int_rshift':           'shift_right',
+    'int_xor':              'bit_xor',
+
+    'uint_add':              'typed_add',
+    'uint_sub':              'subtract',
+    'uint_mul':              'multiply',
+    'uint_floordiv':         [om.PushAllArgs, 'divide', am.PushConst(1), am.CallConstantMethod("Math", "floor")],
+    'uint_mod':              'modulo',
+    'uint_lt':               'typed_less',
+    'uint_le':               [om.PushAllArgs, 'greater', 'not'],
+    'uint_eq':               'typed_equals',
+    'uint_ne':               [om.PushAllArgs, 'typed_equals', 'not'],
+    'uint_gt':               'greater',
+    'uint_ge':               [om.PushAllArgs, 'typed_less', 'not'],
+
+    'uint_and':              'bit_and',
+    'uint_or':               'bit_or',
+    'uint_lshift':           'shift_left',
+    'uint_rshift':           'shift_right',
+    'uint_xor':              'bit_xor',
+    
+    'float_add':              'typed_add',
+    'float_sub':              'subtract',
+    'float_mul':              'multiply',
+    'float_floordiv':         [om.PushAllArgs, 'divide', am.PushConst(1), am.CallConstantMethod("Math", "floor")],
+    'float_mod':              'modulo',
+    'float_lt':               'typed_less',
+    'float_le':               [om.PushAllArgs, 'greater', 'not'],
+    'float_eq':               'typed_equals',
+    'float_ne':               [om.PushAllArgs, 'typed_equals', 'not'],