[pypy-commit] pypy py3.5-async: some more translation issues that showed up

plan_rich pypy.commits at gmail.com
Wed Aug 10 12:29:10 EDT 2016


Author: Richard Plangger <planrichi at gmail.com>
Branch: py3.5-async
Changeset: r86131:663016b57d78
Date: 2016-08-10 18:27 +0200
http://bitbucket.org/pypy/pypy/changeset/663016b57d78/

Log:	some more translation issues that showed up

diff --git a/pypy/interpreter/astcompiler/assemble.py.orig b/pypy/interpreter/astcompiler/assemble.py.orig
deleted file mode 100644
--- a/pypy/interpreter/astcompiler/assemble.py.orig
+++ /dev/null
@@ -1,765 +0,0 @@
-"""Python control flow graph generation and bytecode assembly."""
-
-import os
-from rpython.rlib import rfloat
-from rpython.rlib.objectmodel import specialize, we_are_translated
-
-from pypy.interpreter.astcompiler import ast, consts, misc, symtable
-from pypy.interpreter.error import OperationError
-from pypy.interpreter.pycode import PyCode
-from pypy.tool import stdlib_opcode as ops
-
-
-class StackDepthComputationError(Exception):
-    pass
-
-
-class Instruction(object):
-    """Represents a single opcode."""
-
-    def __init__(self, opcode, arg=0):
-        self.opcode = opcode
-        self.arg = arg
-        self.lineno = 0
-        self.has_jump = False
-
-    def size(self):
-        """Return the size of bytes of this instruction when it is
-        encoded.
-        """
-        if self.opcode >= ops.HAVE_ARGUMENT:
-            return (6 if self.arg > 0xFFFF else 3)
-        return 1
-
-    def jump_to(self, target, absolute=False):
-        """Indicate the target this jump instruction.
-
-        The opcode must be a JUMP opcode.
-        """
-        self.jump = (target, absolute)
-        self.has_jump = True
-
-    def __repr__(self):
-        data = [ops.opname[self.opcode]]
-        template = "<%s"
-        if self.opcode >= ops.HAVE_ARGUMENT:
-            data.append(self.arg)
-            template += " %i"
-            if self.has_jump:
-                data.append(self.jump[0])
-                template += " %s"
-        template += ">"
-        return template % tuple(data)
-
-
-class Block(object):
-    """A basic control flow block.
-
-    It has one entry point and several possible exit points.  Its
-    instructions may be jumps to other blocks, or if control flow
-    reaches the end of the block, it continues to next_block.
-    """
-
-    marked = False
-    have_return = False
-    auto_inserted_return = False
-
-    def __init__(self):
-        self.instructions = []
-        self.next_block = None
-
-    def _post_order_see(self, stack, nextblock):
-        if nextblock.marked == 0:
-            nextblock.marked = 1
-            stack.append(nextblock)
-
-    def post_order(self):
-        """Return this block and its children in post order.  This means
-        that the graph of blocks is first cleaned up to ignore
-        back-edges, thus turning it into a DAG.  Then the DAG is
-        linearized.  For example:
-
-                   A --> B -\           =>     [A, D, B, C]
-                     \-> D ---> C
-        """
-        resultblocks = []
-        stack = [self]
-        self.marked = 1
-        while stack:
-            current = stack[-1]
-            if current.marked == 1:
-                current.marked = 2
-                if current.next_block is not None:
-                    self._post_order_see(stack, current.next_block)
-            else:
-                i = current.marked - 2
-                assert i >= 0
-                while i < len(current.instructions):
-                    instr = current.instructions[i]
-                    i += 1
-                    if instr.has_jump:
-                        current.marked = i + 2
-                        self._post_order_see(stack, instr.jump[0])
-                        break
-                else:
-                    resultblocks.append(current)
-                    stack.pop()
-        resultblocks.reverse()
-        return resultblocks
-
-    def code_size(self):
-        """Return the encoded size of all the instructions in this
-        block.
-        """
-        i = 0
-        for instr in self.instructions:
-            i += instr.size()
-        return i
-
-    def get_code(self):
-        """Encode the instructions in this block into bytecode."""
-        code = []
-        for instr in self.instructions:
-            opcode = instr.opcode
-            if opcode >= ops.HAVE_ARGUMENT:
-                arg = instr.arg
-                if instr.arg > 0xFFFF:
-                    ext = arg >> 16
-                    code.append(chr(ops.EXTENDED_ARG))
-                    code.append(chr(ext & 0xFF))
-                    code.append(chr(ext >> 8))
-                    arg &= 0xFFFF
-                code.append(chr(opcode))
-                code.append(chr(arg & 0xFF))
-                code.append(chr(arg >> 8))
-            else:
-                code.append(chr(opcode))
-        return ''.join(code)
-
-
-def _make_index_dict_filter(syms, flag):
-    i = 0
-    result = {}
-    for name, scope in syms.iteritems():
-        if scope == flag:
-            result[name] = i
-            i += 1
-    return result
-
-
- at specialize.argtype(0)
-def _iter_to_dict(iterable, offset=0):
-    result = {}
-    index = offset
-    for item in iterable:
-        result[item] = index
-        index += 1
-    return result
-
-
-class PythonCodeMaker(ast.ASTVisitor):
-    """Knows how to assemble a PyCode object."""
-
-    def __init__(self, space, name, first_lineno, scope, compile_info):
-        self.space = space
-        self.name = name
-        self.first_lineno = first_lineno
-        self.compile_info = compile_info
-        self.first_block = self.new_block()
-        self.use_block(self.first_block)
-        self.names = {}
-        self.var_names = _iter_to_dict(scope.varnames)
-        self.cell_vars = _make_index_dict_filter(scope.symbols,
-                                                 symtable.SCOPE_CELL)
-        self.free_vars = _iter_to_dict(scope.free_vars, len(self.cell_vars))
-        self.w_consts = space.newdict()
-        self.argcount = 0
-        self.kwonlyargcount = 0
-        self.lineno_set = False
-        self.lineno = 0
-        self.add_none_to_final_return = True
-
-    def new_block(self):
-        return Block()
-
-    def use_block(self, block):
-        """Start emitting bytecode into block."""
-        self.current_block = block
-        self.instrs = block.instructions
-
-    def use_next_block(self, block=None):
-        """Set this block as the next_block for the last and use it."""
-        if block is None:
-            block = self.new_block()
-        self.current_block.next_block = block
-        self.use_block(block)
-        return block
-
-    def is_dead_code(self):
-        """Return False if any code can be meaningfully added to the
-        current block, or True if it would be dead code."""
-        # currently only True after a RETURN_VALUE.
-        return self.current_block.have_return
-
-    def emit_op(self, op):
-        """Emit an opcode without an argument."""
-        instr = Instruction(op)
-        if not self.lineno_set:
-            instr.lineno = self.lineno
-            self.lineno_set = True
-        if not self.is_dead_code():
-            self.instrs.append(instr)
-            if op == ops.RETURN_VALUE:
-                self.current_block.have_return = True
-        return instr
-
-    def emit_op_arg(self, op, arg):
-        """Emit an opcode with an integer argument."""
-        instr = Instruction(op, arg)
-        if not self.lineno_set:
-            instr.lineno = self.lineno
-            self.lineno_set = True
-        if not self.is_dead_code():
-            self.instrs.append(instr)
-
-    def emit_op_name(self, op, container, name):
-        """Emit an opcode referencing a name."""
-        self.emit_op_arg(op, self.add_name(container, name))
-
-    def emit_jump(self, op, block_to, absolute=False):
-        """Emit a jump opcode to another block."""
-        self.emit_op(op).jump_to(block_to, absolute)
-
-    def add_name(self, container, name):
-        """Get the index of a name in container."""
-        name = self.scope.mangle(name)
-        try:
-            index = container[name]
-        except KeyError:
-            index = len(container)
-            container[name] = index
-        return index
-
-    def add_const(self, obj):
-        """Add a W_Root to the constant array and return its location."""
-        space = self.space
-        # To avoid confusing equal but separate types, we hash store the type
-        # of the constant in the dictionary.  Moreover, we have to keep the
-        # difference between -0.0 and 0.0 floats, and this recursively in
-        # tuples.
-        w_key = self._make_key(obj)
-
-        w_len = space.finditem(self.w_consts, w_key)
-        if w_len is None:
-            w_len = space.len(self.w_consts)
-            space.setitem(self.w_consts, w_key, w_len)
-        if space.int_w(w_len) == 0:
-            self.scope.doc_removable = False
-        return space.int_w(w_len)
-
-    def _make_key(self, obj):
-        # see the tests 'test_zeros_not_mixed*' in ../test/test_compiler.py
-        space = self.space
-        w_type = space.type(obj)
-        if space.is_w(w_type, space.w_float):
-            val = space.float_w(obj)
-            if val == 0.0 and rfloat.copysign(1., val) < 0:
-                w_key = space.newtuple([obj, space.w_float, space.w_None])
-            else:
-                w_key = space.newtuple([obj, space.w_float])
-        elif space.is_w(w_type, space.w_complex):
-            w_real = space.getattr(obj, space.wrap("real"))
-            w_imag = space.getattr(obj, space.wrap("imag"))
-            real = space.float_w(w_real)
-            imag = space.float_w(w_imag)
-            real_negzero = (real == 0.0 and
-                            rfloat.copysign(1., real) < 0)
-            imag_negzero = (imag == 0.0 and
-                            rfloat.copysign(1., imag) < 0)
-            if real_negzero and imag_negzero:
-                tup = [obj, space.w_complex, space.w_None, space.w_None,
-                       space.w_None]
-            elif imag_negzero:
-                tup = [obj, space.w_complex, space.w_None, space.w_None]
-            elif real_negzero:
-                tup = [obj, space.w_complex, space.w_None]
-            else:
-                tup = [obj, space.w_complex]
-            w_key = space.newtuple(tup)
-        elif space.is_w(w_type, space.w_tuple):
-            result_w = [obj, w_type]
-            for w_item in space.fixedview(obj):
-                result_w.append(self._make_key(w_item))
-            w_key = space.newtuple(result_w[:])
-        elif isinstance(obj, PyCode):
-            w_key = space.newtuple([obj, w_type, space.id(obj)])
-        else:
-            w_key = space.newtuple([obj, w_type])
-        return w_key
-
-    def load_const(self, obj):
-        index = self.add_const(obj)
-        self.emit_op_arg(ops.LOAD_CONST, index)
-
-    def update_position(self, lineno, force=False):
-        """Possibly change the lineno for the next instructions."""
-        if force or lineno > self.lineno:
-            self.lineno = lineno
-            self.lineno_set = False
-
-    def _resolve_block_targets(self, blocks):
-        """Compute the arguments of jump instructions."""
-        last_extended_arg_count = 0
-        # The reason for this loop is extended jumps.  EXTENDED_ARG
-        # extends the bytecode size, so it might invalidate the offsets
-        # we've already given.  Thus we have to loop until the number of
-        # extended args is stable.  Any extended jump at all is
-        # extremely rare, so performance is not too concerning.
-        while True:
-            extended_arg_count = 0
-            offset = 0
-            force_redo = False
-            # Calculate the code offset of each block.
-            for block in blocks:
-                block.offset = offset
-                offset += block.code_size()
-            for block in blocks:
-                offset = block.offset
-                for instr in block.instructions:
-                    offset += instr.size()
-                    if instr.has_jump:
-                        target, absolute = instr.jump
-                        op = instr.opcode
-                        # Optimize an unconditional jump going to another
-                        # unconditional jump.
-                        if op == ops.JUMP_ABSOLUTE or op == ops.JUMP_FORWARD:
-                            if target.instructions:
-                                target_op = target.instructions[0].opcode
-                                if target_op == ops.JUMP_ABSOLUTE:
-                                    target = target.instructions[0].jump[0]
-                                    instr.opcode = ops.JUMP_ABSOLUTE
-                                    absolute = True
-                                elif target_op == ops.RETURN_VALUE:
-                                    # Replace JUMP_* to a RETURN into
-                                    # just a RETURN
-                                    instr.opcode = ops.RETURN_VALUE
-                                    instr.arg = 0
-                                    instr.has_jump = False
-                                    # The size of the code changed,
-                                    # we have to trigger another pass
-                                    force_redo = True
-                                    continue
-                        if absolute:
-                            jump_arg = target.offset
-                        else:
-                            jump_arg = target.offset - offset
-                        instr.arg = jump_arg
-                        if jump_arg > 0xFFFF:
-                            extended_arg_count += 1
-            if (extended_arg_count == last_extended_arg_count and
-                not force_redo):
-                break
-            else:
-                last_extended_arg_count = extended_arg_count
-
-    def _build_consts_array(self):
-        """Turn the applevel constants dictionary into a list."""
-        w_consts = self.w_consts
-        space = self.space
-        consts_w = [space.w_None] * space.len_w(w_consts)
-        w_iter = space.iter(w_consts)
-        first = space.wrap(0)
-        while True:
-            try:
-                w_key = space.next(w_iter)
-            except OperationError as e:
-                if not e.match(space, space.w_StopIteration):
-                    raise
-                break
-            w_index = space.getitem(w_consts, w_key)
-            w_constant = space.getitem(w_key, first)
-            w_constant = misc.intern_if_common_string(space, w_constant)
-            consts_w[space.int_w(w_index)] = w_constant
-        return consts_w
-
-    def _get_code_flags(self):
-        """Get an extra flags that should be attached to the code object."""
-        raise NotImplementedError
-
-    def _stacksize(self, blocks):
-        """Compute co_stacksize."""
-        for block in blocks:
-            block.initial_depth = 0
-        # Assumes that it is sufficient to walk the blocks in 'post-order'.
-        # This means we ignore all back-edges, but apart from that, we only
-        # look into a block when all the previous blocks have been done.
-        self._max_depth = 0
-        for block in blocks:
-            depth = self._do_stack_depth_walk(block)
-            if block.auto_inserted_return and depth != 0:
-                os.write(2, "StackDepthComputationError in %s at %s:%s\n" % (
-                    self.compile_info.filename, self.name, self.first_lineno))
-                raise StackDepthComputationError   # fatal error
-        return self._max_depth
-
-    def _next_stack_depth_walk(self, nextblock, depth):
-        if depth > nextblock.initial_depth:
-            nextblock.initial_depth = depth
-
-    def _do_stack_depth_walk(self, block):
-        depth = block.initial_depth
-        for instr in block.instructions:
-            depth += _opcode_stack_effect(instr.opcode, instr.arg)
-            if depth >= self._max_depth:
-                self._max_depth = depth
-            jump_op = instr.opcode
-            if instr.has_jump:
-                target_depth = depth
-                if jump_op == ops.FOR_ITER:
-                    target_depth -= 2
-                elif (jump_op == ops.SETUP_FINALLY or
-                      jump_op == ops.SETUP_EXCEPT or
-                      jump_op == ops.SETUP_WITH):
-                    if jump_op == ops.SETUP_FINALLY:
-                        target_depth += 4
-                    elif jump_op == ops.SETUP_EXCEPT:
-                        target_depth += 4
-                    elif jump_op == ops.SETUP_WITH:
-                        target_depth += 3
-                    if target_depth > self._max_depth:
-                        self._max_depth = target_depth
-                elif (jump_op == ops.JUMP_IF_TRUE_OR_POP or
-                      jump_op == ops.JUMP_IF_FALSE_OR_POP):
-                    depth -= 1
-                self._next_stack_depth_walk(instr.jump[0], target_depth)
-                if jump_op == ops.JUMP_ABSOLUTE or jump_op == ops.JUMP_FORWARD:
-                    # Nothing more can occur.
-                    break
-            elif jump_op == ops.RETURN_VALUE or jump_op == ops.RAISE_VARARGS:
-                # Nothing more can occur.
-                break
-        else:
-            if block.next_block:
-                self._next_stack_depth_walk(block.next_block, depth)
-        return depth
-
-    def _build_lnotab(self, blocks):
-        """Build the line number table for tracebacks and tracing."""
-        current_line = self.first_lineno
-        current_off = 0
-        table = []
-        push = table.append
-        for block in blocks:
-            offset = block.offset
-            for instr in block.instructions:
-                if instr.lineno:
-                    # compute deltas
-                    line = instr.lineno - current_line
-                    if line < 0:
-                        continue
-                    addr = offset - current_off
-                    # Python assumes that lineno always increases with
-                    # increasing bytecode address (lnotab is unsigned
-                    # char).  Depending on when SET_LINENO instructions
-                    # are emitted this is not always true.  Consider the
-                    # code:
-                    #     a = (1,
-                    #          b)
-                    # In the bytecode stream, the assignment to "a"
-                    # occurs after the loading of "b".  This works with
-                    # the C Python compiler because it only generates a
-                    # SET_LINENO instruction for the assignment.
-                    if line or addr:
-                        while addr > 255:
-                            push(chr(255))
-                            push(chr(0))
-                            addr -= 255
-                        while line > 255:
-                            push(chr(addr))
-                            push(chr(255))
-                            line -= 255
-                            addr = 0
-                        push(chr(addr))
-                        push(chr(line))
-                        current_line = instr.lineno
-                        current_off = offset
-                offset += instr.size()
-        return ''.join(table)
-
-    def assemble(self):
-        """Build a PyCode object."""
-        # Unless it's interactive, every code object must end in a return.
-        if not self.current_block.have_return:
-            self.use_next_block()
-            if self.add_none_to_final_return:
-                self.load_const(self.space.w_None)
-            self.emit_op(ops.RETURN_VALUE)
-            self.current_block.auto_inserted_return = True
-        # Set the first lineno if it is not already explicitly set.
-        if self.first_lineno == -1:
-            if self.first_block.instructions:
-                self.first_lineno = self.first_block.instructions[0].lineno
-            else:
-                self.first_lineno = 1
-        blocks = self.first_block.post_order()
-        self._resolve_block_targets(blocks)
-        lnotab = self._build_lnotab(blocks)
-        stack_depth = self._stacksize(blocks)
-        consts_w = self._build_consts_array()
-        names = _list_from_dict(self.names)
-        var_names = _list_from_dict(self.var_names)
-        cell_names = _list_from_dict(self.cell_vars)
-        free_names = _list_from_dict(self.free_vars, len(cell_names))
-        flags = self._get_code_flags()
-        # (Only) inherit compilerflags in PyCF_MASK
-        flags |= (self.compile_info.flags & consts.PyCF_MASK)
-        bytecode = ''.join([block.get_code() for block in blocks])
-        return PyCode(self.space,
-                      self.argcount,
-                      self.kwonlyargcount,
-                      len(self.var_names),
-                      stack_depth,
-                      flags,
-                      bytecode,
-                      list(consts_w),
-                      names,
-                      var_names,
-                      self.compile_info.filename,
-                      self.name,
-                      self.first_lineno,
-                      lnotab,
-                      free_names,
-                      cell_names,
-                      self.compile_info.hidden_applevel)
-
-
-def _list_from_dict(d, offset=0):
-    result = [None] * len(d)
-    for obj, index in d.iteritems():
-        result[index - offset] = obj
-    return result
-
-
-_static_opcode_stack_effects = {
-    ops.NOP: 0,
-
-    ops.POP_TOP: -1,
-    ops.ROT_TWO: 0,
-    ops.ROT_THREE: 0,
-    ops.DUP_TOP: 1,
-    ops.DUP_TOP_TWO: 2,
-
-    ops.UNARY_POSITIVE: 0,
-    ops.UNARY_NEGATIVE: 0,
-    ops.UNARY_NOT: 0,
-    ops.UNARY_INVERT: 0,
-
-    ops.LIST_APPEND: -1,
-    ops.SET_ADD: -1,
-    ops.MAP_ADD: -2,
-<<<<<<< local
-=======
-    # XXX 
-    ops.STORE_MAP: -2,
->>>>>>> other
-
-    ops.BINARY_POWER: -1,
-    ops.BINARY_MULTIPLY: -1,
-    ops.BINARY_MODULO: -1,
-    ops.BINARY_ADD: -1,
-    ops.BINARY_SUBTRACT: -1,
-    ops.BINARY_SUBSCR: -1,
-    ops.BINARY_FLOOR_DIVIDE: -1,
-    ops.BINARY_TRUE_DIVIDE: -1,
-    ops.BINARY_MATRIX_MULTIPLY: -1,
-    ops.BINARY_LSHIFT: -1,
-    ops.BINARY_RSHIFT: -1,
-    ops.BINARY_AND: -1,
-    ops.BINARY_OR: -1,
-    ops.BINARY_XOR: -1,
-
-    ops.INPLACE_FLOOR_DIVIDE: -1,
-    ops.INPLACE_TRUE_DIVIDE: -1,
-    ops.INPLACE_ADD: -1,
-    ops.INPLACE_SUBTRACT: -1,
-    ops.INPLACE_MULTIPLY: -1,
-    ops.INPLACE_MODULO: -1,
-    ops.INPLACE_POWER: -1,
-    ops.INPLACE_MATRIX_MULTIPLY: -1,
-    ops.INPLACE_LSHIFT: -1,
-    ops.INPLACE_RSHIFT: -1,
-    ops.INPLACE_AND: -1,
-    ops.INPLACE_OR: -1,
-    ops.INPLACE_XOR: -1,
-
-    ops.STORE_SUBSCR: -3,
-    ops.DELETE_SUBSCR: -2,
-
-    ops.GET_ITER: 0,
-    ops.FOR_ITER: 1,
-    ops.BREAK_LOOP: 0,
-    ops.CONTINUE_LOOP: 0,
-    ops.SETUP_LOOP: 0,
-
-    ops.PRINT_EXPR: -1,
-
-<<<<<<< local
-    ops.WITH_CLEANUP_START: -1,
-    ops.WITH_CLEANUP_FINISH: -1,  # XXX Sometimes more
-=======
-    # TODO 
-    ops.WITH_CLEANUP: -1,
->>>>>>> other
-    ops.LOAD_BUILD_CLASS: 1,
-<<<<<<< local
-=======
-    # TODO 
-    ops.STORE_LOCALS: -1,
->>>>>>> other
-    ops.POP_BLOCK: 0,
-    ops.POP_EXCEPT: -1,
-    ops.END_FINALLY: -4,     # assume always 4: we pretend that SETUP_FINALLY
-                             # pushes 4.  In truth, it would only push 1 and
-                             # the corresponding END_FINALLY only pops 1.
-    ops.SETUP_WITH: 1,
-    ops.SETUP_FINALLY: 0,
-    ops.SETUP_EXCEPT: 0,
-
-    ops.RETURN_VALUE: -1,
-    ops.YIELD_VALUE: 0,
-    ops.YIELD_FROM: -1,
-    ops.COMPARE_OP: -1,
-
-    # TODO 
-    ops.LOOKUP_METHOD: 1,
-
-    ops.LOAD_NAME: 1,
-    ops.STORE_NAME: -1,
-    ops.DELETE_NAME: 0,
-
-    ops.LOAD_FAST: 1,
-    ops.STORE_FAST: -1,
-    ops.DELETE_FAST: 0,
-
-    ops.LOAD_ATTR: 0,
-    ops.STORE_ATTR: -2,
-    ops.DELETE_ATTR: -1,
-
-    ops.LOAD_GLOBAL: 1,
-    ops.STORE_GLOBAL: -1,
-    ops.DELETE_GLOBAL: 0,
-    ops.DELETE_DEREF: 0,
-
-    ops.LOAD_CLOSURE: 1,
-    ops.LOAD_DEREF: 1,
-    ops.STORE_DEREF: -1,
-    ops.DELETE_DEREF: 0,
-
-    ops.LOAD_CONST: 1,
-
-    ops.IMPORT_STAR: -1,
-    ops.IMPORT_NAME: -1,
-    ops.IMPORT_FROM: 1,
-
-    ops.JUMP_FORWARD: 0,
-    ops.JUMP_ABSOLUTE: 0,
-    ops.JUMP_IF_TRUE_OR_POP: 0,
-    ops.JUMP_IF_FALSE_OR_POP: 0,
-    ops.POP_JUMP_IF_TRUE: -1,
-    ops.POP_JUMP_IF_FALSE: -1,
-    # TODO 
-    ops.JUMP_IF_NOT_DEBUG: 0,
-
-    # TODO 
-    ops.BUILD_LIST_FROM_ARG: 1,
-}
-
-
-def _compute_UNPACK_SEQUENCE(arg):
-    return arg - 1
-
-def _compute_UNPACK_EX(arg):
-    return (arg & 0xFF) + (arg >> 8)
-
-def _compute_BUILD_TUPLE(arg):
-    return 1 - arg
-
-def _compute_BUILD_LIST(arg):
-    return 1 - arg
-
-def _compute_BUILD_SET(arg):
-    return 1 - arg
-
-def _compute_BUILD_MAP(arg):
-    return 1 - 2 * arg
-
-def _compute_BUILD_MAP_UNPACK(arg):
-    return 1 - arg
-
-def _compute_MAKE_CLOSURE(arg):
-    return -2 - _num_args(arg) - ((arg >> 16) & 0xFFFF)
-
-def _compute_MAKE_FUNCTION(arg):
-    return -1 - _num_args(arg) - ((arg >> 16) & 0xFFFF)
-
-def _compute_BUILD_SLICE(arg):
-    if arg == 3:
-        return -2
-    else:
-        return -1
-
-def _compute_RAISE_VARARGS(arg):
-    return -arg
-
-def _num_args(oparg):
-    return (oparg % 256) + 2 * ((oparg // 256) % 256)
-
-def _compute_CALL_FUNCTION(arg):
-    return -_num_args(arg)
-
-def _compute_CALL_FUNCTION_VAR(arg):
-    return -_num_args(arg) - 1
-
-def _compute_CALL_FUNCTION_KW(arg):
-    return -_num_args(arg) - 1
-
-def _compute_CALL_FUNCTION_VAR_KW(arg):
-    return -_num_args(arg) - 2
-
-def _compute_CALL_METHOD(arg):
-    return -_num_args(arg) - 1
-
-
-_stack_effect_computers = {}
-for name, func in globals().items():
-    if name.startswith("_compute_"):
-        func._always_inline_ = True
-        _stack_effect_computers[getattr(ops, name[9:])] = func
-for op, value in _static_opcode_stack_effects.iteritems():
-    def func(arg, _value=value):
-        return _value
-    func._always_inline_ = True
-    _stack_effect_computers[op] = func
-del name, func, op, value
-
-
-def _opcode_stack_effect(op, arg):
-    """Return the stack effect of a opcode an its argument."""
-    if we_are_translated():
-        for possible_op in ops.unrolling_opcode_descs:
-            # EXTENDED_ARG should never get in here.
-            if possible_op.index == ops.EXTENDED_ARG:
-                continue
-            if op == possible_op.index:
-                return _stack_effect_computers[possible_op.index](arg)
-        else:
-            raise AssertionError("unknown opcode: %s" % (op,))
-    else:
-        try:
-            return _static_opcode_stack_effects[op]
-        except KeyError:
-            try:
-                return _stack_effect_computers[op](arg)
-            except KeyError:
-                raise KeyError("Unknown stack effect for %s (%s)" %
-                               (ops.opname[op], op))
diff --git a/pypy/interpreter/astcompiler/astbuilder.py b/pypy/interpreter/astcompiler/astbuilder.py
--- a/pypy/interpreter/astcompiler/astbuilder.py
+++ b/pypy/interpreter/astcompiler/astbuilder.py
@@ -4,6 +4,7 @@
 from pypy.interpreter.pyparser.pygram import syms, tokens
 from pypy.interpreter.pyparser.error import SyntaxError
 from pypy.interpreter.pyparser import parsestring
+from rpython.rlib.objectmodel import always_inline
 
 
 def ast_from_node(space, node, compile_info):
@@ -1169,6 +1170,7 @@
                 raise
             return self.space.call_function(self.space.w_float, w_num_str)
 
+    @always_inline
     def handle_dictelement(self, node, i):
         if node.get_child(i).type == tokens.DOUBLESTAR:
             key = None
@@ -1178,7 +1180,7 @@
             key = self.handle_expr(node.get_child(i))
             value = self.handle_expr(node.get_child(i+2))
             i += 3
-        return [i,key,value]
+        return (i,key,value)
     
     def handle_atom(self, atom_node):
         first_child = atom_node.get_child(0)
@@ -1374,10 +1376,7 @@
                            set_maker.get_column())
 
     def handle_dictcomp(self, dict_maker):
-        dictelement = self.handle_dictelement(dict_maker, 0)
-        i = dictelement[0]
-        key = dictelement[1]
-        value = dictelement[2]
+        i, key, value = self.handle_dictelement(dict_maker, 0)
         comps = self.comprehension_helper(dict_maker.get_child(i))
         return ast.DictComp(key, value, comps, dict_maker.get_lineno(),
                             dict_maker.get_column())
@@ -1387,10 +1386,9 @@
         values = []
         i = 0
         while i < node.num_children():
-            dictelement = self.handle_dictelement(node, i)
-            i = dictelement[0]
-            keys.append(dictelement[1])
-            values.append(dictelement[2])
+            i, key, value = self.handle_dictelement(node, i)
+            keys.append(key)
+            values.append(value)
             i += 1
         return ast.Dict(keys, values, node.get_lineno(), node.get_column())
     
diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -441,8 +441,7 @@
         # 4. load class name
         self.load_const(self.space.wrap(cls.name.decode('utf-8')))
         # 5. generate the rest of the code for the call
-        self._make_call(2,
-                        cls.bases, cls.keywords)
+        self._make_call(2, cls.bases, cls.keywords)
         # 6. apply decorators
         if cls.decorator_list:
             for i in range(len(cls.decorator_list)):
@@ -1348,8 +1347,7 @@
         if self._optimize_method_call(call):
             return
         call.func.walkabout(self)
-        self._make_call(0,
-                        call.args, call.keywords)
+        self._make_call(0, call.args, call.keywords)
     
     def _call_has_no_star_args(self, call):
         if call.args is not None:
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -1056,7 +1056,7 @@
         w_value = self.popvalue()
         w_gen = self.peekvalue()
         if isinstance(w_gen, Coroutine):
-            if (w_gen.descr_gi_code(w_gen).co_flags & consts.CO_COROUTINE and
+            if (w_gen.descr_gi_code(space).co_flags & consts.CO_COROUTINE and
                not self.pycode.co_flags & (consts.CO_COROUTINE |
                                        consts.CO_ITERABLE_COROUTINE)):
                 raise oefmt(self.space.w_TypeError,
@@ -1479,27 +1479,29 @@
         self.pushvalue(res)
     
     def BEFORE_ASYNC_WITH(self, oparg, next_instr):
+        space = self.space
         w_manager = self.peekvalue()
-        w_enter = self.space.lookup(w_manager, "__aenter__")
-        w_descr = self.space.lookup(w_manager, "__aexit__")
+        w_enter = space.lookup(w_manager, "__aenter__")
+        w_descr = space.lookup(w_manager, "__aexit__")
         if w_enter is None or w_descr is None:
-            raise oefmt(self.space.w_AttributeError,
+            raise oefmt(space.w_AttributeError,
                         "'%T' object is not a context manager (no __aenter__/"
                         "__aexit__ method)", w_manager)
-        w_exit = self.space.get(w_descr, w_manager)
+        w_exit = space.get(w_descr, w_manager)
         self.settopvalue(w_exit)
-        w_result = self.space.get_and_call_function(w_enter, w_manager)
+        w_result = space.get_and_call_function(w_enter, w_manager)
         self.pushvalue(w_result)
     
     def GET_AITER(self, oparg, next_instr):
+        space = self.space
         w_obj = self.peekvalue()
-        w_func = self.space.lookup(w_obj, "__aiter__")
+        w_func = space.lookup(w_obj, "__aiter__")
         if w_func is None:
             raise oefmt(space.w_AttributeError,
                         "object %T does not have __aiter__ method",
                         w_obj)
         w_iter = space.get_and_call_function(w_func, w_obj)
-        w_awaitable = w_iter._GetAwaitableIter(self.space)
+        w_awaitable = w_iter._GetAwaitableIter(space)
         if w_awaitable is None:
             raise oefmt(space.w_TypeError,
                         "'async for' received an invalid object "
@@ -1507,14 +1509,15 @@
         self.settopvalue(w_awaitable)
     
     def GET_ANEXT(self, oparg, next_instr):
+        space = self.space
         w_aiter = self.peekvalue()
-        w_func = self.space.lookup(w_aiter, "__anext__")
+        w_func = space.lookup(w_aiter, "__anext__")
         if w_func is None:
             raise oefmt(space.w_AttributeError,
                         "object %T does not have __anext__ method",
                         w_aiter)
         w_next_iter = space.get_and_call_function(w_func, w_aiter)
-        w_awaitable = w_next_iter._GetAwaitableIter(self.space)
+        w_awaitable = w_next_iter._GetAwaitableIter(space)
         if w_awaitable is None:
             raise oefmt(space.w_TypeError,
                         "'async for' received an invalid object "
diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py
--- a/pypy/module/zipimport/interp_zipimport.py
+++ b/pypy/module/zipimport/interp_zipimport.py
@@ -85,7 +85,7 @@
     def iteratekeys(self, space):
         return space.iter(self.keys(space))
 
-    def itervalues(self, space):
+    def iteratevalues(self, space):
         return space.iter(self.values(space))
 
     def iteritems(self, space):
@@ -112,7 +112,7 @@
     keys = interp2app(W_ZipCache.keys),
     iterkeys = interp2app(W_ZipCache.iteratekeys),
     values = interp2app(W_ZipCache.values),
-    itervalues = interp2app(W_ZipCache.itervalues),
+    itervalues = interp2app(W_ZipCache.iteratevalues),
     clear = interp2app(W_ZipCache.clear),
     __delitem__ = interp2app(W_ZipCache.delitem),
 )


More information about the pypy-commit mailing list