diff --git a/js/src/frontend/FullParseHandler.h b/js/src/frontend/FullParseHandler.h index e26d6fb47..9674ce341 100644 --- a/js/src/frontend/FullParseHandler.h +++ b/js/src/frontend/FullParseHandler.h @@ -1018,6 +1018,14 @@ class FullParseHandler syntaxParser = nullptr; } + // TenFourFox issue 533, from M1263355 + bool canSkipLazyInnerFunctions() { + return !!lazyOuterFunction_; + } + bool canSkipLazyClosedOverBindings() { + return !!lazyOuterFunction_; + } + LazyScript* lazyOuterFunction() { return lazyOuterFunction_; } diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index ab0b945ee..ab3150833 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -1120,8 +1120,11 @@ Parser::defineFunctionThis() // Also define a this-binding if direct eval is used, in derived class // constructors (JSOP_CHECKRETURN relies on it) or if there's a debugger - // statement. + // statement, or if this is a lazy script that has a this-binding + // (TenFourFox issue 533). if (pc->sc->hasDirectEval() || + (handler.canSkipLazyClosedOverBindings() && + pc->sc->asFunctionBox()->function()->lazyScript()->hasThisBinding()) || pc->sc->asFunctionBox()->isDerivedClassConstructor() || pc->sc->hasDebuggerStatement()) { @@ -2936,6 +2939,9 @@ Parser::finishFunctionDefinition(Node pn, FunctionBox* funbo lazy->setIsDerivedClassConstructor(); if (funbox->needsHomeObject()) lazy->setNeedsHomeObject(); + // TenFourFox issue 533 + if (funbox->hasThisBinding()) + lazy->setHasThisBinding(); PropagateTransitiveParseFlags(funbox, lazy); fun->initLazyScript(lazy); diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index c2a7afae2..011c9d34a 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -4282,6 +4282,7 @@ LazyScript::CreateRaw(ExclusiveContext* cx, HandleFunction fun, p.hasBeenCloned = false; p.treatAsRunOnce = false; p.isAsync = false; + p.hasThisBinding = false; size_t bytes = (p.numFreeVariables * sizeof(FreeVariable)) + (p.numInnerFunctions * sizeof(HeapPtrFunction)); @@ -4312,6 +4313,7 @@ LazyScript::CreateRaw(ExclusiveContext* cx, HandleFunction fun, }; p.version = version; + p.hasThisBinding = false; p.numFreeVariables = numFreeVariables; p.isAsync = false; p.numInnerFunctions = numInnerFunctions; diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 90eb07ed9..1a72c7464 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -2150,7 +2150,7 @@ class LazyScript : public gc::TenuredCell // instead of private to suppress -Wunused-private-field compiler warnings. protected: #if JS_BITS_PER_WORD == 32 - uint32_t padding; + //uint32_t padding; // widened after TenFourFox issue 533 #endif private: @@ -2158,8 +2158,7 @@ class LazyScript : public gc::TenuredCell // Assorted bits that should really be in ScriptSourceObject. uint32_t version : 8; - uint32_t numFreeVariables : 23; - uint32_t isAsync: 1; + uint32_t numFreeVariables : 22; uint32_t numInnerFunctions : 20; uint32_t generatorKindBits : 2; @@ -2167,6 +2166,8 @@ class LazyScript : public gc::TenuredCell // N.B. These are booleans but need to be uint32_t to pack correctly on MSVC. // If you add another boolean here, make sure to initialze it in // LazyScript::CreateRaw(). + uint32_t hasThisBinding : 1; + uint32_t isAsync: 1; uint32_t strict : 1; uint32_t bindingsAccessedDynamically : 1; uint32_t hasDebuggerStatement : 1; @@ -2368,6 +2369,13 @@ class LazyScript : public gc::TenuredCell p_.needsHomeObject = true; } + bool hasThisBinding() const { + return p_.hasThisBinding; + } + void setHasThisBinding() { + p_.hasThisBinding = true; + } + const char* filename() const { return scriptSource()->filename(); }