summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2008-12-17 00:38:28 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2008-12-17 00:38:28 (GMT)
commitd0c3515bc5b31a19d00bfc685d7657ad7d79fa94 (patch)
tree299253e76cf9b66349bdaf0cca8c95da19671c74 /Lib
parent43caaa09ea364aab6cbd7ede2aa9c3d004a129a5 (diff)
downloadcpython-d0c3515bc5b31a19d00bfc685d7657ad7d79fa94.zip
cpython-d0c3515bc5b31a19d00bfc685d7657ad7d79fa94.tar.gz
cpython-d0c3515bc5b31a19d00bfc685d7657ad7d79fa94.tar.bz2
Issue #2183: Simplify and optimize bytecode for list comprehensions.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/compiler/pycodegen.py12
-rw-r--r--Lib/opcode.py3
-rw-r--r--Lib/test/test_dis.py36
3 files changed, 18 insertions, 33 deletions
diff --git a/Lib/compiler/pycodegen.py b/Lib/compiler/pycodegen.py
index 61b9fe9..5d5dca0 100644
--- a/Lib/compiler/pycodegen.py
+++ b/Lib/compiler/pycodegen.py
@@ -570,16 +570,10 @@ class CodeGenerator:
self.nextBlock(end)
# list comprehensions
- __list_count = 0
-
def visitListComp(self, node):
self.set_lineno(node)
# setup list
- tmpname = "$list%d" % self.__list_count
- self.__list_count = self.__list_count + 1
self.emit('BUILD_LIST', 0)
- self.emit('DUP_TOP')
- self._implicitNameOp('STORE', tmpname)
stack = []
for i, for_ in zip(range(len(node.quals)), node.quals):
@@ -591,9 +585,8 @@ class CodeGenerator:
self.visit(if_, cont)
stack.insert(0, (start, cont, anchor))
- self._implicitNameOp('LOAD', tmpname)
self.visit(node.expr)
- self.emit('LIST_APPEND')
+ self.emit('LIST_APPEND', len(node.quals) + 1)
for start, cont, anchor in stack:
if cont:
@@ -604,9 +597,6 @@ class CodeGenerator:
self.nextBlock(skip_one)
self.emit('JUMP_ABSOLUTE', start)
self.startBlock(anchor)
- self._implicitNameOp('DELETE', tmpname)
-
- self.__list_count = self.__list_count - 1
def visitListCompFor(self, node):
start = self.newBlock()
diff --git a/Lib/opcode.py b/Lib/opcode.py
index cee5057..d41383b 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -58,7 +58,6 @@ def_op('UNARY_CONVERT', 13)
def_op('UNARY_INVERT', 15)
-def_op('LIST_APPEND', 18)
def_op('BINARY_POWER', 19)
def_op('BINARY_MULTIPLY', 20)
def_op('BINARY_DIVIDE', 21)
@@ -128,7 +127,7 @@ name_op('STORE_NAME', 90) # Index in name list
name_op('DELETE_NAME', 91) # ""
def_op('UNPACK_SEQUENCE', 92) # Number of tuple items
jrel_op('FOR_ITER', 93)
-
+def_op('LIST_APPEND', 94)
name_op('STORE_ATTR', 95) # Index in name list
name_op('DELETE_ATTR', 96) # ""
name_op('STORE_GLOBAL', 97) # ""
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index fd508a9..6fa437b 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -54,29 +54,25 @@ def bug1333982(x=[]):
dis_bug1333982 = """\
%-4d 0 LOAD_CONST 1 (0)
- 3 JUMP_IF_TRUE 41 (to 47)
+ 3 JUMP_IF_TRUE 33 (to 39)
6 POP_TOP
7 LOAD_GLOBAL 0 (AssertionError)
10 BUILD_LIST 0
- 13 DUP_TOP
- 14 STORE_FAST 1 (_[1])
- 17 LOAD_FAST 0 (x)
- 20 GET_ITER
- >> 21 FOR_ITER 13 (to 37)
- 24 STORE_FAST 2 (s)
- 27 LOAD_FAST 1 (_[1])
- 30 LOAD_FAST 2 (s)
- 33 LIST_APPEND
- 34 JUMP_ABSOLUTE 21
- >> 37 DELETE_FAST 1 (_[1])
-
- %-4d 40 LOAD_CONST 2 (1)
- 43 BINARY_ADD
- 44 RAISE_VARARGS 2
- >> 47 POP_TOP
-
- %-4d 48 LOAD_CONST 0 (None)
- 51 RETURN_VALUE
+ 13 LOAD_FAST 0 (x)
+ 16 GET_ITER
+ >> 17 FOR_ITER 12 (to 32)
+ 20 STORE_FAST 1 (s)
+ 23 LOAD_FAST 1 (s)
+ 26 LIST_APPEND 2
+ 29 JUMP_ABSOLUTE 17
+
+ %-4d >> 32 LOAD_CONST 2 (1)
+ 35 BINARY_ADD
+ 36 RAISE_VARARGS 2
+ >> 39 POP_TOP
+
+ %-4d 40 LOAD_CONST 0 (None)
+ 43 RETURN_VALUE
"""%(bug1333982.func_code.co_firstlineno + 1,
bug1333982.func_code.co_firstlineno + 2,
bug1333982.func_code.co_firstlineno + 3)