safely preserving the arguments object through generated closure wrappers.

This commit is contained in:
Jeremy Ashkenas
2010-04-10 14:20:32 -04:00
parent 491ad6de95
commit f36acc27e5
3 changed files with 27 additions and 6 deletions

View File

@@ -1263,11 +1263,16 @@ PushNode: exports.PushNode: {
ClosureNode: exports.ClosureNode: {
# Wrap the expressions body, unless it contains a pure statement,
# in which case, no dice.
# in which case, no dice. If the body mentions `arguments`, then make sure
# that the closure wrapper preserves the original arguments.
wrap: (expressions, statement) ->
return expressions if expressions.contains_pure_statement()
mentions_args: expressions.contains (n) -> (n instanceof LiteralNode) and (n.value is 'arguments')
meth: literal(if mentions_args then 'apply' else 'call')
args: [literal('this')]
args.push literal 'arguments' if mentions_args
func: new ParentheticalNode(new CodeNode([], Expressions.wrap([expressions])))
call: new CallNode(new ValueNode(func, [new AccessorNode(literal('call'))]), [literal('this')])
call: new CallNode(new ValueNode(func, [new AccessorNode(meth)]), args)
if statement then Expressions.wrap([call]) else call
}