Bug 1840996 - Add PrefableCompileOptions and use it in ContextOptions and CompileOptions. r=bthrall
Differential Revision: https://phabricator.services.mozilla.com/D182458
This commit is contained in:
@@ -117,6 +117,93 @@ enum class DelazificationOption : uint8_t {
|
||||
class JS_PUBLIC_API InstantiateOptions;
|
||||
class JS_PUBLIC_API DecodeOptions;
|
||||
|
||||
// Compilation-specific part of JS::ContextOptions which is supposed to be
|
||||
// configured by user prefs.
|
||||
class JS_PUBLIC_API PrefableCompileOptions {
|
||||
public:
|
||||
PrefableCompileOptions()
|
||||
: importAssertions_(false),
|
||||
sourcePragmas_(true),
|
||||
throwOnAsmJSValidationFailure_(false) {}
|
||||
|
||||
bool importAssertions() const { return importAssertions_; }
|
||||
PrefableCompileOptions& setImportAssertions(bool enabled) {
|
||||
importAssertions_ = enabled;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Enable/disable support for parsing '//(#@) source(Mapping)?URL=' pragmas.
|
||||
bool sourcePragmas() const { return sourcePragmas_; }
|
||||
PrefableCompileOptions& setSourcePragmas(bool flag) {
|
||||
sourcePragmas_ = flag;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsmJSOption asmJSOption() const { return asmJSOption_; }
|
||||
PrefableCompileOptions& setAsmJS(bool flag) {
|
||||
asmJSOption_ =
|
||||
flag ? AsmJSOption::Enabled : AsmJSOption::DisabledByAsmJSPref;
|
||||
return *this;
|
||||
}
|
||||
PrefableCompileOptions& setAsmJSOption(AsmJSOption option) {
|
||||
asmJSOption_ = option;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool throwOnAsmJSValidationFailure() const {
|
||||
return throwOnAsmJSValidationFailure_;
|
||||
}
|
||||
PrefableCompileOptions& setThrowOnAsmJSValidationFailure(bool flag) {
|
||||
throwOnAsmJSValidationFailure_ = flag;
|
||||
return *this;
|
||||
}
|
||||
PrefableCompileOptions& toggleThrowOnAsmJSValidationFailure() {
|
||||
throwOnAsmJSValidationFailure_ = !throwOnAsmJSValidationFailure_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(DEBUG) || defined(JS_JITSPEW)
|
||||
template <typename Printer>
|
||||
void dumpWith(Printer& print) const {
|
||||
# define PrintFields_(Name) print(#Name, Name)
|
||||
PrintFields_(importAssertions_);
|
||||
PrintFields_(sourcePragmas_);
|
||||
PrintFields_(throwOnAsmJSValidationFailure_);
|
||||
# undef PrintFields_
|
||||
|
||||
switch (asmJSOption_) {
|
||||
case AsmJSOption::Enabled:
|
||||
print("asmJSOption_", "AsmJSOption::Enabled");
|
||||
break;
|
||||
case AsmJSOption::DisabledByAsmJSPref:
|
||||
print("asmJSOption_", "AsmJSOption::DisabledByAsmJSPref");
|
||||
break;
|
||||
case AsmJSOption::DisabledByLinker:
|
||||
print("asmJSOption_", "AsmJSOption::DisabledByLinker");
|
||||
break;
|
||||
case AsmJSOption::DisabledByNoWasmCompiler:
|
||||
print("asmJSOption_", "AsmJSOption::DisabledByNoWasmCompiler");
|
||||
break;
|
||||
case AsmJSOption::DisabledByDebugger:
|
||||
print("asmJSOption_", "AsmJSOption::DisabledByDebugger");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // defined(DEBUG) || defined(JS_JITSPEW)
|
||||
|
||||
private:
|
||||
// ==== Syntax-related options. ====
|
||||
bool importAssertions_ : 1;
|
||||
|
||||
// The context has specified that source pragmas should be parsed.
|
||||
bool sourcePragmas_ : 1;
|
||||
|
||||
// ==== asm.js options. ====
|
||||
bool throwOnAsmJSValidationFailure_ : 1;
|
||||
|
||||
AsmJSOption asmJSOption_ = AsmJSOption::DisabledByAsmJSPref;
|
||||
};
|
||||
|
||||
/**
|
||||
* The common base class for the CompileOptions hierarchy.
|
||||
*
|
||||
@@ -161,9 +248,6 @@ class JS_PUBLIC_API TransitiveCompileOptions {
|
||||
// The Realm of this script is configured to use fdlibm math library.
|
||||
bool alwaysUseFdlibm_ = false;
|
||||
|
||||
// The context has specified that source pragmas should be parsed.
|
||||
bool sourcePragmas_ = true;
|
||||
|
||||
// Flag used to bypass the filename validation callback.
|
||||
// See also SetFilenameValidationCallback.
|
||||
bool skipFilenameValidation_ = false;
|
||||
@@ -187,8 +271,6 @@ class JS_PUBLIC_API TransitiveCompileOptions {
|
||||
|
||||
public:
|
||||
bool selfHostingMode = false;
|
||||
AsmJSOption asmJSOption = AsmJSOption::DisabledByAsmJSPref;
|
||||
bool throwOnAsmJSValidationFailureOption = false;
|
||||
bool forceAsync = false;
|
||||
bool discardSource = false;
|
||||
bool sourceIsLazy = false;
|
||||
@@ -199,8 +281,6 @@ class JS_PUBLIC_API TransitiveCompileOptions {
|
||||
// modules loaded with ChromeUtils.importModule.
|
||||
bool topLevelAwait = true;
|
||||
|
||||
bool importAssertions = false;
|
||||
|
||||
// When decoding from XDR into a Stencil, directly reference data in the
|
||||
// buffer (where possible) instead of copying it. This is an optional
|
||||
// performance optimization, and may also reduce memory if the buffer is going
|
||||
@@ -240,6 +320,8 @@ class JS_PUBLIC_API TransitiveCompileOptions {
|
||||
// WARNING: This option will eventually be removed.
|
||||
bool deoptimizeModuleGlobalVars = false;
|
||||
|
||||
PrefableCompileOptions prefableOptions_;
|
||||
|
||||
/**
|
||||
* |introductionType| is a statically allocated C string. See JSScript.h
|
||||
* for more information.
|
||||
@@ -301,7 +383,17 @@ class JS_PUBLIC_API TransitiveCompileOptions {
|
||||
DelazificationOption eagerDelazificationStrategy() const {
|
||||
return eagerDelazificationStrategy_;
|
||||
}
|
||||
bool sourcePragmas() const { return sourcePragmas_; }
|
||||
|
||||
bool importAssertions() const { return prefableOptions_.importAssertions(); }
|
||||
bool sourcePragmas() const { return prefableOptions_.sourcePragmas(); }
|
||||
bool throwOnAsmJSValidationFailure() const {
|
||||
return prefableOptions_.throwOnAsmJSValidationFailure();
|
||||
}
|
||||
AsmJSOption asmJSOption() const { return prefableOptions_.asmJSOption(); }
|
||||
void setAsmJSOption(AsmJSOption option) {
|
||||
prefableOptions_.setAsmJSOption(option);
|
||||
}
|
||||
|
||||
JS::ConstUTF8CharsZ filename() const { return filename_; }
|
||||
JS::ConstUTF8CharsZ introducerFilename() const { return introducerFilename_; }
|
||||
const char16_t* sourceMapURL() const { return sourceMapURL_; }
|
||||
@@ -319,21 +411,17 @@ class JS_PUBLIC_API TransitiveCompileOptions {
|
||||
PrintFields_(mutedErrors_);
|
||||
PrintFields_(forceStrictMode_);
|
||||
PrintFields_(alwaysUseFdlibm_);
|
||||
PrintFields_(sourcePragmas_);
|
||||
PrintFields_(skipFilenameValidation_);
|
||||
PrintFields_(hideScriptFromDebugger_);
|
||||
PrintFields_(deferDebugMetadata_);
|
||||
PrintFields_(eagerDelazificationStrategy_);
|
||||
PrintFields_(selfHostingMode);
|
||||
PrintFields_(asmJSOption);
|
||||
PrintFields_(throwOnAsmJSValidationFailureOption);
|
||||
PrintFields_(forceAsync);
|
||||
PrintFields_(discardSource);
|
||||
PrintFields_(sourceIsLazy);
|
||||
PrintFields_(allowHTMLComments);
|
||||
PrintFields_(nonSyntacticScope);
|
||||
PrintFields_(topLevelAwait);
|
||||
PrintFields_(importAssertions);
|
||||
PrintFields_(borrowBuffer);
|
||||
PrintFields_(usePinnedBytecode);
|
||||
PrintFields_(allocateInstantiationStorage);
|
||||
@@ -343,6 +431,8 @@ class JS_PUBLIC_API TransitiveCompileOptions {
|
||||
PrintFields_(introductionOffset);
|
||||
PrintFields_(hasIntroductionInfo);
|
||||
# undef PrintFields_
|
||||
|
||||
prefableOptions_.dumpWith(print);
|
||||
}
|
||||
#endif // defined(DEBUG) || defined(JS_JITSPEW)
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "jstypes.h" // JS_PUBLIC_API
|
||||
|
||||
#include "js/CompileOptions.h" // PrefableCompileOptions
|
||||
#include "js/WasmFeatures.h"
|
||||
|
||||
struct JS_PUBLIC_API JSContext;
|
||||
@@ -21,8 +22,7 @@ class JS_PUBLIC_API ContextOptions {
|
||||
public:
|
||||
// clang-format off
|
||||
ContextOptions()
|
||||
: asmJS_(true),
|
||||
wasm_(true),
|
||||
: wasm_(true),
|
||||
wasmForTrustedPrinciples_(true),
|
||||
wasmVerbose_(false),
|
||||
wasmBaseline_(true),
|
||||
@@ -33,12 +33,10 @@ class JS_PUBLIC_API ContextOptions {
|
||||
#undef WASM_DEFAULT_FEATURE
|
||||
#undef WASM_EXPERIMENTAL_FEATURE
|
||||
testWasmAwaitTier2_(false),
|
||||
throwOnAsmJSValidationFailure_(false),
|
||||
disableIon_(false),
|
||||
disableEvalSecurityChecks_(false),
|
||||
asyncStack_(true),
|
||||
asyncStackCaptureDebuggeeOnly_(false),
|
||||
sourcePragmas_(true),
|
||||
throwOnDebuggeeWouldRun_(true),
|
||||
dumpStackOnDebuggeeWouldRun_(false),
|
||||
strictMode_(false),
|
||||
@@ -46,18 +44,20 @@ class JS_PUBLIC_API ContextOptions {
|
||||
trackNotImplemented_(false),
|
||||
trySmoosh_(false),
|
||||
#endif
|
||||
fuzzing_(false),
|
||||
importAssertions_(false) {
|
||||
fuzzing_(false) {
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
bool asmJS() const { return asmJS_; }
|
||||
bool asmJS() const {
|
||||
return compileOptions_.asmJSOption() == AsmJSOption::Enabled;
|
||||
}
|
||||
AsmJSOption asmJSOption() const { return compileOptions_.asmJSOption(); }
|
||||
ContextOptions& setAsmJS(bool flag) {
|
||||
asmJS_ = flag;
|
||||
compileOptions_.setAsmJS(flag);
|
||||
return *this;
|
||||
}
|
||||
ContextOptions& toggleAsmJS() {
|
||||
asmJS_ = !asmJS_;
|
||||
ContextOptions& setAsmJSOption(AsmJSOption option) {
|
||||
compileOptions_.setAsmJSOption(option);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -111,14 +111,14 @@ class JS_PUBLIC_API ContextOptions {
|
||||
#undef WASM_FEATURE
|
||||
|
||||
bool throwOnAsmJSValidationFailure() const {
|
||||
return throwOnAsmJSValidationFailure_;
|
||||
return compileOptions_.throwOnAsmJSValidationFailure();
|
||||
}
|
||||
ContextOptions& setThrowOnAsmJSValidationFailure(bool flag) {
|
||||
throwOnAsmJSValidationFailure_ = flag;
|
||||
compileOptions_.setThrowOnAsmJSValidationFailure(flag);
|
||||
return *this;
|
||||
}
|
||||
ContextOptions& toggleThrowOnAsmJSValidationFailure() {
|
||||
throwOnAsmJSValidationFailure_ = !throwOnAsmJSValidationFailure_;
|
||||
compileOptions_.toggleThrowOnAsmJSValidationFailure();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -131,9 +131,9 @@ class JS_PUBLIC_API ContextOptions {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool importAssertions() const { return importAssertions_; }
|
||||
bool importAssertions() const { return compileOptions_.importAssertions(); }
|
||||
ContextOptions& setImportAssertions(bool enabled) {
|
||||
importAssertions_ = enabled;
|
||||
compileOptions_.setImportAssertions(enabled);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -160,9 +160,9 @@ class JS_PUBLIC_API ContextOptions {
|
||||
}
|
||||
|
||||
// Enable/disable support for parsing '//(#@) source(Mapping)?URL=' pragmas.
|
||||
bool sourcePragmas() const { return sourcePragmas_; }
|
||||
bool sourcePragmas() const { return compileOptions_.sourcePragmas(); }
|
||||
ContextOptions& setSourcePragmas(bool flag) {
|
||||
sourcePragmas_ = flag;
|
||||
compileOptions_.setSourcePragmas(flag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -213,12 +213,17 @@ class JS_PUBLIC_API ContextOptions {
|
||||
ContextOptions& setFuzzing(bool flag);
|
||||
|
||||
void disableOptionsForSafeMode() {
|
||||
setAsmJS(false);
|
||||
setAsmJSOption(AsmJSOption::DisabledByAsmJSPref);
|
||||
setWasmBaseline(false);
|
||||
}
|
||||
|
||||
PrefableCompileOptions& compileOptions() { return compileOptions_; }
|
||||
const PrefableCompileOptions& compileOptions() const {
|
||||
return compileOptions_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool asmJS_ : 1;
|
||||
// WASM options.
|
||||
bool wasm_ : 1;
|
||||
bool wasmForTrustedPrinciples_ : 1;
|
||||
bool wasmVerbose_ : 1;
|
||||
@@ -228,12 +233,14 @@ class JS_PUBLIC_API ContextOptions {
|
||||
JS_FOR_WASM_FEATURES(WASM_FEATURE, WASM_FEATURE, WASM_FEATURE)
|
||||
#undef WASM_FEATURE
|
||||
bool testWasmAwaitTier2_ : 1;
|
||||
bool throwOnAsmJSValidationFailure_ : 1;
|
||||
|
||||
// JIT options.
|
||||
bool disableIon_ : 1;
|
||||
bool disableEvalSecurityChecks_ : 1;
|
||||
|
||||
// Runtime options.
|
||||
bool asyncStack_ : 1;
|
||||
bool asyncStackCaptureDebuggeeOnly_ : 1;
|
||||
bool sourcePragmas_ : 1;
|
||||
bool throwOnDebuggeeWouldRun_ : 1;
|
||||
bool dumpStackOnDebuggeeWouldRun_ : 1;
|
||||
bool strictMode_ : 1;
|
||||
@@ -242,7 +249,9 @@ class JS_PUBLIC_API ContextOptions {
|
||||
bool trySmoosh_ : 1;
|
||||
#endif
|
||||
bool fuzzing_ : 1;
|
||||
bool importAssertions_ : 1;
|
||||
|
||||
// Compile options.
|
||||
PrefableCompileOptions compileOptions_;
|
||||
};
|
||||
|
||||
JS_PUBLIC_API ContextOptions& ContextOptionsRef(JSContext* cx);
|
||||
|
||||
@@ -4966,7 +4966,7 @@ bool GeneralParser<ParseHandler, Unit>::assertClause(
|
||||
ListNodeType assertionsSet) {
|
||||
MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assert));
|
||||
|
||||
if (!options().importAssertions) {
|
||||
if (!options().importAssertions()) {
|
||||
error(JSMSG_IMPORT_ASSERTIONS_NOT_SUPPORTED);
|
||||
return false;
|
||||
}
|
||||
@@ -12792,7 +12792,7 @@ GeneralParser<ParseHandler, Unit>::importExpr(YieldHandling yieldHandling,
|
||||
}
|
||||
|
||||
Node optionalArg;
|
||||
if (options().importAssertions) {
|
||||
if (options().importAssertions()) {
|
||||
if (next == TokenKind::Comma) {
|
||||
tokenStream.consumeKnownToken(TokenKind::Comma,
|
||||
TokenStream::SlashIsRegExp);
|
||||
|
||||
@@ -28,7 +28,7 @@ FRAGMENT(asmjs, segfault) {
|
||||
|
||||
JS::CompileOptions opts(cx);
|
||||
opts.setFileAndLine(__FILE__, line0 + 1);
|
||||
opts.asmJSOption = JS::AsmJSOption::Enabled;
|
||||
opts.setAsmJSOption(JS::AsmJSOption::Enabled);
|
||||
|
||||
JS::SourceText<mozilla::Utf8Unit> srcBuf;
|
||||
JS::Rooted<JS::Value> rval(cx);
|
||||
|
||||
@@ -2302,15 +2302,12 @@ void JS::TransitiveCompileOptions::copyPODTransitiveOptions(
|
||||
mutedErrors_ = rhs.mutedErrors_;
|
||||
forceStrictMode_ = rhs.forceStrictMode_;
|
||||
alwaysUseFdlibm_ = rhs.alwaysUseFdlibm_;
|
||||
sourcePragmas_ = rhs.sourcePragmas_;
|
||||
skipFilenameValidation_ = rhs.skipFilenameValidation_;
|
||||
hideScriptFromDebugger_ = rhs.hideScriptFromDebugger_;
|
||||
deferDebugMetadata_ = rhs.deferDebugMetadata_;
|
||||
eagerDelazificationStrategy_ = rhs.eagerDelazificationStrategy_;
|
||||
|
||||
selfHostingMode = rhs.selfHostingMode;
|
||||
asmJSOption = rhs.asmJSOption;
|
||||
throwOnAsmJSValidationFailureOption = rhs.throwOnAsmJSValidationFailureOption;
|
||||
forceAsync = rhs.forceAsync;
|
||||
discardSource = rhs.discardSource;
|
||||
sourceIsLazy = rhs.sourceIsLazy;
|
||||
@@ -2318,13 +2315,14 @@ void JS::TransitiveCompileOptions::copyPODTransitiveOptions(
|
||||
nonSyntacticScope = rhs.nonSyntacticScope;
|
||||
|
||||
topLevelAwait = rhs.topLevelAwait;
|
||||
importAssertions = rhs.importAssertions;
|
||||
|
||||
borrowBuffer = rhs.borrowBuffer;
|
||||
usePinnedBytecode = rhs.usePinnedBytecode;
|
||||
allocateInstantiationStorage = rhs.allocateInstantiationStorage;
|
||||
deoptimizeModuleGlobalVars = rhs.deoptimizeModuleGlobalVars;
|
||||
|
||||
prefableOptions_ = rhs.prefableOptions_;
|
||||
|
||||
introductionType = rhs.introductionType;
|
||||
introductionLineno = rhs.introductionLineno;
|
||||
introductionOffset = rhs.introductionOffset;
|
||||
@@ -2409,23 +2407,16 @@ bool JS::OwningCompileOptions::copy(JS::FrontendContext* fc,
|
||||
}
|
||||
|
||||
JS::CompileOptions::CompileOptions(JSContext* cx) : ReadOnlyCompileOptions() {
|
||||
if (!js::IsAsmJSCompilationAvailable(cx)) {
|
||||
// Distinguishing the cases is just for error reporting.
|
||||
asmJSOption = !cx->options().asmJS()
|
||||
? AsmJSOption::DisabledByAsmJSPref
|
||||
: AsmJSOption::DisabledByNoWasmCompiler;
|
||||
} else if (cx->realm() && (cx->realm()->debuggerObservesWasm() ||
|
||||
cx->realm()->debuggerObservesAsmJS())) {
|
||||
asmJSOption = AsmJSOption::DisabledByDebugger;
|
||||
} else {
|
||||
asmJSOption = AsmJSOption::Enabled;
|
||||
prefableOptions_ = cx->options().compileOptions();
|
||||
|
||||
if (cx->options().asmJSOption() == AsmJSOption::Enabled) {
|
||||
if (!js::IsAsmJSCompilationAvailable(cx)) {
|
||||
prefableOptions_.setAsmJSOption(AsmJSOption::DisabledByNoWasmCompiler);
|
||||
} else if (cx->realm() && (cx->realm()->debuggerObservesWasm() ||
|
||||
cx->realm()->debuggerObservesAsmJS())) {
|
||||
prefableOptions_.setAsmJSOption(AsmJSOption::DisabledByDebugger);
|
||||
}
|
||||
}
|
||||
throwOnAsmJSValidationFailureOption =
|
||||
cx->options().throwOnAsmJSValidationFailure();
|
||||
|
||||
importAssertions = cx->options().importAssertions();
|
||||
|
||||
sourcePragmas_ = cx->options().sourcePragmas();
|
||||
|
||||
// Certain modes of operation force strict-mode in general.
|
||||
forceStrictMode_ = cx->options().strictMode();
|
||||
|
||||
@@ -1955,7 +1955,7 @@ class MOZ_STACK_CLASS ModuleValidator : public ModuleValidatorShared {
|
||||
auto& ts = tokenStream();
|
||||
ErrorMetadata metadata;
|
||||
if (ts.computeErrorMetadata(&metadata, AsVariant(offset))) {
|
||||
if (ts.anyCharsAccess().options().throwOnAsmJSValidationFailureOption) {
|
||||
if (ts.anyCharsAccess().options().throwOnAsmJSValidationFailure()) {
|
||||
ReportCompileErrorLatin1(fc_, std::move(metadata), nullptr,
|
||||
JSMSG_USE_ASM_TYPE_FAIL, &args);
|
||||
} else {
|
||||
@@ -7010,7 +7010,7 @@ static bool HandleInstantiationFailure(JSContext* cx, CallArgs args,
|
||||
options.setMutedErrors(source->mutedErrors())
|
||||
.setFile(source->filename())
|
||||
.setNoScriptRval(false);
|
||||
options.asmJSOption = AsmJSOption::DisabledByLinker;
|
||||
options.setAsmJSOption(AsmJSOption::DisabledByLinker);
|
||||
|
||||
// The exported function inherits an implicit strict context if the module
|
||||
// also inherited it somehow.
|
||||
@@ -7090,7 +7090,7 @@ static bool SuccessfulValidation(frontend::ParserBase& parser,
|
||||
}
|
||||
|
||||
static bool TypeFailureWarning(frontend::ParserBase& parser, const char* str) {
|
||||
if (parser.options().throwOnAsmJSValidationFailureOption) {
|
||||
if (parser.options().throwOnAsmJSValidationFailure()) {
|
||||
parser.errorNoOffset(JSMSG_USE_ASM_TYPE_FAIL, str ? str : "");
|
||||
return false;
|
||||
}
|
||||
@@ -7109,7 +7109,7 @@ static bool IsAsmJSCompilerAvailable(JSContext* cx) {
|
||||
}
|
||||
|
||||
static bool EstablishPreconditions(frontend::ParserBase& parser) {
|
||||
switch (parser.options().asmJSOption) {
|
||||
switch (parser.options().asmJSOption()) {
|
||||
case AsmJSOption::DisabledByAsmJSPref:
|
||||
return TypeFailureWarning(
|
||||
parser, "Asm.js optimizer disabled by 'asmjs' runtime option");
|
||||
|
||||
Reference in New Issue
Block a user