Bug 928971 - Consistently test for whether functions will be run once closures, r=luke.

This commit is contained in:
Brian Hackett 2013-10-21 10:01:47 -06:00
parent 12968871bd
commit 0442b2a8c4
2 changed files with 18 additions and 8 deletions

View File

@ -2622,6 +2622,22 @@ EmitSwitch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
return true;
}
bool
BytecodeEmitter::isRunOnceLambda()
{
// The run once lambda flags set by the parser are approximate, and we look
// at properties of the function itself before deciding to emit a function
// as a run once lambda.
if (!(parent && parent->emittingRunOnceLambda) && !lazyRunOnceLambda)
return false;
FunctionBox *funbox = sc->asFunctionBox();
return !funbox->argumentsHasLocalBinding() &&
!funbox->isGenerator() &&
!funbox->function()->name();
}
bool
frontend::EmitFunctionScript(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *body)
{
@ -2667,11 +2683,7 @@ frontend::EmitFunctionScript(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNo
* the script ends up running multiple times via foo.caller related
* shenanigans.
*/
bool runOnce =
bce->isRunOnceLambda() &&
!funbox->argumentsHasLocalBinding() &&
!funbox->isGenerator() &&
!funbox->function()->name();
bool runOnce = bce->isRunOnceLambda();
if (runOnce) {
bce->switchToProlog();
if (Emit1(cx, bce, JSOP_RUNONCE) < 0)

View File

@ -127,9 +127,7 @@ struct BytecodeEmitter
bool lazyRunOnceLambda:1; /* true while lazily emitting a script for
* a lambda which is only expected to run once. */
bool isRunOnceLambda() {
return (parent && parent->emittingRunOnceLambda) || lazyRunOnceLambda;
}
bool isRunOnceLambda();
bool insideEval:1; /* True if compiling an eval-expression or a function
nested inside an eval. */