mirror of https://github.com/python/cpython
Use new _implicitNameOp() to generate name op code for list comprehensions.
Always emit a SET_LINENO 0 at the beginning of the module. The builtin compiler does this, and it's much easier to compare bytecode generated by the two compilers if they both do. Move the SET_LINENO inside the FOR_LOOP block for list comprehensions. Also for compat. with builtin compiler.
This commit is contained in:
parent
23f7aed2a7
commit
13d70944cb
|
@ -193,6 +193,18 @@ class CodeGenerator:
|
||||||
else:
|
else:
|
||||||
self.emit(prefix + '_GLOBAL', name)
|
self.emit(prefix + '_GLOBAL', name)
|
||||||
|
|
||||||
|
def _implicitNameOp(self, prefix, name):
|
||||||
|
"""Emit name ops for names generated implicitly by for loops
|
||||||
|
|
||||||
|
The interpreter generates names that start with a period or
|
||||||
|
dollar sign. The symbol table ignores these names because
|
||||||
|
they aren't present in the program text.
|
||||||
|
"""
|
||||||
|
if self.optimized:
|
||||||
|
self.emit(prefix + '_FAST', name)
|
||||||
|
else:
|
||||||
|
self.emit(prefix + '_NAME', name)
|
||||||
|
|
||||||
def set_lineno(self, node, force=0):
|
def set_lineno(self, node, force=0):
|
||||||
"""Emit SET_LINENO if node has lineno attribute and it is
|
"""Emit SET_LINENO if node has lineno attribute and it is
|
||||||
different than the last lineno emitted.
|
different than the last lineno emitted.
|
||||||
|
@ -221,6 +233,7 @@ class CodeGenerator:
|
||||||
ClassGen = None
|
ClassGen = None
|
||||||
|
|
||||||
def visitModule(self, node):
|
def visitModule(self, node):
|
||||||
|
self.emit('SET_LINENO', 0)
|
||||||
lnf = walk(node.node, self.NameFinder(), 0)
|
lnf = walk(node.node, self.NameFinder(), 0)
|
||||||
self.locals.push(lnf.getLocals())
|
self.locals.push(lnf.getLocals())
|
||||||
if node.doc:
|
if node.doc:
|
||||||
|
@ -421,7 +434,7 @@ class CodeGenerator:
|
||||||
self.emit('BUILD_LIST', 0)
|
self.emit('BUILD_LIST', 0)
|
||||||
self.emit('DUP_TOP')
|
self.emit('DUP_TOP')
|
||||||
self.emit('LOAD_ATTR', 'append')
|
self.emit('LOAD_ATTR', 'append')
|
||||||
self.emit('STORE_FAST', append)
|
self._implicitNameOp('STORE', append)
|
||||||
|
|
||||||
stack = []
|
stack = []
|
||||||
for i, for_ in zip(range(len(node.quals)), node.quals):
|
for i, for_ in zip(range(len(node.quals)), node.quals):
|
||||||
|
@ -433,7 +446,7 @@ class CodeGenerator:
|
||||||
self.visit(if_, cont)
|
self.visit(if_, cont)
|
||||||
stack.insert(0, (start, cont, anchor))
|
stack.insert(0, (start, cont, anchor))
|
||||||
|
|
||||||
self.emit('LOAD_FAST', append)
|
self._implicitNameOp('LOAD', append)
|
||||||
self.visit(node.expr)
|
self.visit(node.expr)
|
||||||
self.emit('CALL_FUNCTION', 1)
|
self.emit('CALL_FUNCTION', 1)
|
||||||
self.emit('POP_TOP')
|
self.emit('POP_TOP')
|
||||||
|
@ -447,7 +460,7 @@ class CodeGenerator:
|
||||||
self.nextBlock(skip_one)
|
self.nextBlock(skip_one)
|
||||||
self.emit('JUMP_ABSOLUTE', start)
|
self.emit('JUMP_ABSOLUTE', start)
|
||||||
self.startBlock(anchor)
|
self.startBlock(anchor)
|
||||||
self.emit('DELETE_FAST', append)
|
self._implicitNameOp('DELETE', append)
|
||||||
|
|
||||||
self.__list_count = self.__list_count - 1
|
self.__list_count = self.__list_count - 1
|
||||||
|
|
||||||
|
@ -457,8 +470,8 @@ class CodeGenerator:
|
||||||
|
|
||||||
self.visit(node.list)
|
self.visit(node.list)
|
||||||
self.visit(ast.Const(0))
|
self.visit(ast.Const(0))
|
||||||
self.emit('SET_LINENO', node.lineno)
|
|
||||||
self.nextBlock(start)
|
self.nextBlock(start)
|
||||||
|
self.emit('SET_LINENO', node.lineno)
|
||||||
self.emit('FOR_LOOP', anchor)
|
self.emit('FOR_LOOP', anchor)
|
||||||
self.nextBlock()
|
self.nextBlock()
|
||||||
self.visit(node.assign)
|
self.visit(node.assign)
|
||||||
|
|
|
@ -193,6 +193,18 @@ class CodeGenerator:
|
||||||
else:
|
else:
|
||||||
self.emit(prefix + '_GLOBAL', name)
|
self.emit(prefix + '_GLOBAL', name)
|
||||||
|
|
||||||
|
def _implicitNameOp(self, prefix, name):
|
||||||
|
"""Emit name ops for names generated implicitly by for loops
|
||||||
|
|
||||||
|
The interpreter generates names that start with a period or
|
||||||
|
dollar sign. The symbol table ignores these names because
|
||||||
|
they aren't present in the program text.
|
||||||
|
"""
|
||||||
|
if self.optimized:
|
||||||
|
self.emit(prefix + '_FAST', name)
|
||||||
|
else:
|
||||||
|
self.emit(prefix + '_NAME', name)
|
||||||
|
|
||||||
def set_lineno(self, node, force=0):
|
def set_lineno(self, node, force=0):
|
||||||
"""Emit SET_LINENO if node has lineno attribute and it is
|
"""Emit SET_LINENO if node has lineno attribute and it is
|
||||||
different than the last lineno emitted.
|
different than the last lineno emitted.
|
||||||
|
@ -221,6 +233,7 @@ class CodeGenerator:
|
||||||
ClassGen = None
|
ClassGen = None
|
||||||
|
|
||||||
def visitModule(self, node):
|
def visitModule(self, node):
|
||||||
|
self.emit('SET_LINENO', 0)
|
||||||
lnf = walk(node.node, self.NameFinder(), 0)
|
lnf = walk(node.node, self.NameFinder(), 0)
|
||||||
self.locals.push(lnf.getLocals())
|
self.locals.push(lnf.getLocals())
|
||||||
if node.doc:
|
if node.doc:
|
||||||
|
@ -421,7 +434,7 @@ class CodeGenerator:
|
||||||
self.emit('BUILD_LIST', 0)
|
self.emit('BUILD_LIST', 0)
|
||||||
self.emit('DUP_TOP')
|
self.emit('DUP_TOP')
|
||||||
self.emit('LOAD_ATTR', 'append')
|
self.emit('LOAD_ATTR', 'append')
|
||||||
self.emit('STORE_FAST', append)
|
self._implicitNameOp('STORE', append)
|
||||||
|
|
||||||
stack = []
|
stack = []
|
||||||
for i, for_ in zip(range(len(node.quals)), node.quals):
|
for i, for_ in zip(range(len(node.quals)), node.quals):
|
||||||
|
@ -433,7 +446,7 @@ class CodeGenerator:
|
||||||
self.visit(if_, cont)
|
self.visit(if_, cont)
|
||||||
stack.insert(0, (start, cont, anchor))
|
stack.insert(0, (start, cont, anchor))
|
||||||
|
|
||||||
self.emit('LOAD_FAST', append)
|
self._implicitNameOp('LOAD', append)
|
||||||
self.visit(node.expr)
|
self.visit(node.expr)
|
||||||
self.emit('CALL_FUNCTION', 1)
|
self.emit('CALL_FUNCTION', 1)
|
||||||
self.emit('POP_TOP')
|
self.emit('POP_TOP')
|
||||||
|
@ -447,7 +460,7 @@ class CodeGenerator:
|
||||||
self.nextBlock(skip_one)
|
self.nextBlock(skip_one)
|
||||||
self.emit('JUMP_ABSOLUTE', start)
|
self.emit('JUMP_ABSOLUTE', start)
|
||||||
self.startBlock(anchor)
|
self.startBlock(anchor)
|
||||||
self.emit('DELETE_FAST', append)
|
self._implicitNameOp('DELETE', append)
|
||||||
|
|
||||||
self.__list_count = self.__list_count - 1
|
self.__list_count = self.__list_count - 1
|
||||||
|
|
||||||
|
@ -457,8 +470,8 @@ class CodeGenerator:
|
||||||
|
|
||||||
self.visit(node.list)
|
self.visit(node.list)
|
||||||
self.visit(ast.Const(0))
|
self.visit(ast.Const(0))
|
||||||
self.emit('SET_LINENO', node.lineno)
|
|
||||||
self.nextBlock(start)
|
self.nextBlock(start)
|
||||||
|
self.emit('SET_LINENO', node.lineno)
|
||||||
self.emit('FOR_LOOP', anchor)
|
self.emit('FOR_LOOP', anchor)
|
||||||
self.nextBlock()
|
self.nextBlock()
|
||||||
self.visit(node.assign)
|
self.visit(node.assign)
|
||||||
|
|
Loading…
Reference in New Issue