From 3cab8e70c61dbab7261d0aaf68963cae0ec92f1a Mon Sep 17 00:00:00 2001 From: Ted Campbell Date: Thu, 22 Aug 2019 13:08:10 +0000 Subject: [PATCH] Bug 1575055 - Privatize js::CompileOptions::strictMode. r=jandem We already have an accessor to make sure this is can only be set but not cleared so hide the underlying storage. Differential Revision: https://phabricator.services.mozilla.com/D42559 --HG-- extra : moz-landing-system : lando --- js/public/CompileOptions.h | 10 +++++++--- js/src/builtin/Eval.cpp | 16 +++++++++++----- js/src/debugger/Frame.cpp | 8 +++++--- js/src/frontend/BytecodeCompiler.cpp | 8 ++++---- js/src/frontend/Parser.cpp | 2 +- js/src/jsapi.cpp | 6 ++++-- js/src/shell/js.cpp | 4 ++-- js/src/vm/SelfHosting.cpp | 2 +- js/src/wasm/AsmJS.cpp | 2 +- js/xpconnect/loader/mozJSComponentLoader.cpp | 2 +- 10 files changed, 37 insertions(+), 23 deletions(-) diff --git a/js/public/CompileOptions.h b/js/public/CompileOptions.h index 01ff14a37f1c..42ab7a3443f5 100644 --- a/js/public/CompileOptions.h +++ b/js/public/CompileOptions.h @@ -103,6 +103,10 @@ class JS_PUBLIC_API TransitiveCompileOptions { // conditions are checked in the CompileOptions constructor. bool forceFullParse_ = false; + // Either the Realm configuration or the compile request may force + // strict-mode. + bool forceStrictMode_ = false; + const char* filename_ = nullptr; const char* introducerFilename_ = nullptr; const char16_t* sourceMapURL_ = nullptr; @@ -111,7 +115,6 @@ class JS_PUBLIC_API TransitiveCompileOptions { // POD options. bool selfHostingMode = false; bool canLazilyParse = true; - bool strictOption = false; bool extraWarningsOption = false; bool werrorOption = false; AsmJSOption asmJSOption = AsmJSOption::Disabled; @@ -149,6 +152,7 @@ class JS_PUBLIC_API TransitiveCompileOptions { // depends on the derived type. bool mutedErrors() const { return mutedErrors_; } bool forceFullParse() const { return forceFullParse_; } + bool forceStrictMode() const { return forceStrictMode_; } const char* filename() const { return filename_; } const char* introducerFilename() const { return introducerFilename_; } const char16_t* sourceMapURL() const { return sourceMapURL_; } @@ -443,8 +447,8 @@ class MOZ_STACK_CLASS JS_PUBLIC_API CompileOptions final CompileOptions& setIntroductionInfoToCaller(JSContext* cx, const char* introductionType); - CompileOptions& maybeMakeStrictMode(bool strict) { - strictOption = strictOption || strict; + CompileOptions& setForceStrictMode() { + forceStrictMode_ = true; return *this; } diff --git a/js/src/builtin/Eval.cpp b/js/src/builtin/Eval.cpp index 7b1a5d98072d..cb6197995bb1 100644 --- a/js/src/builtin/Eval.cpp +++ b/js/src/builtin/Eval.cpp @@ -294,9 +294,12 @@ static bool EvalKernel(JSContext* cx, HandleValue v, EvalType evalType, options.setIsRunOnce(true) .setNoScriptRval(false) .setMutedErrors(mutedErrors) - .maybeMakeStrictMode(evalType == DIRECT_EVAL && IsStrictEvalPC(pc)) .setScriptOrModule(maybeScript); + if (evalType == DIRECT_EVAL && IsStrictEvalPC(pc)) { + options.setForceStrictMode(); + } + if (introducerFilename) { options.setFileAndLine(filename, 1); options.setIntroductionInfo(introducerFilename, "eval", lineno, @@ -381,10 +384,13 @@ bool js::DirectEvalStringFromIon(JSContext* cx, HandleObject env, RootedScope enclosing(cx, callerScript->innermostScope(pc)); CompileOptions options(cx); - options.setIsRunOnce(true) - .setNoScriptRval(false) - .setMutedErrors(mutedErrors) - .maybeMakeStrictMode(IsStrictEvalPC(pc)); + options.setIsRunOnce(true); + options.setNoScriptRval(false); + options.setMutedErrors(mutedErrors); + + if (IsStrictEvalPC(pc)) { + options.setForceStrictMode(); + } if (introducerFilename) { options.setFileAndLine(filename, 1); diff --git a/js/src/debugger/Frame.cpp b/js/src/debugger/Frame.cpp index cb1fbd7b8ec8..199c4610c437 100644 --- a/js/src/debugger/Frame.cpp +++ b/js/src/debugger/Frame.cpp @@ -789,9 +789,11 @@ static bool EvaluateInEnv(JSContext* cx, Handle env, options.setIsRunOnce(true) .setNoScriptRval(false) .setFileAndLine(filename, lineno) - .setIntroductionType("debugger eval") - .maybeMakeStrictMode(frame && frame.hasScript() ? frame.script()->strict() - : false); + .setIntroductionType("debugger eval"); + + if (frame && frame.hasScript() && frame.script()->strict()) { + options.setForceStrictMode(); + } SourceText srcBuf; if (!srcBuf.init(cx, chars.begin().get(), chars.length(), diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index e5a6b2fed373..1bd1f8c0779a 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -387,7 +387,7 @@ BytecodeCompiler::BytecodeCompiler(JSContext* cx, cx(cx), options(options), sourceObject(cx), - directives(options.strictOption), + directives(options.forceStrictMode()), script(cx) {} bool BytecodeCompiler::createScriptSource( @@ -745,7 +745,7 @@ JSScript* frontend::CompileGlobalBinASTScript( return nullptr; } - Directives directives(options.strictOption); + Directives directives(options.forceStrictMode()); GlobalSharedContext globalsc(cx, ScopeKind::Global, directives, options.extraWarningsOption); @@ -796,8 +796,8 @@ static ModuleObject* InternalParseModule( AutoAssertReportedException assertException(cx); CompileOptions options(cx, optionsInput); - options.maybeMakeStrictMode( - true); // ES6 10.2.1 Module code is always strict mode code. + options.setForceStrictMode(); // ES6 10.2.1 Module code is always strict mode + // code. options.setIsRunOnce(true); options.allowHTMLComments = false; diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 7ce98ffe866c..2ddf3ea93b08 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -429,7 +429,7 @@ template typename ParseHandler::ListNodeType GeneralParser::parse() { MOZ_ASSERT(checkOptionsCalled_); - Directives directives(options().strictOption); + Directives directives(options().forceStrictMode()); GlobalSharedContext globalsc(cx_, ScopeKind::Global, directives, options().extraWarningsOption); SourceParseContext globalpc(this, &globalsc, /* newDirectives = */ nullptr); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 81d041514c04..7225d8eab54c 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -3525,9 +3525,9 @@ void JS::TransitiveCompileOptions::copyPODTransitiveOptions( const TransitiveCompileOptions& rhs) { mutedErrors_ = rhs.mutedErrors_; forceFullParse_ = rhs.forceFullParse_; + forceStrictMode_ = rhs.forceStrictMode_; selfHostingMode = rhs.selfHostingMode; canLazilyParse = rhs.canLazilyParse; - strictOption = rhs.strictOption; extraWarningsOption = rhs.extraWarningsOption; werrorOption = rhs.werrorOption; asmJSOption = rhs.asmJSOption; @@ -3622,7 +3622,6 @@ JS::CompileOptions::CompileOptions(JSContext* cx) elementAttributeNameRoot(cx), introductionScriptRoot(cx), scriptOrModuleRoot(cx) { - strictOption = cx->options().strictMode(); extraWarningsOption = cx->realm()->behaviors().extraWarnings(cx); discardSource = cx->realm()->behaviors().discardSource(); werrorOption = cx->options().werror(); @@ -3637,6 +3636,9 @@ JS::CompileOptions::CompileOptions(JSContext* cx) cx->options().throwOnAsmJSValidationFailure(); fieldsEnabledOption = cx->realm()->creationOptions().getFieldsEnabled(); + // Certain modes of operation force strict-mode in general. + forceStrictMode_ = cx->options().strictMode(); + // Certain modes of operation disallow syntax parsing in general. forceFullParse_ = cx->realm()->behaviors().disableLazyParsing() || coverage::IsLCovEnabled(); diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 0ac394be1272..b2a620519c3f 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -944,7 +944,7 @@ static bool InitModuleLoader(JSContext* cx) { options.setSelfHostingMode(false); options.setCanLazilyParse(false); options.werrorOption = true; - options.strictOption = true; + options.setForceStrictMode(); JS::SourceText srcBuf; if (!srcBuf.init(cx, std::move(src), srcLen)) { @@ -5219,7 +5219,7 @@ static bool Parse(JSContext* cx, unsigned argc, Value* vp) { options.setIntroductionType("js shell parse").setFileAndLine("", 1); if (goal == frontend::ParseGoal::Module) { // See frontend::CompileModule. - options.maybeMakeStrictMode(true); + options.setForceStrictMode(); options.allowHTMLComments = false; } diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 7a6aa2bc8b3d..e9314f320559 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -2628,8 +2628,8 @@ void js::FillSelfHostingCompileOptions(CompileOptions& options) { options.setSelfHostingMode(true); options.setCanLazilyParse(false); options.werrorOption = true; - options.strictOption = true; options.extraWarningsOption = true; + options.setForceStrictMode(); } GlobalObject* JSRuntime::createSelfHostingGlobal(JSContext* cx) { diff --git a/js/src/wasm/AsmJS.cpp b/js/src/wasm/AsmJS.cpp index 90c5c3aa5186..cf29a43f2b15 100644 --- a/js/src/wasm/AsmJS.cpp +++ b/js/src/wasm/AsmJS.cpp @@ -6936,7 +6936,7 @@ static bool HandleInstantiationFailure(JSContext* cx, CallArgs args, // The exported function inherits an implicit strict context if the module // also inherited it somehow. if (metadata.strict) { - options.strictOption = true; + options.setForceStrictMode(); } AutoStableStringChars stableChars(cx); diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index b8cb88c0ef87..9ca624e594b5 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -845,7 +845,7 @@ nsresult mozJSComponentLoader::ObjectForLocation( // See bug 1303754. CompileOptions options(cx); options.setNoScriptRval(true) - .maybeMakeStrictMode(true) + .setForceStrictMode() .setFileAndLine(nativePath.get(), 1) .setSourceIsLazy(cache || ScriptPreloader::GetSingleton().Active());