author | caroline <ccullen@mozilla.com> |
Thu, 12 Mar 2020 22:48:33 +0000 | |
changeset 518506 | 651f6b4c7d7414fc73ea15080e8874bddc5c122b |
parent 518505 | 1a37a40dc640d4b109547a6e8fdae66bdc4030c5 |
child 518507 | 2b848bc7334e633db0592c45da598e43a48d9975 |
push id | 37211 |
push user | malexandru@mozilla.com |
push date | Fri, 13 Mar 2020 09:53:22 +0000 |
treeherder | mozilla-central@b5c4cdbb59c9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | tcampbell |
bugs | 1619445 |
milestone | 76.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -1682,17 +1682,17 @@ bool PerHandlerParser<SyntaxParseHandler } FunctionBox* funbox = pc_->functionBox(); funbox->synchronizeArgCount(); LazyScriptCreationData data(cx_); if (!data.init(cx_, pc_->closedOverBindingsForLazy(), std::move(pc_->innerFunctionIndexesForLazy), - pc_->sc()->strict())) { + options().forceStrictMode(), pc_->sc()->strict())) { return false; } funbox->functionCreationData().get().lazyScriptData = mozilla::Some(std::move(data)); return true; } @@ -1745,16 +1745,19 @@ bool LazyScriptCreationData::create(JSCo sourceObject, closedOverBindings, innerFunctionIndexes, funbox->extent); if (!lazy) { return false; } // Flags that need to be copied into the JSScript when we do the full // parse. + if (forceStrict) { + lazy->setForceStrict(); + } if (strict) { lazy->setStrict(); } lazy->setGeneratorKind(funbox->generatorKind()); lazy->setAsyncKind(funbox->asyncKind()); if (funbox->hasRest()) { lazy->setHasRest(); }
--- a/js/src/frontend/Stencil.h +++ b/js/src/frontend/Stencil.h @@ -73,24 +73,27 @@ class FunctionIndex : public TypedIndex< }; // Data used to instantiate the lazy script before script emission. struct LazyScriptCreationData { frontend::AtomVector closedOverBindings; // This is traced by the functionbox which owns this LazyScriptCreationData Vector<FunctionIndex> innerFunctionIndexes; + bool forceStrict = false; bool strict = false; mozilla::Maybe<FieldInitializers> fieldInitializers; explicit LazyScriptCreationData(JSContext* cx) : innerFunctionIndexes(cx) {} bool init(JSContext* cx, const frontend::AtomVector& COB, - Vector<FunctionIndex>&& innerIndexes, bool isStrict) { + Vector<FunctionIndex>&& innerIndexes, bool isForceStrict, + bool isStrict) { + forceStrict = isForceStrict; strict = isStrict; innerFunctionIndexes = std::move(innerIndexes); if (!closedOverBindings.appendAll(COB)) { ReportOutOfMemory(cx); // closedOverBindings uses SystemAllocPolicy. return false; } return true;
--- a/js/src/vm/JSScript.cpp +++ b/js/src/vm/JSScript.cpp @@ -4318,16 +4318,19 @@ JSScript* JSScript::Create(JSContext* cx RootedScriptSourceObject sourceObject(cx, lazy->sourceObject()); RootedObject fun(cx, lazy->function()); RootedScript script(cx, JSScript::New(cx, fun, sourceObject, lazy->extent())); if (!script) { return nullptr; } // Propagate flags. + if (lazy->forceStrict()) { + script->setForceStrict(); + } if (lazy->isLikelyConstructorWrapper()) { script->setIsLikelyConstructorWrapper(); } if (lazy->hasBeenCloned()) { script->setHasBeenCloned(); } return script;
--- a/js/src/vm/JSScript.h +++ b/js/src/vm/JSScript.h @@ -2208,16 +2208,17 @@ setterLevel: #define MUTABLE_FLAG_GETTER(lowerName, name) \ FLAG_GETTER(MutableFlags, name, lowerName) #define MUTABLE_FLAG_GETTER_SETTER(lowerName, name) \ FLAG_GETTER_SETTER(MutableFlags, name, public, lowerName, name) IMMUTABLE_FLAG_GETTER(noScriptRval, NoScriptRval) IMMUTABLE_FLAG_GETTER(selfHosted, SelfHosted) IMMUTABLE_FLAG_GETTER_SETTER_PUBLIC(treatAsRunOnce, TreatAsRunOnce) + IMMUTABLE_FLAG_GETTER_SETTER_PUBLIC(forceStrict, ForceStrict) IMMUTABLE_FLAG_GETTER_SETTER_PUBLIC(strict, Strict) IMMUTABLE_FLAG_GETTER(hasNonSyntacticScope, HasNonSyntacticScope) IMMUTABLE_FLAG_GETTER_SETTER_PUBLIC(bindingsAccessedDynamically, BindingsAccessedDynamically) IMMUTABLE_FLAG_GETTER_SETTER_PUBLIC(funHasExtensibleScope, FunHasExtensibleScope) IMMUTABLE_FLAG_GETTER_SETTER_PUBLIC(hasCallSiteObj, HasCallSiteObj) IMMUTABLE_FLAG_GETTER_SETTER_PUBLIC(hasModuleGoal, HasModuleGoal)
--- a/js/src/vm/SharedStencil.h +++ b/js/src/vm/SharedStencil.h @@ -58,90 +58,93 @@ enum class ImmutableScriptFlagsEnum : ui // See Parser::selfHostingMode. SelfHosted = 1 << 1, // Script is a lambda to treat as running once or a global or eval script // that will only run once. Which one it is can be disambiguated by // checking whether function() is null. TreatAsRunOnce = 1 << 2, + + // Code was forced into strict mode using CompileOptions. + ForceStrict = 1 << 3, // ---- // Code is in strict mode. - Strict = 1 << 3, + Strict = 1 << 4, // True if the script has a non-syntactic scope on its dynamic scope chain. // That is, there are objects about which we know nothing between the // outermost syntactic scope and the global. - HasNonSyntacticScope = 1 << 4, + HasNonSyntacticScope = 1 << 5, // See FunctionBox. - BindingsAccessedDynamically = 1 << 5, - FunHasExtensibleScope = 1 << 6, + BindingsAccessedDynamically = 1 << 6, + FunHasExtensibleScope = 1 << 7, // Bytecode contains JSOp::CallSiteObj // (We don't relazify functions with template strings, due to observability) - HasCallSiteObj = 1 << 7, + HasCallSiteObj = 1 << 8, // Script is parsed with a top-level goal of Module. This may be a top-level // or an inner-function script. - HasModuleGoal = 1 << 8, + HasModuleGoal = 1 << 9, - FunctionHasThisBinding = 1 << 9, - FunctionHasExtraBodyVarScope = 1 << 10, + FunctionHasThisBinding = 1 << 10, + FunctionHasExtraBodyVarScope = 1 << 11, // Whether the arguments object for this script, if it needs one, should be // mapped (alias formal parameters). - HasMappedArgsObj = 1 << 11, + HasMappedArgsObj = 1 << 12, // Script contains inner functions. Used to check if we can relazify the // script. - HasInnerFunctions = 1 << 12, + HasInnerFunctions = 1 << 13, - NeedsHomeObject = 1 << 13, + NeedsHomeObject = 1 << 14, - IsDerivedClassConstructor = 1 << 14, + IsDerivedClassConstructor = 1 << 15, // 'this', 'arguments' and f.apply() are used. This is likely to be a // wrapper. - IsLikelyConstructorWrapper = 1 << 15, + IsLikelyConstructorWrapper = 1 << 16, // Set if this function is a generator function or async generator. - IsGenerator = 1 << 16, + IsGenerator = 1 << 17, // Set if this function is an async function or async generator. - IsAsync = 1 << 17, + IsAsync = 1 << 18, // Set if this function has a rest parameter. - HasRest = 1 << 18, + HasRest = 1 << 19, // See comments below. - ArgumentsHasVarBinding = 1 << 19, + ArgumentsHasVarBinding = 1 << 20, // Script came from eval(). - IsForEval = 1 << 20, + IsForEval = 1 << 21, // Whether this is a top-level module script. - IsModule = 1 << 21, + IsModule = 1 << 22, // Whether this function needs a call object or named lambda environment. - NeedsFunctionEnvironmentObjects = 1 << 22, + NeedsFunctionEnvironmentObjects = 1 << 23, // Whether the Parser declared 'arguments'. - ShouldDeclareArguments = 1 << 23, + ShouldDeclareArguments = 1 << 24, // Script is for function. - IsFunction = 1 << 24, + IsFunction = 1 << 25, // Whether this script contains a direct eval statement. - HasDirectEval = 1 << 25, + HasDirectEval = 1 << 26, // Whether this BaseScript is a LazyScript. This flag will be removed after // LazyScript and JSScript are merged in Bug 1529456. - IsLazyScript = 1 << 26, + IsLazyScript = 1 << 27, }; class ImmutableScriptFlags : public ScriptFlagBase<ImmutableScriptFlagsEnum> { // Immutable flags should not be modified after the JSScript that contains // them has been initialized. These flags should likely be preserved when // serializing (XDR) or copying (CopyScript) the script. This is only public // for the JITs. // @@ -160,27 +163,31 @@ class ImmutableScriptFlags : public Scri void operator=(uint32_t flag) { flags_ = flag; } static ImmutableScriptFlags fromCompileOptions( const JS::ReadOnlyCompileOptions& options) { ImmutableScriptFlags isf; isf.setFlag(ImmutableScriptFlagsEnum::NoScriptRval, options.noScriptRval); isf.setFlag(ImmutableScriptFlagsEnum::SelfHosted, options.selfHostingMode); isf.setFlag(ImmutableScriptFlagsEnum::TreatAsRunOnce, options.isRunOnce); + isf.setFlag(ImmutableScriptFlagsEnum::ForceStrict, + options.forceStrictMode()); return isf; }; static ImmutableScriptFlags fromCompileOptions( const JS::TransitiveCompileOptions& options) { ImmutableScriptFlags isf; isf.setFlag(ImmutableScriptFlagsEnum::NoScriptRval, /* noScriptRval (non-transitive compile option) = */ false); isf.setFlag(ImmutableScriptFlagsEnum::SelfHosted, options.selfHostingMode); isf.setFlag(ImmutableScriptFlagsEnum::TreatAsRunOnce, /* isRunOnce (non-transitive compile option) = */ false); + isf.setFlag(ImmutableScriptFlagsEnum::ForceStrict, + options.forceStrictMode()); return isf; }; }; enum class MutableScriptFlagsEnum : uint32_t { // Number of times the |warmUpCount| was forcibly discarded. The counter is // reset when a script is successfully jit-compiled. WarmupResets_MASK = 0xFF,