Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 13d7094

Browse files
committed
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.
1 parent 23f7aed commit 13d7094

2 files changed

Lines changed: 34 additions & 8 deletions

File tree

Lib/compiler/pycodegen.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,18 @@ def _nameOp(self, prefix, name):
193193
else:
194194
self.emit(prefix + '_GLOBAL', name)
195195

196+
def _implicitNameOp(self, prefix, name):
197+
"""Emit name ops for names generated implicitly by for loops
198+
199+
The interpreter generates names that start with a period or
200+
dollar sign. The symbol table ignores these names because
201+
they aren't present in the program text.
202+
"""
203+
if self.optimized:
204+
self.emit(prefix + '_FAST', name)
205+
else:
206+
self.emit(prefix + '_NAME', name)
207+
196208
def set_lineno(self, node, force=0):
197209
"""Emit SET_LINENO if node has lineno attribute and it is
198210
different than the last lineno emitted.
@@ -221,6 +233,7 @@ def set_lineno(self, node, force=0):
221233
ClassGen = None
222234

223235
def visitModule(self, node):
236+
self.emit('SET_LINENO', 0)
224237
lnf = walk(node.node, self.NameFinder(), 0)
225238
self.locals.push(lnf.getLocals())
226239
if node.doc:
@@ -421,7 +434,7 @@ def visitListComp(self, node):
421434
self.emit('BUILD_LIST', 0)
422435
self.emit('DUP_TOP')
423436
self.emit('LOAD_ATTR', 'append')
424-
self.emit('STORE_FAST', append)
437+
self._implicitNameOp('STORE', append)
425438

426439
stack = []
427440
for i, for_ in zip(range(len(node.quals)), node.quals):
@@ -433,7 +446,7 @@ def visitListComp(self, node):
433446
self.visit(if_, cont)
434447
stack.insert(0, (start, cont, anchor))
435448

436-
self.emit('LOAD_FAST', append)
449+
self._implicitNameOp('LOAD', append)
437450
self.visit(node.expr)
438451
self.emit('CALL_FUNCTION', 1)
439452
self.emit('POP_TOP')
@@ -447,7 +460,7 @@ def visitListComp(self, node):
447460
self.nextBlock(skip_one)
448461
self.emit('JUMP_ABSOLUTE', start)
449462
self.startBlock(anchor)
450-
self.emit('DELETE_FAST', append)
463+
self._implicitNameOp('DELETE', append)
451464

452465
self.__list_count = self.__list_count - 1
453466

@@ -457,8 +470,8 @@ def visitListCompFor(self, node):
457470

458471
self.visit(node.list)
459472
self.visit(ast.Const(0))
460-
self.emit('SET_LINENO', node.lineno)
461473
self.nextBlock(start)
474+
self.emit('SET_LINENO', node.lineno)
462475
self.emit('FOR_LOOP', anchor)
463476
self.nextBlock()
464477
self.visit(node.assign)

Tools/compiler/compiler/pycodegen.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,18 @@ def _nameOp(self, prefix, name):
193193
else:
194194
self.emit(prefix + '_GLOBAL', name)
195195

196+
def _implicitNameOp(self, prefix, name):
197+
"""Emit name ops for names generated implicitly by for loops
198+
199+
The interpreter generates names that start with a period or
200+
dollar sign. The symbol table ignores these names because
201+
they aren't present in the program text.
202+
"""
203+
if self.optimized:
204+
self.emit(prefix + '_FAST', name)
205+
else:
206+
self.emit(prefix + '_NAME', name)
207+
196208
def set_lineno(self, node, force=0):
197209
"""Emit SET_LINENO if node has lineno attribute and it is
198210
different than the last lineno emitted.
@@ -221,6 +233,7 @@ def set_lineno(self, node, force=0):
221233
ClassGen = None
222234

223235
def visitModule(self, node):
236+
self.emit('SET_LINENO', 0)
224237
lnf = walk(node.node, self.NameFinder(), 0)
225238
self.locals.push(lnf.getLocals())
226239
if node.doc:
@@ -421,7 +434,7 @@ def visitListComp(self, node):
421434
self.emit('BUILD_LIST', 0)
422435
self.emit('DUP_TOP')
423436
self.emit('LOAD_ATTR', 'append')
424-
self.emit('STORE_FAST', append)
437+
self._implicitNameOp('STORE', append)
425438

426439
stack = []
427440
for i, for_ in zip(range(len(node.quals)), node.quals):
@@ -433,7 +446,7 @@ def visitListComp(self, node):
433446
self.visit(if_, cont)
434447
stack.insert(0, (start, cont, anchor))
435448

436-
self.emit('LOAD_FAST', append)
449+
self._implicitNameOp('LOAD', append)
437450
self.visit(node.expr)
438451
self.emit('CALL_FUNCTION', 1)
439452
self.emit('POP_TOP')
@@ -447,7 +460,7 @@ def visitListComp(self, node):
447460
self.nextBlock(skip_one)
448461
self.emit('JUMP_ABSOLUTE', start)
449462
self.startBlock(anchor)
450-
self.emit('DELETE_FAST', append)
463+
self._implicitNameOp('DELETE', append)
451464

452465
self.__list_count = self.__list_count - 1
453466

@@ -457,8 +470,8 @@ def visitListCompFor(self, node):
457470

458471
self.visit(node.list)
459472
self.visit(ast.Const(0))
460-
self.emit('SET_LINENO', node.lineno)
461473
self.nextBlock(start)
474+
self.emit('SET_LINENO', node.lineno)
462475
self.emit('FOR_LOOP', anchor)
463476
self.nextBlock()
464477
self.visit(node.assign)

0 commit comments

Comments
 (0)