[pypy-svn] r66799 - in pypy/branch/avm/pypy/translator/avm1: . test

magcius at codespeak.net magcius at codespeak.net
Thu Aug 13 00:29:19 CEST 2009


Author: magcius
Date: Thu Aug 13 00:29:18 2009
New Revision: 66799

Added:
   pypy/branch/avm/pypy/translator/avm1/__init__.py
   pypy/branch/avm/pypy/translator/avm1/conftest.py
   pypy/branch/avm/pypy/translator/avm1/metavm.py
   pypy/branch/avm/pypy/translator/avm1/node.py
   pypy/branch/avm/pypy/translator/avm1/opcodes.py
   pypy/branch/avm/pypy/translator/avm1/test/__init__.py
   pypy/branch/avm/pypy/translator/avm1/test/test_runtest.py
   pypy/branch/avm/pypy/translator/avm1/types.py
   pypy/branch/avm/pypy/translator/avm1/util.py
Removed:
   pypy/branch/avm/pypy/translator/avm1/avm.py
Modified:
   pypy/branch/avm/pypy/translator/avm1/avm1.py
   pypy/branch/avm/pypy/translator/avm1/avm1gen.py
   pypy/branch/avm/pypy/translator/avm1/constant.py
   pypy/branch/avm/pypy/translator/avm1/database.py
   pypy/branch/avm/pypy/translator/avm1/genavm.py
   pypy/branch/avm/pypy/translator/avm1/tags.py
   pypy/branch/avm/pypy/translator/avm1/test/browsertest.py
   pypy/branch/avm/pypy/translator/avm1/test/harness.py
   pypy/branch/avm/pypy/translator/avm1/test/runtest.py
   pypy/branch/avm/pypy/translator/avm1/test/test_int.py
Log:
Merge commit 'avm1/master'

Added: pypy/branch/avm/pypy/translator/avm1/__init__.py
==============================================================================

Modified: pypy/branch/avm/pypy/translator/avm1/avm1.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm1/avm1.py	(original)
+++ pypy/branch/avm/pypy/translator/avm1/avm1.py	Thu Aug 13 00:29:18 2009
@@ -19,35 +19,12 @@
 CONSTANT8   = DataType(8, "constant 8", "B")
 CONSTANT16  = DataType(9, "constant 16", "H")
 
-class Index(object):
-    def __init__(self, index):
-        self.index = index
-
-class Value(object):
-    def __init__(self, value):
-        self.value = value
-
-class Null(object):
-    type = NULL
-
-class Undefined(object):
-    type = UNDEFINED
-
-class ConstantIndexDescriptor(object):
-    def __get__(self, obj, objtype):
-        return CONSTANT8 if obj.index < 256 else CONSTANT16
-
-class Constant(Index):
-    type = ConstantIndexDescriptor()
-
-class Register(object):
-    type = REGISTER
-    
-class RegisterByIndex(Register, Index):
-    pass
-
-class RegisterByValue(Register, Value):
-    pass
+preload = dict(this="preload_this",
+               arguments="preload_args",
+               super="preload_super",
+               _root="preload_root",
+               _parent="preload_parent",
+               _global="preload_global")
 
 class Action(object):
     
@@ -128,7 +105,7 @@
         self.insert_end = insert_end
         
         self.labels = {}
-        self.branch_blocks = {}
+        self.branch_blocks = []
         self.actions = []
         
         self.current_offset = 0
@@ -174,6 +151,9 @@
     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)
@@ -187,7 +167,7 @@
             return old_action
 
         # Two nots negate. Take them out.
-        if action.ACTION_NAME == "ActionNot" and action.ACTION_NAME == "ActionNot":
+        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
@@ -199,10 +179,16 @@
         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:
@@ -258,46 +244,47 @@
         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    = False
-        self.preload_args     = True
+        self.suppress_args    = True
+        self.preload_args     = False
         self.suppress_this    = True
         self.preload_this     = False
         self.preload_global   = False
         self.eval_flags()
-    
-    def eval_flags(self): # WARNING! eval_flags will clear registers!
-        # bits = BitStream()
-        # bits.write_bit_value(self.flags, 16)
-        # bits.rewind()
-        # preload_parent  = bits.read_bit()
-        # preload_root    = bits.read_bit()
-        # suppress_super  = bits.read_bit()
-        # preload_super   = bits.read_bit()
-        # suppress_args   = bits.read_bit()
-        # preload_args    = bits.read_bit()
-        # suppress_this   = bits.read_bit()
-        # preload_this    = bits.read_bit()
-        # bits.cursor += 7 # skip over 7 Reserved bits
-        # preload_global  = bits.read_bit()
+
+        for name in parameters:
+            self.registers.append(name)
         
-        self.registers = [None]
+    def eval_flags(self):
         
         # According to the docs, this is the order of register allocation.
-        if self.preload_this:   self.registers.append("this")
-        if self.preload_args:   self.registers.append("arguments")
-        if self.preload_super:  self.registers.append("super")
-        if self.preload_root:   self.registers.append("_root")
-        if self.preload_parent: self.registers.append("_parent")
-        if self.preload_global: self.registers.append("_global")
+        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")
         
-        for name in self.params:
-            self.registers.append(name)
+        if self.preload_global and "_global" not in self.registers:
+            self.registers.insert(6, "_global")
         
     def gen_data(self):
 
@@ -315,7 +302,7 @@
         
         self.block_data = Block.serialize(self)
         bytes = [self.function_name, "\0",
-                 struct.pack("HB", len(self.params), len(self.registers)-1),
+                 struct.pack("HB", len(self.params), len(self.registers)),
                  bits.serialize()]
         
         for name in self.params:
@@ -411,10 +398,11 @@
 
     def get_block_props_late(self, block):
         if len(self.branch_label) > 0:
-            self.branch_offset = block.labels[self.branch_label] - self.offset
+            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)
+        return struct.pack("h", self.branch_offset)
 
 class ActionJump(BranchingActionBase):
     ACTION_NAME = "ActionJump"
@@ -433,37 +421,20 @@
         self.add_element(*args)
     
     def add_element(self, element):
-        if hasattr(element, "__iter__") and not isinstance(element, basestring):
-            for e in element:
-                self.add_element(e)
-        if isinstance(element, (Null, Undefined)):
-            self.values.append((0, element.type))
-        elif isinstance(element, basestring):
-            self.values.append((element, STRING))
-        elif isinstance(element, bool):
-            self.values.append((element, BOOLEAN))
-        elif isinstance(element, int):
-            self.values.append((element, INTEGER))
-        elif isinstance(element, float):
-            if element > 0xFFFFFFFF:
-                self.values.append((element, DOUBLE))
-            else:
-                self.values.append((element, FLOAT))
-        elif isinstance(element, Index):
-            self.values.append((element.index, element.type))
-        elif isinstance(element, RegisterByValue):
-            self.values.append((element.value, RegisterByValue))
-
+        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):
         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)
-            elif type == RegisterByValue:
-                register_index = block.find_register(value)
-                if register_index < 0:
-                    raise ValueError("register value '%s' not found in registers at this point" % value)
-                self.values[index] = (register_index, REGISTER)
     
     def gen_data(self):
         bytes = []
@@ -511,13 +482,16 @@
         has_catch_block = len(self.catch_block.actions) > 0
         bits = BitStream()
         bits.zero_fill(5)
-        bits.write_bit(isinstance(self.catch_object, Register))
+        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("HHH", len(self.try_block) + 5 if has_catch_block else 0, len(self.catch_block), len(self.finally_block))]
-        bytes += self.catch_object.index if isinstance(self.catch_object, Register) else (self.catch_object + "\0")
-        return "".join(bytes)
+        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()]
@@ -556,17 +530,28 @@
     
     def gen_data(self):
         return struct.pack("H", len(self.block)) + self.block.serialize()
-    
-def make_short_action(value, name):
+
+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 type(name, (Action,), dict(ACTION_ID=value, ACTION_NAME=name,
-                                      __len__=__len__, serialize=serialize))
+    return act
 
 ActionNextFrame           = make_short_action(0x04, "ActionNextFrame")
 ActionPreviousFrame       = make_short_action(0x05, "ActionPreviousFrame")
@@ -574,29 +559,29 @@
 ActionStop                = make_short_action(0x07, "ActionStop")
 ActionToggleQuality       = make_short_action(0x08, "ActionToggleQuality")
 ActionStopSounds          = make_short_action(0x09, "ActionStopSounds")
-ActionAdd                 = make_short_action(0x0a, "ActionAdd")
-ActionSubtract            = make_short_action(0x0b, "ActionSubtract")
-ActionMultiply            = make_short_action(0x0c, "ActionMultiply")
-ActionDivide              = make_short_action(0x0d, "ActionDivide")
-ActionEquals              = make_short_action(0x0e, "ActionEquals")
-ActionLess                = make_short_action(0x0f, "ActionLess")
-ActionAnd                 = make_short_action(0x10, "ActionAnd")
-ActionOr                  = make_short_action(0x11, "ActionOr")
+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")
+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")
+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")
+ActionSetVariable         = make_short_action(0x1d, "ActionSetVariable", -2)
 ActionSetTarget2          = make_short_action(0x20, "ActionSetTarget2")
-ActionStringAdd           = make_short_action(0x21, "ActionStringAdd")
-ActionGetProperty         = make_short_action(0x22, "ActionGetProperty")
-ActionSetProperty         = make_short_action(0x23, "ActionSetProperty")
+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")
+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")
@@ -616,7 +601,7 @@
 ActionDefineLocalVal      = make_short_action(0x3c, "ActionDefineLocalVal")
 ActionCallFunction        = make_short_action(0x3d, "ActionCallFunction")
 ActionReturn              = make_short_action(0x3e, "ActionReturn")
-ActionModulo              = make_short_action(0x3f, "ActionModulo")
+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")
@@ -624,26 +609,26 @@
 ActionTypeof              = make_short_action(0x44, "ActionTypeof")
 ActionGetTargetPath       = make_short_action(0x45, "ActionGetTargetPath")
 ActionEnumerate           = make_short_action(0x46, "ActionEnumerate")
-ActionTypedAdd            = make_short_action(0x47, "ActionTypedAdd")
-ActionTypedLessThan       = make_short_action(0x48, "ActionTypedLessThan")
-ActionTypedEquals         = make_short_action(0x49, "ActionTypedEquals")
+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")
+ActionDuplicate           = make_short_action(0x4c, "ActionDuplicate", 1)
 ActionSwap                = make_short_action(0x4d, "ActionSwap")
-ActionGetMember           = make_short_action(0x4e, "ActionGetMember")
-ActionSetMember           = make_short_action(0x4f, "ActionSetMember")
+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")
-ActionBitOr               = make_short_action(0x61, "ActionBitOr")
-ActionBitXor              = make_short_action(0x62, "ActionBitXor")
-ActionShiftLeft           = make_short_action(0x63, "ActionShiftLeft")
-ActionShiftRight          = make_short_action(0x64, "ActionShiftRight")
-ActionShiftUnsigned       = make_short_action(0x65, "ActionShiftUnsigned")
-ActionStrictEquals        = make_short_action(0x66, "ActionStrictEquals")
-ActionGreater             = make_short_action(0x67, "ActionGreater")
-ActionStringGreater       = make_short_action(0x68, "ActionStringGreater")
+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")

Modified: pypy/branch/avm/pypy/translator/avm1/avm1gen.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm1/avm1gen.py	(original)
+++ pypy/branch/avm/pypy/translator/avm1/avm1gen.py	Thu Aug 13 00:29:18 2009
@@ -2,10 +2,33 @@
 """ backend generator routines
 """
 
-from pypy.translator.avm import avm1
+from pypy.objspace.flow import model as flowmodel
+from pypy.rpython.ootypesystem import ootype
+from pypy.translator.avm import avm1, 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
 
-Scope = namedtuple("Scope", "block parent callback stack")
+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):
@@ -24,63 +47,77 @@
     def __add__(self, other):
         if isinstance(other, StackDummy):
             other = other.name
-        return Variable("CONCAT %r %r" % (self.name, other))
+        return Variable("ADD %r %r" % (self.name, other))
 
     def __radd__(self, other):
-        if isinstance(other, StackDummy):
-            other = other.name
-        return Variable("CONCAT %r %r" % (other, self.name))
-        
+        return other + self
+
+class ScriptObject(StackDummy):
+    pass
     
 class Function(StackDummy):
     pass
 
-class AVM1Gen(object):
+class AVM1Gen(OOGenerator):
     """ AVM1 'assembler' generator routines """
-
-    def __getattribute__(self, name):
-        return object.__getattribute__(self, name)
     
     def __init__(self, block=None):
+        self.stack = []
+        self.namespaces = {}
         self.block = block or avm1.Block(None, True)
-        self.scope = Scope(self.block, None, None, [])
+        self.scope = Scope(self.block, None, None, False)
         self.action(self.block.constants)
-        
+        self.ilasm = self
+    
     def new_label(self):
-        return self.scope.block.new_label()
+        return self.fn_block.new_label()
 
     def push_stack(self, *values):
         print "PUSHSTACK:", values
         for element in values:
-            if isinstance(element, avm1.RegisterByIndex):
-                element = Variable(self.scope.block.registers[element.index])
-            elif isinstance(element, avm1.RegisterByValue):
-                element = Variable(element.value)
-            self.scope.stack.append(element)
+            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.scope.stack.pop() for i in xrange(n)]
+        v = [self.stack.pop() for i in xrange(n)]
         print "POPSTACK:", v
         return v
     
     def store_register(self, name, index=-1):
-        index = self.scope.block.store_register(name, index)
+        index = self.fn_block.store_register(name, index)
         self.action(avm1.ActionStoreRegister(index))
         return index
     
     def find_register(self, name):
-        return self.scope.block.find_register(name)
+        print "FINDING REGISTER:", name
+        return self.fn_block.find_register(name)
     
     def action(self, action):
         return self.scope.block.add_action(action)
     
-    def enter_scope(self, new_code_obj, exit_callback=None):
-        self.scope = Scope(new_code_obj, self.scope, exit_callback, [])
-
+    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.scope.block.FUNCTION_TYPE
+        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
         
@@ -92,56 +129,87 @@
             exit_callback()
 
     def finalize_block(self, block):
-        for label, branch_block in block.branch_blocks.iteritems():
-            if not branch_block.is_sealed():
-                raise Exception, "Branch block hasn't been finalized"
+        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_prototype_method(self, function_name, _class, arglist):
+        
+    def begin_static_method(self, function_name, _class, arglist):
         def exit_callback(block):
             self.set_member()
-        self.push_const(function_name, "prototype", _class)
-        self.get_variable()
-        self.get_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:
+        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: %s" % (name,)
+        print "GETVARIABLE:", name
         self.action(avm1.ActionGetVariable())
         self.push_stack(make_variable(name))
     
     def set_member(self):
         self.action(avm1.ActionSetMember())
         self.pop_stack(3)
-
+        
     def get_member(self):
         self.action(avm1.ActionGetMember())
-        value, name, obj = self.pop_stack(3)
-        print "GETMEMBER:", value, name, obj
+        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.push_const(avm1.RegisterByIndex(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."
@@ -152,12 +220,20 @@
 
     def push_var(self, v):
         k = self.find_register(v)
+        print k
         if k >= 0:
+            self.push_stack(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()
-            index = self.store_register(v)
+            if self.in_function() == 2:
+                self.store_register(v)
 
     def push_this(self):
         self.push_var("this")
@@ -165,17 +241,12 @@
     def push_local(self, v):
         self.push_var(v.name)
         
-    def push_const(self, *v):
-        self.push_stack(*v)
-        return self.action(avm1.ActionPush(v))
-
-    def push_undefined(self):
-        self.push_const(avm1.Undefined)
-
-    def push_null(self):
-        self.push_const(avm1.Null)
+    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())
 
@@ -195,15 +266,19 @@
         self.action(avm1.ActionNot())
         self.pop_stack(2)
     
-    def init_object(self, members=None):
-        self.push_const(members.iteritems(), len(members))
+    def init_object(self, members={}):
+        self.push_const(*members.items())
+        self.push_const(len(members))
         self.action(avm1.ActionInitObject())
-        self.pop_stack(2)
+        self.pop_stack(self.pop_stack()[0])
+        self.push_stack(ScriptObject("object"))
 
-    def init_array(self, members=None):
-        self.push_const(members, len(members))
-        self.pop_stack(2)
+    def init_array(self, members=[]):
+        self.push_const(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):
@@ -220,7 +295,7 @@
         self.push_stack(Variable("%s_RETURN" % func_name))
         
     # Assumes the args and number of args and ScriptObject are on the stack.
-    def call_method(self, func_name):
+    def call_method_n(self, func_name):
         self.push_const(func_name)
         self.action(avm1.ActionCallMethod())
         name, obj, nargs = self.pop_stack(3)
@@ -230,34 +305,25 @@
     # 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()
-
-    # Boolean value should be on stack when this is called
-    def branch_if_true(self, label=""):
-        if len(label) == 0:
-            label = self.new_label()
-        self.scope.block.branch_blocks[label] = avm1.Block(self.block, False)
-        self.action(avm1.ActionIf(label))
-        self.pop_stack()
-        return (label, self.scope.block.branch_blocks[label])
+        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()
+    # 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()
+    # 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):
@@ -270,8 +336,9 @@
     
     def newobject(self):
         self.action(avm1.ActionNewObject())
-        _, nargs = self.pop_stack()
-        self.pop_stack(nargs)
+        name, nargs = self.pop_stack()
+        args = self.pop_stack(nargs)
+        self.push_stack(ScriptObject(name))
         
     # FIXME: will refactor later
     #load_str = load_const
@@ -300,11 +367,135 @@
     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 concat_string(self):
-        self.action(avm1.ActionTypedAdd())
-        self.push_stack(self.pop_stack()[0] + self.pop_stack()[0])
+    def dup(self, TYPE):
+        self.action(avm1.ActionDuplicate())
+        self.push_stack([self.pop_stack()] * 2)
+    
+    def load(self, v):
+        print v, type(v)
+        if hasattr(v, "__iter__")  and not isinstance(v, basestring):
+            for i in v:
+                self.load(v)
+        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 extends(self):
+    #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):
+    #     pass
+    
+    def oonewarray(self, TYPE, length):
+        self.newobject_constthis("Array", 1)
+    
+    def push_null(self, TYPE=None):
+        self.action(avm1.ActionPush(avm1.NULL))
+        self
+
+    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_undefined()
+        else:
+            self.push_const(value)

Added: pypy/branch/avm/pypy/translator/avm1/conftest.py
==============================================================================
--- (empty file)
+++ pypy/branch/avm/pypy/translator/avm1/conftest.py	Thu Aug 13 00:29:18 2009
@@ -0,0 +1,19 @@
+class ConftestPlugin:
+    def pytest_addoption(self, parser):
+        group = parser.addgroup("pypy-avm options")
+        # group.addoption('--source', action="store_true", dest="source", default=False,
+        #         help="only generate IL source, don't compile")
+        # group.addoption('--wd', action="store_true", dest="wd", default=False,
+        #         help="store temporary files in the working directory")
+        # group.addoption('--stdout', action="store_true", dest="stdout", default=False,
+        #         help="print the generated IL code to stdout, too")
+        # group.addoption('--nostop', action="store_true", dest="nostop", default=False,
+        #         help="don't stop on warning. The generated IL code could not compile")
+        # group.addoption('--nowrap', action="store_true", dest="nowrap", default=False,
+        #         help="don't wrap exceptions but let them to flow out of the entry point")
+        # group.addoption('--verify', action="store_true", dest="verify", default=False,
+        #         help="check that compiled executables are verifiable")
+        # group.addoption('--norun', action='store_true', dest="norun", default=False,
+        #         help="don't run the compiled executable")
+        # group.addoption('--trace', action='store_true', dest='trace', default=False,
+        #         help='Trace execution of generated code')

Modified: pypy/branch/avm/pypy/translator/avm1/constant.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm1/constant.py	(original)
+++ pypy/branch/avm/pypy/translator/avm1/constant.py	Thu Aug 13 00:29:18 2009
@@ -25,11 +25,14 @@
 
     def _begin_gen_constants(self, asmgen, all_constants):
         self.asmgen = asmgen
+        self.asmgen.push_const(CONST_OBJNAME)
         self.asmgen.init_object()
         self.asmgen.store_register(CONST_OBJNAME)
-        self.asmgen.push_const(CONST_OBJNAME)
         self.asmgen.set_variable()
         return asmgen
+
+    def _end_gen_constants(self, a, b):
+        pass
     
     # _________________________________________________________________
     # OOSupport interface

Modified: pypy/branch/avm/pypy/translator/avm1/database.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm1/database.py	(original)
+++ pypy/branch/avm/pypy/translator/avm1/database.py	Thu Aug 13 00:29:18 2009
@@ -1,9 +1,6 @@
-import string
-from pypy.translator.avm.class_ import Class
-from pypy.translator.avm.delegate import Delegate
-from pypy.translator.avm.cts import types
+#from pypy.translator.avm.class_ import Class
 from pypy.rpython.ootypesystem import ootype
-from pypy.rpython.ootypesystem.module import ll_os
+from pypy.translator.cli.support import Counter
 from pypy.translator.oosupport.database import Database as OODatabase
 
 try:
@@ -16,7 +13,6 @@
         OODatabase.__init__(self, genoo)
         self.classes = {} # INSTANCE --> class_name
         self.classnames = set() # (namespace, name)
-        self.recordnames = {} # RECORD --> name
         self.functions = {} # graph --> function_name
         self.methods = {} # graph --> method_name
         self.consts = {}  # value --> AbstractConst
@@ -26,17 +22,6 @@
     def next_count(self):
         return self.unique()
 
-    def _default_record_name(self, RECORD):
-        trans = string.maketrans('[]<>(), :', '_________')
-        name = ['Record']
-        # XXX: refactor this: we need a proper way to ensure unique names
-        for f_name, (FIELD_TYPE, f_default) in RECORD._fields.iteritems():
-            type_name = FIELD_TYPE._short_name().translate(trans)
-            name.append(f_name)
-            name.append(type_name)
-            
-        return '__'.join(name)
-
     def _default_class_name(self, INSTANCE):
         parts = INSTANCE._name.rsplit('.', 1)
         if len(parts) == 2:
@@ -52,42 +37,26 @@
         self.pending_node(function)
         return function.get_name()
 
-    def pending_class(self, INSTANCE):
-        try:
-            return self.classes[INSTANCE]
-        except KeyError:
-            pass
+    # 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 pending_record(self, RECORD):
-        try:
-            return BUILTIN_RECORDS[RECORD]
-        except KeyError:
-            pass
-        try:
-            return self.recordnames[RECORD]
-        except KeyError:
-            pass
-        name = self._default_record_name(RECORD)
-        name = self.get_unique_class_name(None, name)
-        self.recordnames[RECORD] = name
-        r = Record(self, RECORD, name)
-        self.pending_node(r)
-        return name
+    #     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
@@ -113,18 +82,3 @@
             return NATIVE_INSTANCE._name
         except KeyError:
             return self.classes[INSTANCE]
-
-    def get_record_name(self, RECORD):
-        try:
-            return BUILTIN_RECORDS[RECORD]
-        except KeyError:
-            return self.recordnames[RECORD]
-
-    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

Modified: pypy/branch/avm/pypy/translator/avm1/genavm.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm1/genavm.py	(original)
+++ pypy/branch/avm/pypy/translator/avm1/genavm.py	Thu Aug 13 00:29:18 2009
@@ -1,21 +1,38 @@
-import sys
-import shutil
 
 import py
-from py.compat import subprocess
-from pypy.config.config import Config
 from pypy.translator.oosupport.genoo import GenOO
-from pypy.translator.cli import conftest
-from pypy.translator.cli.avm1gen import AVM1Gen
+from pypy.translator.avm.avm1gen import AVM1Gen
+from pypy.translator.avm.constant import AVM1ConstGenerator
+from pypy.translator.avm.database import LowLevelDatabase
+from pypy.translator.avm.function import Function
+from pypy.translator.avm.opcodes import opcodes
+from pypy.translator.avm.types import AVM1TypeSystem
 
 class GenAVM1(GenOO):
     
-    ConstantGenerator = constant.AVM1ConstGenerator
+    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.assembly_name = entrypoint.get_name()
         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

Added: pypy/branch/avm/pypy/translator/avm1/metavm.py
==============================================================================
--- (empty file)
+++ pypy/branch/avm/pypy/translator/avm1/metavm.py	Thu Aug 13 00:29:18 2009
@@ -0,0 +1,68 @@
+
+from pypy.rpython.ootypesystem import ootype
+from pypy.translator.oosupport.metavm import MicroInstruction
+from pypy.translator.avm.avm1gen import StackDummy
+
+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 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()

Added: pypy/branch/avm/pypy/translator/avm1/node.py
==============================================================================
--- (empty file)
+++ pypy/branch/avm/pypy/translator/avm1/node.py	Thu Aug 13 00:29:18 2009
@@ -0,0 +1,9 @@
+class Node(object):
+    def get_name(self):
+        pass
+
+    def dependencies(self):
+        pass
+
+    def render(self, ilasm):
+        pass

Added: pypy/branch/avm/pypy/translator/avm1/opcodes.py
==============================================================================
--- (empty file)
+++ pypy/branch/avm/pypy/translator/avm1/opcodes.py	Thu Aug 13 00:29:18 2009
@@ -0,0 +1,140 @@
+
+from pypy.translator.oosupport import metavm as om
+from pypy.translator.avm import metavm as am, avm1 as a
+
+DoNothing = [om.PushAllArgs]
+
+misc_ops = {
+    'new':           [om.New],
+    'runtimenew':    [om.RuntimeNew],
+    'oosetfield':    [am.SetField],
+    'oogetfield':    [am.GetField],
+#    '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'],
+    'float_gt':               'greater',
+    'float_ge':               [om.PushAllArgs, 'typed_less', 'not'],
+
+    'float_and':              'bit_and',
+    'float_or':               'bit_or',
+    'float_lshift':           'shift_left',
+    'float_rshift':           'shift_right',
+    'float_xor':              'bit_xor',
+    
+    'llong_add':              'typed_add',
+    'llong_sub':              'subtract',
+    'llong_mul':              'multiply',
+    'llong_floordiv':         [om.PushAllArgs, 'divide', am.PushConst(1), am.CallConstantMethod("Math", "floor")],
+    'llong_mod':              'modulo',
+    'llong_lt':               'typed_less',
+    'llong_le':               [om.PushAllArgs, 'greater', 'not'],
+    'llong_eq':               'typed_equals',
+    'llong_ne':               [om.PushAllArgs, 'typed_equals', 'not'],
+    'llong_gt':               'greater',
+    'llong_ge':               [om.PushAllArgs, 'typed_less', 'not'],
+
+    'llong_and':              'bit_and',
+    'llong_or':               'bit_or',
+    'llong_lshift':           'shift_left',
+    'llong_rshift':           'shift_right',
+    'llong_xor':              'bit_xor',
+
+    'ullong_add':              'typed_add',
+    'ullong_sub':              'subtract',
+    'ullong_mul':              'multiply',
+    'ullong_floordiv':         [om.PushAllArgs, 'divide', am.PushConst(1), am.CallConstantMethod("Math", "floor")],
+    'ullong_mod':              'modulo',
+    'ullong_lt':               'typed_less',
+    'ullong_le':               [om.PushAllArgs, 'greater', 'not'],
+    'ullong_eq':               'typed_equals',
+    'ullong_ne':               [om.PushAllArgs, 'typed_equals', 'not'],
+    'ullong_gt':               'greater',
+    'ullong_ge':               [om.PushAllArgs, 'typed_less', 'not'],
+    'ullong_lshift':           'shift_left',
+    'ullong_rshift':           'shift_right',
+}
+
+opcodes = misc_ops.copy()
+opcodes.update(unary_ops)
+opcodes.update(binary_ops)
+
+for key, value in opcodes.iteritems():
+    if isinstance(value, str):
+        value = [am.StoreResultStart, om.PushAllArgs, value, am.StoreResultEnd]
+    if am.StoreResultStart not in value:
+        value.insert(0, am.StoreResultStart)
+    if am.StoreResultEnd not in value:
+        value.append(am.StoreResultEnd)
+    value = om.InstructionList(value)
+    opcodes[key] = value

Modified: pypy/branch/avm/pypy/translator/avm1/tags.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm1/tags.py	(original)
+++ pypy/branch/avm/pypy/translator/avm1/tags.py	Thu Aug 13 00:29:18 2009
@@ -3,6 +3,7 @@
 
 from pypy.translator.avm.records import RecordHeader, ShapeWithStyle, Matrix, CXForm
 from pypy.translator.avm.avm1 import Block
+from pypy.translator.avm.util import BitStream
 
 next_character_id = 1
 
@@ -117,12 +118,42 @@
         return (struct.pack("<HH", self.shapeid, self.depth) +
                 (self.transform.serialize() + self.colortransform.serialize()).serialize())
 
+class PlaceObject2(PlaceObject):
+
+    TAG_TYPE = 26
+    TAG_MIN_VERSION = 3
+
+    def __init__(self, shapeid, depth, transform=None, colortransform=None):
+        self.shapeid = shapeid
+        self.depth = depth
+        self.transform = transform
+        self.colortransform = colortransform
+    
+    def serialize_data(self):
+        flags = BitStream()
+        flags.write_bit(False) # HasClipActions
+        flags.write_bit(False) # HasClipDepth
+        flags.write_bit(False) # HasName
+        flags.write_bit(False) # HasRatio
+        flags.write_bit(self.colortransform is not None)
+        flags.write_bit(self.transform is not None)
+        flags.write_bit(True)  # HasCharacter
+        flags.write_bit(False) # FlagMove
+        
+        bytes = flags.serialize() + struct.pack("<HH", self.depth, self.shapeid)
+        bits = BitStream()
+        if self.transform is not None:
+            bits += self.transform.serialize()
+        if self.colortransform is not None:
+            bits += self.colortransform.serialize()
+        return bytes + bits.serialize()
+
 class DefineEditText(SwfTag):
 
     TAG_TYPE = 37
     TAG_MIN_VERSION = 4
     
-    def __init__(self, rect, variable, text="", readonly=False, isHTML=False,
+    def __init__(self, rect, variable, text="", readonly=True, isHTML=False,
                  wordwrap=False, multiline=True, password=False, autosize=True,
                  selectable=True, border=False, color=None, maxlength=None,
                  layout=None, font=None, size=12, fontclass=None, characterid=None):

Added: pypy/branch/avm/pypy/translator/avm1/test/__init__.py
==============================================================================
--- (empty file)
+++ pypy/branch/avm/pypy/translator/avm1/test/__init__.py	Thu Aug 13 00:29:18 2009
@@ -0,0 +1 @@
+#

Modified: pypy/branch/avm/pypy/translator/avm1/test/browsertest.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm1/test/browsertest.py	(original)
+++ pypy/branch/avm/pypy/translator/avm1/test/browsertest.py	Thu Aug 13 00:29:18 2009
@@ -16,6 +16,7 @@
 <body>
 <object type="application/x-shockwave-flash" data="test.swf" width="%d" height="%d">
 <param name="movie" value="test.swf" />
+<param name="allowScriptAccess" value="always" />
 </object>
 </body>
 </html>"""
@@ -29,18 +30,15 @@
         return True
     elif string == "false":
         return False
-    elif string == "null" or string == "undefined":
-        return None
-    elif string.isdigit():
+    elif all(c in "0123456789-" for c in string):
         return int(string)
     return string
 
 class TestCase(object):
-    def __init__(self, name, swfdata, testcount):
+    def __init__(self, name, swfdata):
         self.name = name
         self.swfdata = swfdata
-        self.results = []
-        self.testcount = testcount
+        self.result = None
     
 class TestHandler(BaseHTTPRequestHandler):
     """The HTTP handler class that provides the tests and handles results"""
@@ -59,9 +57,10 @@
         self.serve_data(mime, data)
         
     def do_POST(self):
+        print self.path
         if self.path == "/test.result":
             form = parse_qs(self.rfile.read(int(self.headers['content-length'])))
-            self.server.testcase.results.append(parse_result(form['result'][0]))
+            self.server.testcase.result = parse_result(form['result'][0])
 
     def serve_data(self, content_type, data):
         self.send_response(200)
@@ -80,14 +79,14 @@
 
     def get_result(self):
         testcase = self.httpd.testcase
-        while len(testcase.results) < testcase.testcount:
+        while testcase.result is None:
             self.httpd.handle_request()
-        return self.httpd.testcase.results
+        return testcase.result
 
-def browsertest(name, swfdata, testcount):
-    testcase = TestCase(str(name), swfdata, testcount)
+def browsertest(name, swfdata):
+    testcase = TestCase(str(name), swfdata)
     driver = BrowserTest()
     driver.start_server(config.http_port, testcase)
     webbrowser.open('http://localhost:%d/test.html' % config.http_port)
-
+    
     return driver.get_result()

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 Aug 13 00:29:18 2009
@@ -5,23 +5,22 @@
 class TestHarness(object):
     def __init__(self, name):
         self.testname  = name
-        self.in_test   = False
-        self.expected  = []
         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.PlaceObject(1, 2))
+        self.swf.add_tag(t.PlaceObject2(1, 2))
         self.actions = g.AVM1Gen(t.DoAction())
         self.swf.add_tag(self.actions.block)
         self.swf.add_tag(t.ShowFrame())
         self.swf.add_tag(t.End())
+        self.start_test()
         
     def print_text(self, text):
         self.actions.push_const("txt", "\n" + text)
         self.actions.push_var("txt")
         self.actions.swap()
-        self.actions.concat_string()
+        self.actions.emit('typed_add')
         self.actions.set_variable()
 
     def print_var(self, prefix, varname):
@@ -29,8 +28,8 @@
         self.actions.push_var("txt")
         self.actions.push_const("\n" + prefix)
         self.actions.push_var(varname)
-        self.actions.concat_string()
-        self.actions.concat_string()
+        self.actions.emit('typed_add')
+        self.actions.emit('typed_add')
         self.actions.set_variable()
 
     def print_stack(self, prefix):
@@ -40,31 +39,29 @@
         self.actions.swap()
         self.actions.push_const("\n" + prefix)
         self.actions.swap()
-        self.actions.concat_string()
-        self.actions.concat_string()
+        self.actions.emit('typed_add')
+        self.actions.emit('typed_add')
         self.actions.set_variable()
     
-    def start_test(self, name):
-        assert not self.in_test
-        self.in_test = True
-        self.print_text("Running test %s." % name)
+    def start_test(self):
+        self.print_text("Running test %s." % self.testname)
         self.actions.push_const("result")
         
-    def finish_test(self, expected):
+    def finish_test(self):
         # result value is on the stack,
         # followed by the string "result"
-        assert self.in_test
-        self.in_test = False
-        self.expected.append(expected)
         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.push_const("javascript:window.close()", "") # Close the window.
+        self.actions.action(a.ActionGetURL2(""))
 
-    def do_test(self):
-        assert not self.in_test
-        with open("test.swf", "w") as f:
+    def do_test(self, debug=False):
+        self.finish_test()
+        self.actions.scope.block.seal()
+        if debug:
+            f = open("test.swf", "w")
             f.write(self.swf.serialize())
-        results = b.browsertest(self.testname, self.swf, len(self.expected))
-        for e, r in zip(self.expected, results):
-            assert e == r
+            f.close()
+        return b.browsertest(self.testname, self.swf)

Modified: pypy/branch/avm/pypy/translator/avm1/test/runtest.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm1/test/runtest.py	(original)
+++ pypy/branch/avm/pypy/translator/avm1/test/runtest.py	Thu Aug 13 00:29:18 2009
@@ -10,13 +10,14 @@
 from pypy.translator.backendopt.checkvirtual import check_virtual_methods
 from pypy.translator.oosupport.support import patch_os, unpatch_os
 from pypy.translator.avm.test.harness import TestHarness
+from pypy.translator.avm.genavm import GenAVM1
 
-def translate_space_op(gen, op):
-    if op.opname == "cast_int_to_char":
-        gen.push_arg(op.args[0])
-        gen.push_const(1)
-        gen.push_var("String")
-        gen.call_method("fromCharCode")
+# def translate_space_op(gen, op):
+#     if op.opname == "cast_int_to_char":
+#         gen.push_arg(op.args[0])
+#         gen.push_const(1)
+#         gen.push_var("String")
+#         gen.call_method("fromCharCode")
 
 def compile_function(func, name, annotation=[], graph=None, backendopt=True,
                      auto_raise_exc=False, exctrans=False,
@@ -24,8 +25,11 @@
     olddefs = patch_os()
     gen = _build_gen(func, annotation, name, graph, backendopt,
                      exctrans, annotatorpolicy, nowrap)
+    harness = TestHarness(name)
+    gen.ilasm = harness.actions
+    gen.generate_source()
     unpatch_os(olddefs) # restore original values
-    return gen
+    return gen, harness
 
 def _build_gen(func, annotation, name, graph=None, backendopt=True, exctrans=False,
                annotatorpolicy=None, nowrap=False):
@@ -50,62 +54,29 @@
         backend_optimizations(t)
     
     main_graph = t.graphs[0]
-
-    harness = TestHarness(name)
-    harness.actions.begin_function(main_graph.name, [v.name for v in main_graph.getargs()])
-    for op in main_graph.startblock.operations:
-        translate_space_op(harness.actions, op)
-    harness.actions.return_stmt()
-    harness.actions.exit_scope()
+    tmpdir = py.path.local('.')
     
-    return harness
-
-class StructTuple(tuple):
-    def __getattr__(self, name):
-        if name.startswith('item'):
-            i = int(name[len('item'):])
-            return self[i]
-        else:
-            raise AttributeError, name
-
-class OOList(list):
-    def ll_length(self):
-        return len(self)
-
-    def ll_getitem_fast(self, i):
-        return self[i]
-
-class InstanceWrapper:
-    def __init__(self, class_name):
-        self.class_name = class_name
-
-class ExceptionWrapper:
-    def __init__(self, class_name):
-        self.class_name = class_name
-
-    def __repr__(self):
-        return 'ExceptionWrapper(%s)' % repr(self.class_name)
+    return GenAVM1(tmpdir, t, None, exctrans)
 
 class AVM1Test(BaseRtypingTest, OORtypeMixin):
     def __init__(self):
         self._func = None
         self._ann = None
+        self._genoo = None
         self._harness = None
-        self._test_count = 1
 
     def _compile(self, fn, args, ann=None, backendopt=True, auto_raise_exc=False, exctrans=False):
         if ann is None:
             ann = [lltype_to_annotation(typeOf(x)) for x in args]
-        if self._func is fn and self._ann == ann:
-            return self._harness
-        else:
-            self._harness = compile_function(fn, self.__class__.__name__, ann,
-                                             backendopt=backendopt,
-                                             auto_raise_exc=auto_raise_exc,
-                                             exctrans=exctrans)
-            self._func = fn
-            self._ann = ann
-            return self._harness
+        self._genoo, self._harness = compile_function(fn,
+                                                      "%s.%s" % (self.__class__.__name__, fn.func_name),
+                                                      ann,
+                                                      backendopt=backendopt,
+                                                      auto_raise_exc=auto_raise_exc,
+                                                      exctrans=exctrans)
+        self._func = fn
+        self._ann = ann
+        return self._harness
 
     def _skip_win(self, reason):
         if platform.system() == 'Windows':
@@ -123,16 +94,12 @@
             backendopt = getattr(self, 'backendopt', True) # enable it by default
         return backendopt
     
-    def interpret(self, fn, args, expected=None, annotation=None, backendopt=None, exctrans=False):
+    def interpret(self, fn, args, annotation=None, backendopt=None, exctrans=False):
         backendopt = self._get_backendopt(backendopt)
         harness = self._compile(fn, args, annotation, backendopt=backendopt, exctrans=exctrans)
-        harness.start_test("%d" % self._test_count)
-        self._test_count += 1
         harness.actions.call_function_constargs(fn.func_name, *args)
-        harness.finish_test(expected)
-
-    def do_test(self):
-        self._harness.do_test()
+        result = harness.do_test(True)
+        return result
     
     def interpret_raises(self, exception, fn, args, backendopt=None, exctrans=False):
         import exceptions # needed by eval

Modified: pypy/branch/avm/pypy/translator/avm1/test/test_int.py
==============================================================================
--- pypy/branch/avm/pypy/translator/avm1/test/test_int.py	(original)
+++ pypy/branch/avm/pypy/translator/avm1/test/test_int.py	Thu Aug 13 00:29:18 2009
@@ -2,20 +2,49 @@
 import py
 from pypy.translator.avm.test.runtest import AVM1Test
 from pypy.rpython.test.test_rint import BaseTestRint
+from pypy.rlib.rarithmetic import r_longlong
 
 class TestAVM1Int(AVM1Test, BaseTestRint):
     def test_char_constant(self):
         def dummyfn(i):
             return chr(i)
-        self.interpret(dummyfn, [ord(' ')], ' ')
-        self.interpret(dummyfn, [ord('a')], 'a')
-        self.do_test()
+        _ = self.interpret(dummyfn, [ord(' ')])
+        assert _ == ' '
+        _ = self.interpret(dummyfn, [ord('a')])
+        assert _ == 'a'
 
     def test_rarithmetic(self):
         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):
 
-if __name__ == "__main__":
-    TestAVM1Int().test_char_constant()
+            # 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()

Added: pypy/branch/avm/pypy/translator/avm1/test/test_runtest.py
==============================================================================
--- (empty file)
+++ pypy/branch/avm/pypy/translator/avm1/test/test_runtest.py	Thu Aug 13 00:29:18 2009
@@ -0,0 +1,18 @@
+import autopath
+import py
+from pypy.translator.oosupport.test_template.runtest import BaseTestRunTest
+from pypy.translator.avm.test.runtest import AVM1Test
+
+class TestRunTest(BaseTestRunTest, AVM1Test):
+
+    def test_auto_raise_exc(self):
+        def fn():
+            raise ValueError
+        f = self._compile(fn, [], auto_raise_exc=True)
+        py.test.raises(ValueError, f)
+
+    def test_big_arglist(self):
+        def fn(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9):
+            return a0
+        res = self.interpret(fn, [42]*10)
+        assert res == 42

Added: pypy/branch/avm/pypy/translator/avm1/types.py
==============================================================================
--- (empty file)
+++ pypy/branch/avm/pypy/translator/avm1/types.py	Thu Aug 13 00:29:18 2009
@@ -0,0 +1,47 @@
+
+from pypy.translator.avm import avm1
+from pypy.objspace.flow import model as flowmodel
+from pypy.rlib.rarithmetic import r_longlong
+from pypy.rpython.ootypesystem import ootype
+from pypy.rpython.lltypesystem import lltype
+
+_pytype_to_avm1 = {
+    str:        avm1.STRING,
+    unicode:    avm1.STRING,
+    int:        avm1.INTEGER,
+    long:       avm1.INTEGER,
+    bool:       avm1.BOOLEAN,
+    float:      avm1.DOUBLE,
+    r_longlong: avm1.INTEGER,
+}
+
+class AVM1Number(object):
+    pass
+
+class AVM1Primitive(object):
+    pass
+
+_lltype_to_avm1 = {
+    lltype.Number: AVM1Number,
+    lltype.Primitive: AVM1Primitive
+}
+
+def pytype_to_avm1(value):
+    return (value, _pytype_to_avm1[type(value)])
+
+def lltype_to_avm1(value):
+    return _lltype_to_avm1[type(value)]
+
+class AVM1TypeSystem(object):
+    def __init__(self, db):
+        self.db = db
+
+    def escape_name(self, name):
+        return name
+    
+    def lltype_to_cts(self, TYPE):
+        return lltype_to_avm1(TYPE)
+    
+    def llvar_to_cts(self, var):
+        print var.name
+        return self.lltype_to_cts(var.concretetype), var.name

Added: pypy/branch/avm/pypy/translator/avm1/util.py
==============================================================================
--- (empty file)
+++ pypy/branch/avm/pypy/translator/avm1/util.py	Thu Aug 13 00:29:18 2009
@@ -0,0 +1,256 @@
+
+import struct, os, math
+
+ALIGN_LEFT = "left"
+ALIGN_RIGHT = "right"
+
+class BitStream(object):
+
+    """ BitStream is a class for taking care of data structures that are bit-packed, like SWF."""
+    
+    def __init__(self, bits=[]):
+        """
+        Constructor.
+        """
+        self.bits = [bool(b) and b != "0" for b in bits]
+        self.cursor = 0
+        self.chunks = set((0,))
+
+    def read_bit(self):
+        """Reads a bit from the bit stream and returns it as either True or False. IndexError is thrown if reading past the end of the stream."""
+        self.cursor += 1
+        return self.bits[self.cursor-1]
+    
+    def read_bits(self, length):
+        """Reads length bits and return them in their own bit stream."""
+        self.cursor += length
+        return BitStream(self.bits[self.cursor-length:self.cursor])
+    
+    def write_bit(self, value):
+        """Writes the boolean value to the bit stream."""
+        if self.cursor < len(self.bits):
+            self.bits[self.cursor] = bool(value)
+        else:
+            self.bits.append(bool(value))
+        self.cursor += 1
+
+    def write_bits(self, bits, offset=0, length=0):
+        """Writes length bits from bits to this bit stream, starting reading at offset. If length
+        is 0, the entire stream is used."""
+        if length < 1:
+            length = len(bits)
+
+        if length > self.bits_available():
+            for i in range(length - self.bits_available()):
+                self.bits.append(False)
+        
+        self.bits[self.cursor:self.cursor+length] = (bool(x) for x in bits[offset:offset+length])
+        self.cursor += length
+
+    def read_int_value(self, length):
+        """Read length bits and return a number containing those bits with the last bit read being
+        the least significant bit."""
+        n = 0
+        for i in reversed(xrange(length)):
+            n |= self.read_bit() << i
+        return n
+    
+    def write_int_value(self, value, length=-1):
+        """Writes an int to the specified number of bits in the stream, the most significant bit
+        first. If length is not specified or negative, the log base 2 of value is taken."""
+        
+        if length < 0:
+            try:
+                length = int(math.ceil(math.log(value, 2))) # Get the log base 2, or number of bits value will fit in.
+            except ValueError:
+                length = 1
+        self.chunk()
+        for i in reversed(xrange(length)):
+            self.write_bit(value & (1 << i))
+            
+    
+    def read_fixed_value(self, eight_bit):
+        """Reads a fixed point number, either 8.8 or 16.16. If eight_bit is True, an
+        8.8 format is used, otherwise 16.16."""
+        return self.read_int_value(length) / float(0x100 if eight_bit else 0x10000)
+
+    def write_fixed_value(self, value, eight_bit):
+        """Writes a fixed point number of length, decimal part first. If eight_bit is True,
+        an 8.8 format is used instead of a 16.16 format."""
+        self.write_bit_value(value * float(0x100 if eight_bit else 0x10000), 8 if eight_bit else 16)
+
+    # Precalculated, see the Wikipedia links below.
+    _EXPN_BIAS = {16: 16, 32: 127, 64: 1023}
+    _N_EXPN_BITS = {16: 5, 32: 8, 64: 8}
+    _N_FRAC_BITS = {16: 10, 32: 23, 64: 52}
+    _FLOAT_NAME = {16: "float16", 32: "float", 64: "double"}
+
+    def read_float_value(self, length):
+        """Reads a floating point number of length, which must be 16 (float16), 32 (float),
+        or 64 (double). See: http://en.wikipedia.org/wiki/IEEE_floating-point_standard"""
+
+        if length not in BitStream._FLOAT_NAME:
+            raise ValueError, "length is not 16, 32 or 64."
+        
+        sign = self.read_bit()
+        expn = self.read_int_value(BitStream._N_EXPN_BITS[length])
+        frac = self.read_int_value(BitStream._N_FRAC_BITS[length])
+        
+        frac_total = float(1 << BitStream._N_FRAC_BITS[length])
+
+        if expn == 0:
+            if frac == 0:
+                return 0
+            else:
+                return ~frac + 1 if sign else frac
+        elif expn == frac_total - 1:
+            if frac == 0:
+                return float("-inf") if sign else float("inf")
+            else:
+                return float("nan")
+
+        return (-1 if sign else 1) * 2**(expn - BitStream._EXPN_BIAS[length]) * (1 + frac / frac_total)
+
+    def write_float_value(self, value, length):
+        """Writes a floating point number of length, which must be 16 (float16),
+        32 (float), or 64 (double). See: http://en.wikipedia.org/wiki/IEEE_floating-point_standard"""
+        
+        if length not in BitStream._FLOAT_NAME:
+            raise ValueError, "length is not 16, 32 or 64."
+        
+        if value == 0: # value is zero, so we don't care about length
+            self.write_int_value(0, length)
+        
+        if math.isnan(value):
+            self.one_fill(length)
+            return
+        elif value == float("-inf"): # negative infinity
+            self.one_fill(BitStream._N_EXPN_BITS[length] + 1) # sign merged
+            self.zero_fill(BitStream._N_FRAC_BITS[length])
+            return
+        elif value == float("inf"): # positive infinity
+            self.write_bit(False)
+            self.one_fill(BitStream._N_EXPN_BITS[length])
+            self.zero_fill(BitStream._N_FRAC_BITS[length])
+            return
+
+        if value < 0:
+            self.write_bit(True)
+            value = ~value + 1
+        else:
+            self.write_bit(False)
+        
+        exp = BitStream._EXPN_BIAS[length]
+        if value < 1:
+            while int(value) != 1:
+                value *= 2
+                exp -= 1
+        else:
+            while int(value) != 1:
+                value /= 2
+                exp += 1
+
+        if exp < 0 or exp > ( 1 << BitStream._N_EXPN_BITS[length] ):
+            raise ValueError, "Exponent out of range in %s [%d]." % (BitStream._FLOAT_NAME[length], length)
+
+        frac_total = 1 << BitStream._N_FRAC_BITS[length]
+        self.write_int_value(exp, BitStream._N_EXPN_BITS[length])
+        self.write_int_value(int((value-1)*frac_total) & (frac_total - 1), BitStream._N_FRAC_BITS[length])
+
+    
+    def one_fill(self, amount):
+        """Fills amount bits with one. The equivalent of calling
+        self.write_boolean(True) amount times, but more efficient."""
+
+        if amount > self.bits_available():
+            for i in range(amount - self.bits_available()):
+                self.bits.append(True)
+        
+        self.bits[self.cursor:self.cursor+amount] = [True] * amount
+        self.cursor += amount
+        
+    def zero_fill(self, amount):
+        """Fills amount bits with zero. The equivalent of calling
+        self.write_boolean(False) amount times, but more efficient."""
+
+        if amount > self.bits_available():
+            for i in range(amount - self.bits_available()):
+                self.bits.append(False)
+        
+        self.bits[self.cursor:self.cursor+amount] = [False] * amount
+        self.cursor += amount
+        
+    def seek(self, offset, whence=os.SEEK_SET):
+        if whence == os.SEEK_SET:
+            self.cursor = offset
+        elif whence == os.SEEK_CUR:
+            self.cursor += offset
+        elif whence == os.SEEK_END:
+            self.cursor = len(self.bits) - abs(offset)
+
+    def rewind(self):
+        self.seek(0, os.SEEK_SET)
+        
+    def skip_to_end(self):
+        self.seek(0, os.SEEK_END)
+
+    def bits_available(self):
+        return len(self.bits) - self.cursor
+
+    def flush(self):
+        self.zero_fill(8 - (len(self) % 8))
+
+    def chunk(self):
+        self.chunks.add(int(math.ceil(self.cursor / 8.)))
+    
+    def __len__(self):
+        return len(self.bits)
+
+    def __getitem__(self, i):
+        return self.bits.__getitem__(i)
+
+    def __setitem__(self, i, v):
+        return self.bits.__setitem__(i, v)
+    
+    def __str__(self):
+        return "".join("1" if b else "0" for b in self.bits)
+
+    def __add__(self, bits):
+        b = BitStream()
+        b.write_bits(self)
+        b.write_bits(bits)
+        return b
+
+    def __iadd__(self, bits):
+        self.write_bits(bits)
+        return self
+    
+    def serialize(self, align=ALIGN_LEFT, endianness=None):
+        """Serialize bit array into a byte string, aligning either
+        on the right (ALIGN_RIGHT) or left (ALIGN_LEFT). Endianness
+        can also be "<" for little-endian modes."""
+        lst = self.bits[:]
+        leftover = len(lst) % 8
+        if leftover > 0:
+            if align == ALIGN_RIGHT:
+                lst[:0] = [False] * (8-leftover) # Insert some False values to pad the list so it is aligned to the right.
+            else:
+                lst += [False] * (8-leftover)
+        
+        lst = BitStream(lst)
+        tmp = [lst.read_int_value(8) for i in xrange(int(math.ceil(len(lst)/8.0)))]
+        
+        bytes = [None] * len(tmp)
+        if endianness == "<":
+            m = sorted(self.chunks) + [len(tmp)]
+            for start, end in zip(m, m[1::]):
+                bytes[start:end] = tmp[end-1:None if start == 0 else start-1:-1]
+        else:
+            bytes = tmp
+        return ''.join(chr(b) for b in bytes)
+
+    def parse(self, string, endianness="<"):
+        """Parse a bit array from a byte string into this BitStream."""
+        for char in string:
+            self.write_int_value(ord(char), 8)
+    



More information about the Pypy-commit mailing list