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.
This commit is contained in:
Neil Schemenauer 2006-08-04 16:20:30 +00:00
parent 45381938e9
commit 06ded09d40
3 changed files with 31 additions and 28 deletions

View file

@ -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 _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', args)
else:
self.emit('LOAD_CONST', gen)
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)
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', 0)
else:
self.emit('LOAD_CONST', gen)
self.emit('MAKE_FUNCTION', 0)
self._makeClosure(gen, 0)
# precomputation of outmost iterable
self.visit(node.code.quals[0].iter)
self.emit('GET_ITER')