summaryrefslogtreecommitdiffstats
path: root/Lib/compiler
diff options
context:
space:
mode:
authorNeil Schemenauer <nascheme@enme.ucalgary.ca>2006-08-04 16:20:30 (GMT)
committerNeil Schemenauer <nascheme@enme.ucalgary.ca>2006-08-04 16:20:30 (GMT)
commit06ded09d4048bf44ce9b61c82494cf0a0825412c (patch)
tree5aa766517b8a84d0d4d048dcd3c62f78638da8e0 /Lib/compiler
parent45381938e940279df3962f6ebe01efb8375198a3 (diff)
downloadcpython-06ded09d4048bf44ce9b61c82494cf0a0825412c.zip
cpython-06ded09d4048bf44ce9b61c82494cf0a0825412c.tar.gz
cpython-06ded09d4048bf44ce9b61c82494cf0a0825412c.tar.bz2
Fix the 'compiler' package to generate correct code for MAKE_CLOSURE.
In the 2.5 development cycle, MAKE_CLOSURE as changed to take free variables as a tuple rather than as individual items on the stack. Closes patch #1534084.
Diffstat (limited to 'Lib/compiler')
-rw-r--r--Lib/compiler/pycodegen.py39
1 files changed, 13 insertions, 26 deletions
diff --git a/Lib/compiler/pycodegen.py b/Lib/compiler/pycodegen.py
index d5d68aa..e3667b5 100644
--- a/Lib/compiler/pycodegen.py
+++ b/Lib/compiler/pycodegen.py
@@ -382,16 +382,7 @@ class CodeGenerator:
self.set_lineno(node)
for default in node.defaults:
self.visit(default)
- frees = gen.scope.get_free_vars()
- if frees:
- for name in frees:
- self.emit('LOAD_CLOSURE', name)
- self.emit('LOAD_CONST', gen)
- self.emit('MAKE_CLOSURE', len(node.defaults))
- else:
- self.emit('LOAD_CONST', gen)
- self.emit('MAKE_FUNCTION', len(node.defaults))
-
+ self._makeClosure(gen, len(node.defaults))
for i in range(ndecorators):
self.emit('CALL_FUNCTION', 1)
@@ -405,14 +396,7 @@ class CodeGenerator:
for base in node.bases:
self.visit(base)
self.emit('BUILD_TUPLE', len(node.bases))
- frees = gen.scope.get_free_vars()
- for name in frees:
- self.emit('LOAD_CLOSURE', name)
- self.emit('LOAD_CONST', gen)
- if frees:
- self.emit('MAKE_CLOSURE', 0)
- else:
- self.emit('MAKE_FUNCTION', 0)
+ self._makeClosure(gen, 0)
self.emit('CALL_FUNCTION', 0)
self.emit('BUILD_CLASS')
self.storeName(node.name)
@@ -644,22 +628,25 @@ class CodeGenerator:
self.newBlock()
self.emit('POP_TOP')
- def visitGenExpr(self, node):
- gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
- self.get_module())
- walk(node.code, gen)
- gen.finish()
- self.set_lineno(node)
+ def _makeClosure(self, gen, args):
frees = gen.scope.get_free_vars()
if frees:
for name in frees:
self.emit('LOAD_CLOSURE', name)
+ self.emit('BUILD_TUPLE', len(frees))
self.emit('LOAD_CONST', gen)
- self.emit('MAKE_CLOSURE', 0)
+ self.emit('MAKE_CLOSURE', args)
else:
self.emit('LOAD_CONST', gen)
- self.emit('MAKE_FUNCTION', 0)
+ self.emit('MAKE_FUNCTION', args)
+ def visitGenExpr(self, node):
+ gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
+ self.get_module())
+ walk(node.code, gen)
+ gen.finish()
+ self.set_lineno(node)
+ self._makeClosure(gen, 0)
# precomputation of outmost iterable
self.visit(node.code.quals[0].iter)
self.emit('GET_ITER')