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:
Ryan Hunt 2020-09-28 19:18:48 +00:00
parent 5f7ab67e9c
commit 33b1e95109
18 changed files with 193 additions and 140 deletions

View File

@ -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))

View File

@ -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)

View File

@ -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;

View File

@ -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."),

View File

@ -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;

View File

@ -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") ||

View File

@ -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

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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();

View File

@ -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