mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 880085 - Unbreak run once closure optimizations, and don't treat named lambdas as run once closures, r=luke.
This commit is contained in:
parent
aba7ac56ed
commit
aba6876518
@ -454,6 +454,8 @@ frontend::CompileLazyFunction(JSContext *cx, LazyScript *lazy, const jschar *cha
|
||||
script->directlyInsideEval = true;
|
||||
if (lazy->usesArgumentsAndApply())
|
||||
script->usesArgumentsAndApply = true;
|
||||
if (lazy->hasBeenCloned())
|
||||
script->hasBeenCloned = true;
|
||||
|
||||
BytecodeEmitter bce(/* parent = */ nullptr, &parser, pn->pn_funbox, script, options.forEval,
|
||||
/* evalCaller = */ NullPtr(), /* hasGlobalScope = */ true,
|
||||
@ -461,6 +463,9 @@ frontend::CompileLazyFunction(JSContext *cx, LazyScript *lazy, const jschar *cha
|
||||
if (!bce.init())
|
||||
return false;
|
||||
|
||||
if (lazy->treatAsRunOnce())
|
||||
bce.lazyRunOnceLambda = true;
|
||||
|
||||
return EmitFunctionScript(cx, &bce, pn->pn_body);
|
||||
}
|
||||
|
||||
|
@ -107,6 +107,7 @@ BytecodeEmitter::BytecodeEmitter(BytecodeEmitter *parent,
|
||||
hasSingletons(false),
|
||||
emittingForInit(false),
|
||||
emittingRunOnceLambda(false),
|
||||
lazyRunOnceLambda(false),
|
||||
insideEval(insideEval),
|
||||
hasGlobalScope(hasGlobalScope),
|
||||
emitterMode(emitterMode)
|
||||
@ -2666,10 +2667,11 @@ frontend::EmitFunctionScript(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNo
|
||||
* the script ends up running multiple times via foo.caller related
|
||||
* shenanigans.
|
||||
*/
|
||||
bool runOnce = bce->parent &&
|
||||
bce->parent->emittingRunOnceLambda &&
|
||||
bool runOnce =
|
||||
bce->isRunOnceLambda() &&
|
||||
!funbox->argumentsHasLocalBinding() &&
|
||||
!funbox->isGenerator();
|
||||
!funbox->isGenerator() &&
|
||||
!funbox->function()->name();
|
||||
if (runOnce) {
|
||||
bce->switchToProlog();
|
||||
if (Emit1(cx, bce, JSOP_RUNONCE) < 0)
|
||||
@ -4788,9 +4790,7 @@ EmitFunc(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
bce->script->compileAndGo &&
|
||||
fun->isInterpreted() &&
|
||||
(bce->checkSingletonContext() ||
|
||||
(!bce->isInLoop() &&
|
||||
bce->parent &&
|
||||
bce->parent->emittingRunOnceLambda));
|
||||
(!bce->isInLoop() && bce->isRunOnceLambda()));
|
||||
if (!JSFunction::setTypeForScriptedFunction(cx, fun, singleton))
|
||||
return false;
|
||||
|
||||
@ -4801,6 +4801,8 @@ EmitFunc(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
scope = bce->sc->asFunctionBox()->function();
|
||||
fun->lazyScript()->setParent(scope, bce->script->sourceObject());
|
||||
}
|
||||
if (bce->emittingRunOnceLambda)
|
||||
fun->lazyScript()->setTreatAsRunOnce();
|
||||
} else {
|
||||
SharedContext *outersc = bce->sc;
|
||||
|
||||
|
@ -124,6 +124,12 @@ struct BytecodeEmitter
|
||||
|
||||
bool emittingRunOnceLambda:1; /* true while emitting a lambda which is only
|
||||
expected to run once. */
|
||||
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 insideEval:1; /* True if compiling an eval-expression or a function
|
||||
nested inside an eval. */
|
||||
|
@ -2942,6 +2942,7 @@ LazyScript::LazyScript(JSFunction *fun, void *table, uint32_t numFreeVariables,
|
||||
directlyInsideEval_(false),
|
||||
usesArgumentsAndApply_(false),
|
||||
hasBeenCloned_(false),
|
||||
treatAsRunOnce_(false),
|
||||
begin_(begin),
|
||||
end_(end),
|
||||
lineno_(lineno),
|
||||
|
@ -1183,7 +1183,7 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
|
||||
uint32_t version_ : 8;
|
||||
|
||||
uint32_t numFreeVariables_ : 24;
|
||||
uint32_t numInnerFunctions_ : 24;
|
||||
uint32_t numInnerFunctions_ : 23;
|
||||
|
||||
uint32_t generatorKindBits_:2;
|
||||
|
||||
@ -1194,6 +1194,7 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
|
||||
uint32_t directlyInsideEval_:1;
|
||||
uint32_t usesArgumentsAndApply_:1;
|
||||
uint32_t hasBeenCloned_:1;
|
||||
uint32_t treatAsRunOnce_:1;
|
||||
|
||||
// Source location for the script.
|
||||
uint32_t begin_;
|
||||
@ -1310,6 +1311,13 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
|
||||
hasBeenCloned_ = true;
|
||||
}
|
||||
|
||||
bool treatAsRunOnce() const {
|
||||
return treatAsRunOnce_;
|
||||
}
|
||||
void setTreatAsRunOnce() {
|
||||
treatAsRunOnce_ = true;
|
||||
}
|
||||
|
||||
ScriptSource *source() const {
|
||||
return sourceObject()->source();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user