mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 1664361 - wasm: Add function-references configuration option and runtime flag. r=lth
This commit adds the boilerplate machinery for the function-references proposal. The interesting piece is that the GC proposal is moved to require the function-references proposal to be enabled. The configuration machinery for features is refactored in this commit to avoid passing 6 different booleans around as parameters to functions. * A FeatureArgs struct is added with values for all 'feature' configuration options - A feature is defined as an option that affects validation or semantics - Essentially everything besides 'debug', 'mode', 'tier' * All feature configuration responsibility is removed from CompilerEnvironment * ModuleEnvironment is modified to accept a FeatureArgs in addition to a CompilerEnvironment - The CompilerEnvironment field may eventually be removed, as it's not needed within function validation, and is only used by the compilers later Differential Revision: https://phabricator.services.mozilla.com/D89857
This commit is contained in:
parent
5f7ab67e9c
commit
33b1e95109
@ -277,7 +277,11 @@ void LoadContextOptions(const char* aPrefName, void* /* aClosure */) {
|
||||
#ifdef ENABLE_WASM_SIMD
|
||||
.setWasmSimd(GetWorkerPref<bool>("wasm_simd"_ns))
|
||||
#endif
|
||||
#ifdef ENABLE_WASM_REFTYPES
|
||||
#ifdef ENABLE_WASM_FUNCTION_REFERENCES
|
||||
.setWasmFunctionReferences(
|
||||
GetWorkerPref<bool>("wasm_function_references"_ns))
|
||||
#endif
|
||||
#ifdef ENABLE_WASM_GC
|
||||
.setWasmGc(GetWorkerPref<bool>("wasm_gc"_ns))
|
||||
#endif
|
||||
.setWasmVerbose(GetWorkerPref<bool>("wasm_verbose"_ns))
|
||||
|
@ -542,28 +542,52 @@ def enable_wasm_reftypes(value):
|
||||
set_config('ENABLE_WASM_REFTYPES', enable_wasm_reftypes)
|
||||
set_define('ENABLE_WASM_REFTYPES', enable_wasm_reftypes)
|
||||
|
||||
# Support for WebAssembly function-references.
|
||||
# ===========================
|
||||
|
||||
@depends(milestone.is_nightly, '--disable-wasm-reftypes')
|
||||
def default_wasm_function_references(is_nightly, reftypes):
|
||||
if is_nightly and reftypes:
|
||||
return True
|
||||
|
||||
js_option('--enable-wasm-function-references',
|
||||
default=default_wasm_function_references,
|
||||
help='{Enable|Disable} WebAssembly function-references')
|
||||
|
||||
@depends('--enable-wasm-function-references', '--disable-wasm-reftypes')
|
||||
def wasm_function_references(value, reftypes):
|
||||
if not value:
|
||||
return
|
||||
|
||||
if reftypes:
|
||||
return True
|
||||
|
||||
die('--enable-wasm-function-references only possible without --disable-wasm-reftypes')
|
||||
|
||||
set_config('ENABLE_WASM_FUNCTION_REFERENCES', wasm_function_references)
|
||||
set_define('ENABLE_WASM_FUNCTION_REFERENCES', wasm_function_references)
|
||||
|
||||
# Support for WebAssembly GC.
|
||||
# ===========================
|
||||
|
||||
@depends(milestone.is_nightly, '--enable-wasm-reftypes', '--enable-typed-objects')
|
||||
def default_wasm_gc(is_nightly, reftypes, typed_objects):
|
||||
if is_nightly and reftypes and typed_objects:
|
||||
@depends(milestone.is_nightly, '--enable-wasm-function-references', '--enable-typed-objects')
|
||||
def default_wasm_gc(is_nightly, function_references, typed_objects):
|
||||
if is_nightly and function_references and typed_objects:
|
||||
return True
|
||||
|
||||
js_option('--enable-wasm-gc',
|
||||
default=default_wasm_gc,
|
||||
help='{Enable|Disable} WebAssembly GC')
|
||||
|
||||
@depends('--enable-wasm-gc', '--enable-wasm-reftypes', '--enable-typed-objects')
|
||||
def wasm_gc(value, reftypes, typed_objects):
|
||||
@depends('--enable-wasm-gc', '--enable-wasm-function-references', '--enable-typed-objects')
|
||||
def wasm_gc(value, function_references, typed_objects):
|
||||
if not value:
|
||||
return
|
||||
|
||||
if reftypes and typed_objects:
|
||||
if function_references and typed_objects:
|
||||
return True
|
||||
|
||||
die('--enable-wasm-gc only possible with --enable-wasm-reftypes and --enable-typed-objects')
|
||||
die('--enable-wasm-gc only possible with --enable-wasm-function-references and --enable-typed-objects')
|
||||
|
||||
set_config('ENABLE_WASM_GC', wasm_gc)
|
||||
set_define('ENABLE_WASM_GC', wasm_gc)
|
||||
|
@ -26,6 +26,7 @@ class JS_PUBLIC_API ContextOptions {
|
||||
wasmIon_(true),
|
||||
wasmCranelift_(false),
|
||||
wasmReftypes_(true),
|
||||
wasmFunctionReferences_(false),
|
||||
wasmGc_(false),
|
||||
wasmMultiValue_(false),
|
||||
wasmSimd_(false),
|
||||
@ -108,6 +109,10 @@ class JS_PUBLIC_API ContextOptions {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool wasmFunctionReferences() const { return wasmFunctionReferences_; }
|
||||
// Defined out-of-line because it depends on a compile-time option
|
||||
ContextOptions& setWasmFunctionReferences(bool flag);
|
||||
|
||||
bool wasmGc() const { return wasmGc_; }
|
||||
// Defined out-of-line because it depends on a compile-time option
|
||||
ContextOptions& setWasmGc(bool flag);
|
||||
@ -242,6 +247,7 @@ class JS_PUBLIC_API ContextOptions {
|
||||
bool wasmIon_ : 1;
|
||||
bool wasmCranelift_ : 1;
|
||||
bool wasmReftypes_ : 1;
|
||||
bool wasmFunctionReferences_ : 1;
|
||||
bool wasmGc_ : 1;
|
||||
bool wasmMultiValue_ : 1;
|
||||
bool wasmSimd_ : 1;
|
||||
|
@ -849,6 +849,13 @@ static bool WasmReftypesEnabled(JSContext* cx, unsigned argc, Value* vp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool WasmFunctionReferencesEnabled(JSContext* cx, unsigned argc,
|
||||
Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
args.rval().setBoolean(wasm::FunctionReferencesAvailable(cx));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool WasmGcEnabled(JSContext* cx, unsigned argc, Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
args.rval().setBoolean(wasm::GcTypesAvailable(cx));
|
||||
@ -6833,6 +6840,10 @@ gc::ZealModeHelpText),
|
||||
"wasmReftypesEnabled()",
|
||||
" Returns a boolean indicating whether the WebAssembly reftypes proposal is enabled."),
|
||||
|
||||
JS_FN_HELP("wasmFunctionReferencesEnabled", WasmFunctionReferencesEnabled, 1, 0,
|
||||
"wasmFunctionReferencesEnabled()",
|
||||
" Returns a boolean indicating whether the WebAssembly function-references proposal is enabled."),
|
||||
|
||||
JS_FN_HELP("wasmGcEnabled", WasmGcEnabled, 1, 0,
|
||||
"wasmGcEnabled()",
|
||||
" Returns a boolean indicating whether the WebAssembly GC types proposal is enabled."),
|
||||
|
@ -430,6 +430,13 @@ JS::ContextOptions& JS::ContextOptions::setWasmCranelift(bool flag) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
JS::ContextOptions& JS::ContextOptions::setWasmFunctionReferences(bool flag) {
|
||||
#ifdef ENABLE_WASM_FUNCTION_REFERENCES
|
||||
wasmFunctionReferences_ = flag;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
JS::ContextOptions& JS::ContextOptions::setWasmGc(bool flag) {
|
||||
#ifdef ENABLE_WASM_GC
|
||||
wasmGc_ = flag;
|
||||
|
@ -502,6 +502,9 @@ bool shell::enableWasmBaseline = false;
|
||||
bool shell::enableWasmIon = false;
|
||||
bool shell::enableWasmCranelift = false;
|
||||
bool shell::enableWasmReftypes = true;
|
||||
#ifdef ENABLE_WASM_FUNCTION_REFERENCES
|
||||
bool shell::enableWasmFunctionReferences = false;
|
||||
#endif
|
||||
#ifdef ENABLE_WASM_GC
|
||||
bool shell::enableWasmGc = false;
|
||||
#endif
|
||||
@ -10325,6 +10328,9 @@ static bool SetContextOptions(JSContext* cx, const OptionParser& op) {
|
||||
}
|
||||
|
||||
enableWasmReftypes = !op.getBoolOption("no-wasm-reftypes");
|
||||
#ifdef ENABLE_WASM_FUNCTION_REFERENCES
|
||||
enableWasmFunctionReferences = op.getBoolOption("wasm-function-references");
|
||||
#endif
|
||||
#ifdef ENABLE_WASM_GC
|
||||
enableWasmGc = op.getBoolOption("wasm-gc");
|
||||
#endif
|
||||
@ -10365,6 +10371,9 @@ static bool SetContextOptions(JSContext* cx, const OptionParser& op) {
|
||||
#ifdef ENABLE_WASM_CRANELIFT
|
||||
.setWasmCranelift(enableWasmCranelift)
|
||||
#endif
|
||||
#ifdef ENABLE_WASM_FUNCTION_REFERENCES
|
||||
.setWasmFunctionReferences(enableWasmFunctionReferences)
|
||||
#endif
|
||||
#ifdef ENABLE_WASM_GC
|
||||
.setWasmGc(enableWasmGc)
|
||||
#endif
|
||||
@ -11181,6 +11190,13 @@ int main(int argc, char** argv, char** envp) {
|
||||
"instantiation on completion of tier2") ||
|
||||
!op.addBoolOption('\0', "no-wasm-reftypes",
|
||||
"Disable wasm reference types features") ||
|
||||
#ifdef ENABLE_WASM_FUNCTION_REFERENCES
|
||||
!op.addBoolOption(
|
||||
'\0', "wasm-function-references",
|
||||
"Enable experimental wasm function-references features") ||
|
||||
#else
|
||||
!op.addBoolOption('\0', "wasm-function-references", "No-op") ||
|
||||
#endif
|
||||
#ifdef ENABLE_WASM_GC
|
||||
!op.addBoolOption('\0', "wasm-gc",
|
||||
"Enable experimental wasm GC features") ||
|
||||
|
@ -113,6 +113,9 @@ extern bool enableWasmBaseline;
|
||||
extern bool enableWasmIon;
|
||||
extern bool enableWasmCranelift;
|
||||
extern bool enableWasmReftypes;
|
||||
#ifdef ENABLE_WASM_FUNCTION_REFERENCES
|
||||
extern bool enableWasmFunctionReferences;
|
||||
#endif
|
||||
#ifdef ENABLE_WASM_GC
|
||||
extern bool enableWasmGc;
|
||||
#endif
|
||||
|
@ -1358,10 +1358,8 @@ class MOZ_STACK_CLASS ModuleValidatorShared {
|
||||
funcImportMap_(cx),
|
||||
arrayViews_(cx),
|
||||
compilerEnv_(CompileMode::Once, Tier::Optimized, OptimizedBackend::Ion,
|
||||
DebugEnabled::False, /* multi value */ false,
|
||||
/* ref types */ false, /* gc types */ false,
|
||||
/* huge memory */ false, /* v128 */ false),
|
||||
env_(&compilerEnv_, Shareable::False, ModuleKind::AsmJS) {
|
||||
DebugEnabled::False),
|
||||
env_(&compilerEnv_, FeatureArgs(), ModuleKind::AsmJS) {
|
||||
compilerEnv_.computeParameters();
|
||||
env_.minMemoryLength = RoundUpToNextValidAsmJSHeapLength(0);
|
||||
}
|
||||
|
@ -14896,7 +14896,7 @@ bool BaseCompiler::emitBody() {
|
||||
|
||||
// Thread operations
|
||||
case uint16_t(Op::ThreadPrefix): {
|
||||
if (env_.sharedMemoryEnabled == Shareable::False) {
|
||||
if (env_.sharedMemoryEnabled() == Shareable::False) {
|
||||
return iter_.unrecognizedOpcode(&op);
|
||||
}
|
||||
switch (op.b1) {
|
||||
|
@ -77,6 +77,19 @@ uint32_t wasm::ObservedCPUFeatures() {
|
||||
#endif
|
||||
}
|
||||
|
||||
FeatureArgs FeatureArgs::build(JSContext* cx) {
|
||||
FeatureArgs features;
|
||||
features.sharedMemory =
|
||||
wasm::ThreadsAvailable(cx) ? Shareable::True : Shareable::False;
|
||||
features.refTypes = wasm::ReftypesAvailable(cx);
|
||||
features.functionReferences = wasm::FunctionReferencesAvailable(cx);
|
||||
features.gcTypes = wasm::GcTypesAvailable(cx);
|
||||
features.multiValue = wasm::MultiValuesAvailable(cx);
|
||||
features.v128 = wasm::SimdAvailable(cx);
|
||||
features.hugeMemory = wasm::IsHugeMemoryEnabled();
|
||||
return features;
|
||||
}
|
||||
|
||||
SharedCompileArgs CompileArgs::build(JSContext* cx,
|
||||
ScriptedCaller&& scriptedCaller) {
|
||||
bool baseline = BaselineAvailable(cx);
|
||||
@ -124,13 +137,8 @@ SharedCompileArgs CompileArgs::build(JSContext* cx,
|
||||
target->ionEnabled = ion;
|
||||
target->craneliftEnabled = cranelift;
|
||||
target->debugEnabled = debug;
|
||||
target->sharedMemoryEnabled = wasm::ThreadsAvailable(cx);
|
||||
target->forceTiering = forceTiering;
|
||||
target->reftypesEnabled = wasm::ReftypesAvailable(cx);
|
||||
target->gcEnabled = wasm::GcTypesAvailable(cx);
|
||||
target->hugeMemory = wasm::IsHugeMemoryEnabled();
|
||||
target->multiValuesEnabled = wasm::MultiValuesAvailable(cx);
|
||||
target->v128Enabled = wasm::SimdAvailable(cx);
|
||||
target->features = FeatureArgs::build(cx);
|
||||
|
||||
Log(cx, "available wasm compilers: tier1=%s tier2=%s",
|
||||
baseline ? "baseline" : "none",
|
||||
@ -428,21 +436,12 @@ CompilerEnvironment::CompilerEnvironment(const CompileArgs& args)
|
||||
|
||||
CompilerEnvironment::CompilerEnvironment(CompileMode mode, Tier tier,
|
||||
OptimizedBackend optimizedBackend,
|
||||
DebugEnabled debugEnabled,
|
||||
bool multiValueConfigured,
|
||||
bool refTypesConfigured,
|
||||
bool gcTypesConfigured,
|
||||
bool hugeMemory, bool v128Configured)
|
||||
DebugEnabled debugEnabled)
|
||||
: state_(InitialWithModeTierDebug),
|
||||
mode_(mode),
|
||||
tier_(tier),
|
||||
optimizedBackend_(optimizedBackend),
|
||||
debug_(debugEnabled),
|
||||
refTypes_(refTypesConfigured),
|
||||
gcTypes_(gcTypesConfigured),
|
||||
multiValues_(multiValueConfigured),
|
||||
hugeMemory_(hugeMemory),
|
||||
v128_(v128Configured) {}
|
||||
debug_(debugEnabled) {}
|
||||
|
||||
void CompilerEnvironment::computeParameters() {
|
||||
MOZ_ASSERT(state_ == InitialWithModeTierDebug);
|
||||
@ -472,16 +471,11 @@ void CompilerEnvironment::computeParameters(Decoder& d) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool reftypesEnabled = args_->reftypesEnabled;
|
||||
bool gcEnabled = args_->gcEnabled;
|
||||
bool baselineEnabled = args_->baselineEnabled;
|
||||
bool ionEnabled = args_->ionEnabled;
|
||||
bool debugEnabled = args_->debugEnabled;
|
||||
bool craneliftEnabled = args_->craneliftEnabled;
|
||||
bool forceTiering = args_->forceTiering;
|
||||
bool hugeMemory = args_->hugeMemory;
|
||||
bool multiValuesEnabled = args_->multiValuesEnabled;
|
||||
bool v128Enabled = args_->v128Enabled;
|
||||
|
||||
bool hasSecondTier = ionEnabled || craneliftEnabled;
|
||||
MOZ_ASSERT_IF(debugEnabled, baselineEnabled);
|
||||
@ -511,12 +505,6 @@ void CompilerEnvironment::computeParameters(Decoder& d) {
|
||||
craneliftEnabled ? OptimizedBackend::Cranelift : OptimizedBackend::Ion;
|
||||
|
||||
debug_ = debugEnabled ? DebugEnabled::True : DebugEnabled::False;
|
||||
refTypes_ = reftypesEnabled;
|
||||
gcTypes_ = gcEnabled;
|
||||
multiValues_ = multiValuesEnabled;
|
||||
hugeMemory_ = hugeMemory;
|
||||
multiValues_ = multiValuesEnabled;
|
||||
v128_ = v128Enabled;
|
||||
|
||||
state_ = Computed;
|
||||
}
|
||||
@ -589,9 +577,7 @@ SharedModule wasm::CompileBuffer(const CompileArgs& args,
|
||||
Decoder d(bytecode.bytes, 0, error, warnings);
|
||||
|
||||
CompilerEnvironment compilerEnv(args);
|
||||
ModuleEnvironment env(&compilerEnv, args.sharedMemoryEnabled
|
||||
? Shareable::True
|
||||
: Shareable::False);
|
||||
ModuleEnvironment env(&compilerEnv, args.features);
|
||||
if (!DecodeModuleEnvironment(d, &env)) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -618,27 +604,14 @@ void wasm::CompileTier2(const CompileArgs& args, const Bytes& bytecode,
|
||||
UniqueChars error;
|
||||
Decoder d(bytecode, 0, &error);
|
||||
|
||||
bool gcTypesConfigured = false; // No optimized backend support yet
|
||||
#ifdef ENABLE_WASM_REFTYPES
|
||||
bool refTypesConfigured = true;
|
||||
#else
|
||||
bool refTypesConfigured = false;
|
||||
#endif
|
||||
bool multiValueConfigured = args.multiValuesEnabled;
|
||||
bool v128Configured = args.v128Enabled;
|
||||
|
||||
OptimizedBackend optimizedBackend = args.craneliftEnabled
|
||||
? OptimizedBackend::Cranelift
|
||||
: OptimizedBackend::Ion;
|
||||
|
||||
CompilerEnvironment compilerEnv(
|
||||
CompileMode::Tier2, Tier::Optimized, optimizedBackend,
|
||||
DebugEnabled::False, multiValueConfigured, refTypesConfigured,
|
||||
gcTypesConfigured, args.hugeMemory, v128Configured);
|
||||
CompilerEnvironment compilerEnv(CompileMode::Tier2, Tier::Optimized,
|
||||
optimizedBackend, DebugEnabled::False);
|
||||
|
||||
ModuleEnvironment env(&compilerEnv, args.sharedMemoryEnabled
|
||||
? Shareable::True
|
||||
: Shareable::False);
|
||||
ModuleEnvironment env(&compilerEnv, args.features);
|
||||
if (!DecodeModuleEnvironment(d, &env)) {
|
||||
return;
|
||||
}
|
||||
@ -746,9 +719,7 @@ SharedModule wasm::CompileStreaming(
|
||||
const Atomic<bool>& cancelled, UniqueChars* error,
|
||||
UniqueCharsVector* warnings, JSTelemetrySender telemetrySender) {
|
||||
CompilerEnvironment compilerEnv(args);
|
||||
ModuleEnvironment env(&compilerEnv, args.sharedMemoryEnabled
|
||||
? Shareable::True
|
||||
: Shareable::False);
|
||||
ModuleEnvironment env(&compilerEnv, args.features);
|
||||
|
||||
{
|
||||
Decoder d(envBytes, 0, error, warnings);
|
||||
|
@ -40,6 +40,29 @@ struct ScriptedCaller {
|
||||
ScriptedCaller() : filenameIsURL(false), line(0) {}
|
||||
};
|
||||
|
||||
// Describes the features that control wasm compilation.
|
||||
|
||||
struct FeatureArgs {
|
||||
FeatureArgs()
|
||||
: sharedMemory(Shareable::False),
|
||||
refTypes(false),
|
||||
functionReferences(false),
|
||||
gcTypes(false),
|
||||
multiValue(false),
|
||||
v128(false),
|
||||
hugeMemory(false) {}
|
||||
|
||||
static FeatureArgs build(JSContext* cx);
|
||||
|
||||
Shareable sharedMemory;
|
||||
bool refTypes;
|
||||
bool functionReferences;
|
||||
bool gcTypes;
|
||||
bool multiValue;
|
||||
bool v128;
|
||||
bool hugeMemory;
|
||||
};
|
||||
|
||||
// Describes all the parameters that control wasm compilation.
|
||||
|
||||
struct CompileArgs;
|
||||
@ -54,13 +77,9 @@ struct CompileArgs : ShareableBase<CompileArgs> {
|
||||
bool ionEnabled;
|
||||
bool craneliftEnabled;
|
||||
bool debugEnabled;
|
||||
bool sharedMemoryEnabled;
|
||||
bool forceTiering;
|
||||
bool reftypesEnabled;
|
||||
bool gcEnabled;
|
||||
bool hugeMemory;
|
||||
bool multiValuesEnabled;
|
||||
bool v128Enabled;
|
||||
|
||||
FeatureArgs features;
|
||||
|
||||
// CompileArgs has two constructors:
|
||||
//
|
||||
@ -80,13 +99,7 @@ struct CompileArgs : ShareableBase<CompileArgs> {
|
||||
ionEnabled(false),
|
||||
craneliftEnabled(false),
|
||||
debugEnabled(false),
|
||||
sharedMemoryEnabled(false),
|
||||
forceTiering(false),
|
||||
reftypesEnabled(false),
|
||||
gcEnabled(false),
|
||||
hugeMemory(false),
|
||||
multiValuesEnabled(false),
|
||||
v128Enabled(false) {}
|
||||
forceTiering(false) {}
|
||||
};
|
||||
|
||||
// Return the estimated compiled (machine) code size for the given bytecode size
|
||||
|
@ -5013,7 +5013,7 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
|
||||
|
||||
// Thread operations
|
||||
case uint16_t(Op::ThreadPrefix): {
|
||||
if (f.env().sharedMemoryEnabled == Shareable::False) {
|
||||
if (f.env().sharedMemoryEnabled() == Shareable::False) {
|
||||
return f.iter().unrecognizedOpcode(&op);
|
||||
}
|
||||
switch (op.b1) {
|
||||
|
@ -127,11 +127,26 @@ static inline bool WasmReftypesFlag(JSContext* cx) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool WasmFunctionReferencesFlag(JSContext* cx) {
|
||||
if (IsFuzzingIon(cx) || IsFuzzingCranelift(cx)) {
|
||||
return false;
|
||||
}
|
||||
#ifdef ENABLE_WASM_FUNCTION_REFERENCES
|
||||
return WasmReftypesFlag(cx) && cx->options().wasmFunctionReferences();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool WasmGcFlag(JSContext* cx) {
|
||||
if (IsFuzzingIon(cx) || IsFuzzingCranelift(cx)) {
|
||||
return false;
|
||||
}
|
||||
return cx->options().wasmGc();
|
||||
#ifdef ENABLE_WASM_GC
|
||||
return WasmFunctionReferencesFlag(cx) && cx->options().wasmGc();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool WasmThreadsFlag(JSContext* cx) {
|
||||
@ -273,17 +288,21 @@ bool wasm::IonDisabledByFeatures(JSContext* cx, bool* isDisabled,
|
||||
JSStringBuilder* reason) {
|
||||
// Ion has no debugging support, no gc support.
|
||||
bool debug = WasmDebuggerActive(cx);
|
||||
bool functionReferences = WasmFunctionReferencesFlag(cx);
|
||||
bool gc = WasmGcFlag(cx);
|
||||
if (reason) {
|
||||
char sep = 0;
|
||||
if (debug && !Append(reason, "debug", &sep)) {
|
||||
return false;
|
||||
}
|
||||
if (functionReferences && !Append(reason, "function-references", &sep)) {
|
||||
return false;
|
||||
}
|
||||
if (gc && !Append(reason, "gc", &sep)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*isDisabled = debug || gc;
|
||||
*isDisabled = debug || functionReferences || gc;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -300,6 +319,7 @@ bool wasm::CraneliftDisabledByFeatures(JSContext* cx, bool* isDisabled,
|
||||
JSStringBuilder* reason) {
|
||||
// Cranelift has no debugging support, no gc support, no simd.
|
||||
bool debug = WasmDebuggerActive(cx);
|
||||
bool functionReferences = WasmFunctionReferencesFlag(cx);
|
||||
bool gc = WasmGcFlag(cx);
|
||||
bool simd = WasmSimdFlag(cx);
|
||||
if (reason) {
|
||||
@ -307,6 +327,9 @@ bool wasm::CraneliftDisabledByFeatures(JSContext* cx, bool* isDisabled,
|
||||
if (debug && !Append(reason, "debug", &sep)) {
|
||||
return false;
|
||||
}
|
||||
if (functionReferences && !Append(reason, "function-references", &sep)) {
|
||||
return false;
|
||||
}
|
||||
if (gc && !Append(reason, "gc", &sep)) {
|
||||
return false;
|
||||
}
|
||||
@ -314,7 +337,7 @@ bool wasm::CraneliftDisabledByFeatures(JSContext* cx, bool* isDisabled,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*isDisabled = debug || gc || simd;
|
||||
*isDisabled = debug || functionReferences || gc || simd;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -336,6 +359,11 @@ bool wasm::ReftypesAvailable(JSContext* cx) {
|
||||
return WasmReftypesFlag(cx) && AnyCompilerAvailable(cx);
|
||||
}
|
||||
|
||||
bool wasm::FunctionReferencesAvailable(JSContext* cx) {
|
||||
// Cranelift and Ion do not support function-references.
|
||||
return WasmFunctionReferencesFlag(cx) && BaselineAvailable(cx);
|
||||
}
|
||||
|
||||
bool wasm::GcTypesAvailable(JSContext* cx) {
|
||||
// Cranelift and Ion do not support GC.
|
||||
return WasmGcFlag(cx) && BaselineAvailable(cx);
|
||||
@ -351,8 +379,7 @@ bool wasm::SimdAvailable(JSContext* cx) {
|
||||
}
|
||||
|
||||
bool wasm::ThreadsAvailable(JSContext* cx) {
|
||||
return WasmThreadsFlag(cx) &&
|
||||
(BaselineAvailable(cx) || IonAvailable(cx) || CraneliftAvailable(cx));
|
||||
return WasmThreadsFlag(cx) && AnyCompilerAvailable(cx);
|
||||
}
|
||||
|
||||
bool wasm::HasPlatformSupport(JSContext* cx) {
|
||||
@ -826,7 +853,7 @@ bool wasm::CompileAndSerialize(const ShareableBytes& bytecode,
|
||||
|
||||
// The caller must ensure that huge memory support is configured the same in
|
||||
// the receiving process of this serialized module.
|
||||
compileArgs->hugeMemory = wasm::IsHugeMemoryEnabled();
|
||||
compileArgs->features.hugeMemory = wasm::IsHugeMemoryEnabled();
|
||||
|
||||
SerializeListener listener(serialized);
|
||||
|
||||
|
@ -106,6 +106,9 @@ bool CodeCachingAvailable(JSContext* cx);
|
||||
// General reference types (externref, funcref) and operations on them.
|
||||
bool ReftypesAvailable(JSContext* cx);
|
||||
|
||||
// Typed functions reference support.
|
||||
bool FunctionReferencesAvailable(JSContext* cx);
|
||||
|
||||
// Experimental (ref T) types and structure types.
|
||||
bool GcTypesAvailable(JSContext* cx);
|
||||
|
||||
|
@ -902,7 +902,7 @@ inline bool OpIter<Policy>::readBlockType(BlockType* type) {
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WASM_MULTI_VALUE
|
||||
if (!env_.multiValuesEnabled()) {
|
||||
if (!env_.multiValueEnabled()) {
|
||||
return fail("invalid block type reference");
|
||||
}
|
||||
|
||||
|
@ -1300,7 +1300,7 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
|
||||
}
|
||||
#endif
|
||||
case uint16_t(Op::ThreadPrefix): {
|
||||
if (env.sharedMemoryEnabled == Shareable::False) {
|
||||
if (env.sharedMemoryEnabled() == Shareable::False) {
|
||||
return iter.unrecognizedOpcode(&op);
|
||||
}
|
||||
switch (op.b1) {
|
||||
@ -2013,7 +2013,7 @@ static bool DecodeMemoryLimits(Decoder& d, ModuleEnvironment* env) {
|
||||
ConvertMemoryPagesToBytes(&memory);
|
||||
|
||||
if (memory.shared == Shareable::True &&
|
||||
env->sharedMemoryEnabled == Shareable::False) {
|
||||
env->sharedMemoryEnabled() == Shareable::False) {
|
||||
return d.fail("shared memory is disabled");
|
||||
}
|
||||
|
||||
@ -3214,21 +3214,10 @@ bool wasm::Validate(JSContext* cx, const ShareableBytes& bytecode,
|
||||
UniqueChars* error) {
|
||||
Decoder d(bytecode.bytes, 0, error);
|
||||
|
||||
bool gcTypesConfigured = GcTypesAvailable(cx);
|
||||
bool refTypesConfigured = ReftypesAvailable(cx);
|
||||
bool multiValueConfigured = MultiValuesAvailable(cx);
|
||||
bool hugeMemory = false;
|
||||
bool v128Configured = SimdAvailable(cx);
|
||||
|
||||
CompilerEnvironment compilerEnv(
|
||||
CompileMode::Once, Tier::Optimized, OptimizedBackend::Ion,
|
||||
DebugEnabled::False, multiValueConfigured, refTypesConfigured,
|
||||
gcTypesConfigured, hugeMemory, v128Configured);
|
||||
ModuleEnvironment env(
|
||||
&compilerEnv,
|
||||
cx->realm()->creationOptions().getSharedMemoryAndAtomicsEnabled()
|
||||
? Shareable::True
|
||||
: Shareable::False);
|
||||
FeatureArgs features = FeatureArgs::build(cx);
|
||||
CompilerEnvironment compilerEnv(CompileMode::Once, Tier::Optimized,
|
||||
OptimizedBackend::Ion, DebugEnabled::False);
|
||||
ModuleEnvironment env(&compilerEnv, features);
|
||||
if (!DecodeModuleEnvironment(d, &env)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "ds/Bitmap.h"
|
||||
|
||||
#include "wasm/WasmCompile.h"
|
||||
#include "wasm/WasmTypes.h"
|
||||
|
||||
namespace js {
|
||||
@ -69,11 +70,6 @@ struct CompilerEnvironment {
|
||||
Tier tier_;
|
||||
OptimizedBackend optimizedBackend_;
|
||||
DebugEnabled debug_;
|
||||
bool refTypes_;
|
||||
bool gcTypes_;
|
||||
bool multiValues_;
|
||||
bool hugeMemory_;
|
||||
bool v128_;
|
||||
};
|
||||
};
|
||||
|
||||
@ -87,9 +83,7 @@ struct CompilerEnvironment {
|
||||
// final value of gcTypes/refTypes.
|
||||
CompilerEnvironment(CompileMode mode, Tier tier,
|
||||
OptimizedBackend optimizedBackend,
|
||||
DebugEnabled debugEnabled, bool multiValueConfigured,
|
||||
bool refTypesConfigured, bool gcTypesConfigured,
|
||||
bool hugeMemory, bool v128Configured);
|
||||
DebugEnabled debugEnabled);
|
||||
|
||||
// Compute any remaining compilation parameters.
|
||||
void computeParameters(Decoder& d);
|
||||
@ -116,26 +110,6 @@ struct CompilerEnvironment {
|
||||
MOZ_ASSERT(isComputed());
|
||||
return debug_;
|
||||
}
|
||||
bool gcTypes() const {
|
||||
MOZ_ASSERT(isComputed());
|
||||
return gcTypes_;
|
||||
}
|
||||
bool refTypes() const {
|
||||
MOZ_ASSERT(isComputed());
|
||||
return refTypes_;
|
||||
}
|
||||
bool multiValues() const {
|
||||
MOZ_ASSERT(isComputed());
|
||||
return multiValues_;
|
||||
}
|
||||
bool hugeMemory() const {
|
||||
MOZ_ASSERT(isComputed());
|
||||
return hugeMemory_;
|
||||
}
|
||||
bool v128() const {
|
||||
MOZ_ASSERT(isComputed());
|
||||
return v128_;
|
||||
}
|
||||
};
|
||||
|
||||
// ModuleEnvironment contains all the state necessary to process or render
|
||||
@ -152,8 +126,8 @@ struct CompilerEnvironment {
|
||||
struct ModuleEnvironment {
|
||||
// Constant parameters for the entire compilation:
|
||||
const ModuleKind kind;
|
||||
const Shareable sharedMemoryEnabled;
|
||||
CompilerEnvironment* const compilerEnv;
|
||||
const FeatureArgs features;
|
||||
|
||||
// Module fields decoded from the module environment (or initialized while
|
||||
// validating an asm.js module) and immutable during compilation:
|
||||
@ -183,11 +157,11 @@ struct ModuleEnvironment {
|
||||
NameVector funcNames;
|
||||
|
||||
explicit ModuleEnvironment(CompilerEnvironment* compilerEnv,
|
||||
Shareable sharedMemoryEnabled,
|
||||
FeatureArgs features,
|
||||
ModuleKind kind = ModuleKind::Wasm)
|
||||
: kind(kind),
|
||||
sharedMemoryEnabled(sharedMemoryEnabled),
|
||||
compilerEnv(compilerEnv),
|
||||
features(features),
|
||||
memoryUsage(MemoryUsage::None),
|
||||
minMemoryLength(0),
|
||||
numStructTypes(0) {}
|
||||
@ -205,21 +179,21 @@ struct ModuleEnvironment {
|
||||
size_t numFuncDefs() const {
|
||||
return funcTypes.length() - funcImportGlobalDataOffsets.length();
|
||||
}
|
||||
bool gcTypesEnabled() const { return compilerEnv->gcTypes(); }
|
||||
bool refTypesEnabled() const { return compilerEnv->refTypes(); }
|
||||
bool multiValuesEnabled() const { return compilerEnv->multiValues(); }
|
||||
bool v128Enabled() const { return compilerEnv->v128(); }
|
||||
Shareable sharedMemoryEnabled() const { return features.sharedMemory; }
|
||||
bool refTypesEnabled() const { return features.refTypes; }
|
||||
bool functionReferencesEnabled() const { return features.functionReferences; }
|
||||
bool gcTypesEnabled() const { return features.gcTypes; }
|
||||
bool multiValueEnabled() const { return features.multiValue; }
|
||||
bool v128Enabled() const { return features.v128; }
|
||||
bool hugeMemoryEnabled() const { return !isAsmJS() && features.hugeMemory; }
|
||||
bool usesMemory() const { return memoryUsage != MemoryUsage::None; }
|
||||
bool usesSharedMemory() const { return memoryUsage == MemoryUsage::Shared; }
|
||||
bool isAsmJS() const { return kind == ModuleKind::AsmJS; }
|
||||
bool debugEnabled() const {
|
||||
return compilerEnv->debug() == DebugEnabled::True;
|
||||
}
|
||||
bool hugeMemoryEnabled() const {
|
||||
return !isAsmJS() && compilerEnv->hugeMemory();
|
||||
}
|
||||
uint32_t funcMaxResults() const {
|
||||
return multiValuesEnabled() ? MaxResults : 1;
|
||||
return multiValueEnabled() ? MaxResults : 1;
|
||||
}
|
||||
bool funcIsImport(uint32_t funcIndex) const {
|
||||
return funcIndex < funcImportGlobalDataOffsets.length();
|
||||
|
@ -954,6 +954,10 @@ static void ReloadPrefsCallback(const char* pref, void* aXpccx) {
|
||||
#endif
|
||||
bool useWasmReftypes =
|
||||
Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_reftypes");
|
||||
#ifdef ENABLE_WASM_FUNCTION_REFERENCES
|
||||
bool useWasmFunctionReferences =
|
||||
Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_function_references");
|
||||
#endif
|
||||
#ifdef ENABLE_WASM_GC
|
||||
bool useWasmGc = Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_gc");
|
||||
#endif
|
||||
@ -1033,6 +1037,9 @@ static void ReloadPrefsCallback(const char* pref, void* aXpccx) {
|
||||
#ifdef ENABLE_WASM_CRANELIFT
|
||||
.setWasmCranelift(useWasmCranelift)
|
||||
#endif
|
||||
#ifdef ENABLE_WASM_FUNCTION_REFERENCES
|
||||
.setWasmFunctionReferences(useWasmFunctionReferences)
|
||||
#endif
|
||||
#ifdef ENABLE_WASM_GC
|
||||
.setWasmGc(useWasmGc)
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user