diff options
author | Neil Schemenauer <nascheme@enme.ucalgary.ca> | 2006-08-04 16:20:30 (GMT) |
---|---|---|
committer | Neil Schemenauer <nascheme@enme.ucalgary.ca> | 2006-08-04 16:20:30 (GMT) |
commit | 06ded09d4048bf44ce9b61c82494cf0a0825412c (patch) | |
tree | 5aa766517b8a84d0d4d048dcd3c62f78638da8e0 /Lib/compiler | |
parent | 45381938e940279df3962f6ebe01efb8375198a3 (diff) | |
download | cpython-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.py | 39 |
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') |