Bug 1508561 - Disentangle support for reftypes and gc. r=jseward

This does the following:

- It introduces a controlling ifdef ENABLE_WASM_REFTYPES that enables
  exactly those features that are in the reftypes proposal, excluding
  those in the gc proposal.  Any remaining features (namely, ref.eq,
  (ref T) types, struct types) are still under ENABLE_WASM_GC control.
  ENABLE_WASM_GC requires ENABLE_WASM_REFTYPES and this is checked.

- It introduces a new TestingFunctions predicate, wasmReftypesEnabled,
  that distinguishes reftype-proposal support from gc-proposal
  support.  We keep wasmGcEnabled to test for gc-proposal support.

- It segregates test cases so that gc-proposal relevant tests are in
  their own files, and tests relevant to the reftypes-proposal are now
  guarded by wasmReftypesEnabled.

- It renames the predicate HasGcSupport() as HasReftypesSupport(),
  since that is what the predicate tests for.

- It has a drive-by fix for the DEBUG-only function wasm::Classify()
  to properly put ref.null and ref.is_null under ifdef control.

Reftypes will soon be enabled unconditionally in Nightly (once we can
trace pointers from Ion frames) while gc-types will remain conditional
until Ion supports all the new instructions for struct types.  Therefore:

- The command line switch and about:config option are still called
  --wasm-gc and j.o.wasm_gc, respectively, which is fine since they will
  fairly soon control only gc-proposal features.

- Internal names still use "Gc" rather than "Reftypes", eg,
  HasGcTypes, wasmGc_, and so on.  This is most appropriate since it
  reduces the scope of the patch and these names will pertain mainly
  to the gc feature in the future.

--HG--
extra : rebase_source : 51cf3bfe67da594e89195472e4ce1ccfa36c146d
This commit is contained in:
Lars T Hansen 2018-12-18 17:26:32 +01:00
Родитель 3311ddda7f
Коммит d66fb136aa
44 изменённых файлов: 235 добавлений и 156 удалений

Просмотреть файл

@ -286,7 +286,7 @@ void LoadContextOptions(const char* aPrefName, void* /* aClosure */) {
.setWasmForceCranelift(
GetWorkerPref<bool>(NS_LITERAL_CSTRING("wasm_cranelift")))
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
.setWasmGc(GetWorkerPref<bool>(NS_LITERAL_CSTRING("wasm_gc")))
#endif
.setWasmVerbose(GetWorkerPref<bool>(NS_LITERAL_CSTRING("wasm_verbose")))

Просмотреть файл

@ -100,4 +100,5 @@ if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
CXXFLAGS += ['-Wno-error=shadow']
if CONFIG['NIGHTLY_BUILD']:
DEFINES['ENABLE_WASM_REFTYPES'] = True
DEFINES['ENABLE_WASM_GC'] = True

Просмотреть файл

@ -670,9 +670,19 @@ static bool WasmBulkMemSupported(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
static bool WasmReftypesEnabled(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().setBoolean(wasm::HasReftypesSupport(cx));
return true;
}
static bool WasmGcEnabled(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().setBoolean(wasm::HasGcSupport(cx));
#ifdef ENABLE_WASM_GC
args.rval().setBoolean(wasm::HasReftypesSupport(cx));
#else
args.rval().setBoolean(false);
#endif
return true;
}
@ -681,7 +691,7 @@ static bool WasmGeneralizedTables(JSContext* cx, unsigned argc, Value* vp) {
#ifdef ENABLE_WASM_GENERALIZED_TABLES
// Generalized tables depend on anyref, though not currently on (ref T)
// types nor on structures or other GC-proposal features.
bool isSupported = wasm::HasGcSupport(cx);
bool isSupported = wasm::HasReftypesSupport(cx);
#else
bool isSupported = false;
#endif
@ -5957,9 +5967,13 @@ gc::ZealModeHelpText),
" Returns a boolean indicating whether a given module has finished compiled code for tier2. \n"
"This will return true early if compilation isn't two-tiered. "),
JS_FN_HELP("wasmReftypesEnabled", WasmReftypesEnabled, 1, 0,
"wasmReftypesEnabled(bool)",
" Returns a boolean indicating whether the WebAssembly reftypes proposal is enabled."),
JS_FN_HELP("wasmGcEnabled", WasmGcEnabled, 1, 0,
"wasmGcEnabled(bool)",
" Returns a boolean indicating whether the WebAssembly GC support is enabled."),
" Returns a boolean indicating whether the WebAssembly GC types proposal is enabled."),
JS_FN_HELP("wasmGeneralizedTables", WasmGeneralizedTables, 1, 0,
"wasmGeneralizedTables(bool)",

Просмотреть файл

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
// Moving a JS value through a wasm anyref is a pair of boxing/unboxing
// conversions that leaves the value unchanged. There are many cases,

Просмотреть файл

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled() || typeof WebAssembly.Global !== 'function'
// |jit-test| skip-if: !wasmReftypesEnabled() || typeof WebAssembly.Global !== 'function'
// Dummy object.
function Baguette(calories) {

Просмотреть файл

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
const { startProfiling, endProfiling, assertEqPreciseStacks, isSingleStepProfilingEnabled } = WasmHelpers;

Просмотреть файл

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
// Do not run the test if we're jit-compiling JS, since it's the wasm frames
// we're interested in and eager JS compilation can upset the test.

Просмотреть файл

@ -0,0 +1,22 @@
// |jit-test| skip-if: !wasmGcEnabled()
//
// ref.eq is part of the gc feature, not the reftypes feature.
let { exports } = wasmEvalText(`(module
(gc_feature_opt_in 2)
(func (export "ref_eq") (param $a anyref) (param $b anyref) (result i32)
(ref.eq (get_local $a) (get_local $b)))
(func (export "ref_eq_for_control") (param $a anyref) (param $b anyref) (result f64)
(if f64 (ref.eq (get_local $a) (get_local $b))
(f64.const 5.0)
(f64.const 3.0))))`);
assertEq(exports.ref_eq(null, null), 1);
assertEq(exports.ref_eq(null, {}), 0);
assertEq(exports.ref_eq(this, this), 1);
assertEq(exports.ref_eq_for_control(null, null), 5);
assertEq(exports.ref_eq_for_control(null, {}), 3);
assertEq(exports.ref_eq_for_control(this, this), 5);

Просмотреть файл

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
gczeal(14, 1);
let { exports } = wasmEvalText(`(module

Просмотреть файл

@ -1,5 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// Ensure that if gc types aren't enabled, test cases properly fail.
// |jit-test| skip-if: !wasmReftypesEnabled()
// Dummy constructor.
function Baguette(calories) {
@ -90,25 +89,11 @@ let { exports } = wasmEvalText(`(module
get_local 0
ref.is_null
)
(func (export "ref_eq") (param $a anyref) (param $b anyref) (result i32)
(ref.eq (get_local $a) (get_local $b)))
(func (export "ref_eq_for_control") (param $a anyref) (param $b anyref) (result f64)
(if f64 (ref.eq (get_local $a) (get_local $b))
(f64.const 5.0)
(f64.const 3.0)))
)`);
assertEq(exports.is_null(), 1);
assertEq(exports.is_null_spill(), 1);
assertEq(exports.is_null_local(), 1);
assertEq(exports.ref_eq(null, null), 1);
assertEq(exports.ref_eq(null, {}), 0);
assertEq(exports.ref_eq(this, this), 1);
assertEq(exports.ref_eq_for_control(null, null), 5);
assertEq(exports.ref_eq_for_control(null, {}), 3);
assertEq(exports.ref_eq_for_control(this, this), 5);
// Anyref param and result in wasm functions.

Просмотреть файл

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
load(libdir + "wasm-binary.js");

Просмотреть файл

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled() || !wasmDebuggingIsSupported()
// |jit-test| skip-if: !wasmReftypesEnabled() || !wasmDebuggingIsSupported()
(function() {
let g = newGlobal();

Просмотреть файл

@ -0,0 +1,4 @@
// |jit-test| skip-if: wasmGcEnabled()
assertErrorMessage(() => wasmEvalText(`(module (func (param (ref 0)) (unreachable)))`),
WebAssembly.CompileError, /reference types not enabled/);

Просмотреть файл

@ -1,4 +1,4 @@
// |jit-test| skip-if: wasmGcEnabled()
// |jit-test| skip-if: wasmReftypesEnabled()
const { CompileError, validate } = WebAssembly;

Просмотреть файл

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
enableShellAllocationMetadataBuilder();
gczeal(9, 1);

Просмотреть файл

@ -0,0 +1,41 @@
// |jit-test| skip-if: !wasmGcEnabled()
//
// Struct types are only available if we opt in, so test that.
let CURRENT_VERSION = 2;
new WebAssembly.Module(wasmTextToBinary(
`(module
(gc_feature_opt_in ${CURRENT_VERSION})
(type (struct (field i32))))`));
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(type (struct (field i32))))`)),
WebAssembly.CompileError,
/Structure types not enabled/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.new 0)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.get 0 0)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.set 0 0)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.narrow anyref anyref)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);

Просмотреть файл

@ -1,4 +1,6 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
//
// Also see gc-feature-opt-in-struct.js for tests that use the struct feature.
// Version numbers
@ -44,19 +46,6 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
WebAssembly.CompileError,
/GC feature version is unknown/);
// Struct types are only available if we opt in.
new WebAssembly.Module(wasmTextToBinary(
`(module
(gc_feature_opt_in ${CURRENT_VERSION})
(type (struct (field i32))))`));
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(type (struct (field i32))))`)),
WebAssembly.CompileError,
/Structure types not enabled/);
// Parameters of ref type are only available if we opt in.
new WebAssembly.Module(wasmTextToBinary(
@ -137,26 +126,3 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.new 0)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.get 0 0)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.set 0 0)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.narrow anyref anyref)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);

Просмотреть файл

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
// Attempt to test intercalls from ion to baseline and back.
//

Просмотреть файл

@ -1,8 +1,4 @@
if (!wasmGcEnabled()) {
assertErrorMessage(() => wasmEvalText(`(module (func (param (ref 0)) (unreachable)))`),
WebAssembly.CompileError, /reference types not enabled/);
quit(0);
}
// |jit-test| skip-if: !wasmGcEnabled()
// Parsing and resolving.

Просмотреть файл

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
// Tests wasm frame tracing. Only tests for direct and indirect call chains
// in wasm that lead to JS allocation. Does not test any timeout or interrupt

Просмотреть файл

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
// Tests wasm frame tracing in the presence of interrupt handlers that perform
// allocation. The structure is

Просмотреть файл

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
// Generates a bunch of numbers-on-the-heap, and tries to ensure that they are
// held live -- at least for a short while -- only by references from the wasm

Просмотреть файл

@ -0,0 +1,50 @@
// |jit-test| skip-if: !wasmGeneralizedTables() || !wasmGcEnabled()
// table.set in bounds with i32 x anyref - works, no value generated
// table.set with (ref T) - works
// table.set with null - works
// table.set out of bounds - fails
{
let ins = wasmEvalText(
`(module
(gc_feature_opt_in 2)
(table (export "t") 10 anyref)
(type $dummy (struct (field i32)))
(func (export "set_anyref") (param i32) (param anyref)
(table.set (get_local 0) (get_local 1)))
(func (export "set_null") (param i32)
(table.set (get_local 0) (ref.null)))
(func (export "set_ref") (param i32) (param anyref)
(table.set (get_local 0) (struct.narrow anyref (ref $dummy) (get_local 1))))
(func (export "make_struct") (result anyref)
(struct.new $dummy (i32.const 37))))`);
let x = {};
ins.exports.set_anyref(3, x);
assertEq(ins.exports.t.get(3), x);
ins.exports.set_null(3);
assertEq(ins.exports.t.get(3), null);
let dummy = ins.exports.make_struct();
ins.exports.set_ref(5, dummy);
assertEq(ins.exports.t.get(5), dummy);
assertErrorMessage(() => ins.exports.set_anyref(10, x), RangeError, /index out of bounds/);
assertErrorMessage(() => ins.exports.set_anyref(-1, x), RangeError, /index out of bounds/);
}
// table.grow on table of anyref with non-null ref value
{
let ins = wasmEvalText(
`(module
(gc_feature_opt_in 2)
(type $S (struct (field i32) (field f64)))
(table (export "t") 2 anyref)
(func (export "f") (result i32)
(table.grow (i32.const 1) (struct.new $S (i32.const 0) (f64.const 3.14)))))`);
assertEq(ins.exports.t.length, 2);
assertEq(ins.exports.f(), 2);
assertEq(ins.exports.t.length, 3);
assertEq(typeof ins.exports.t.get(2), "object");
}

Просмотреть файл

@ -223,7 +223,6 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
/table index out of range for table.get/);
// table.set in bounds with i32 x anyref - works, no value generated
// table.set with (ref T) - works
// table.set with null - works
// table.set out of bounds - fails
@ -232,23 +231,15 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(gc_feature_opt_in 2)
(table (export "t") 10 anyref)
(type $dummy (struct (field i32)))
(func (export "set_anyref") (param i32) (param anyref)
(table.set (get_local 0) (get_local 1)))
(func (export "set_null") (param i32)
(table.set (get_local 0) (ref.null)))
(func (export "set_ref") (param i32) (param anyref)
(table.set (get_local 0) (struct.narrow anyref (ref $dummy) (get_local 1))))
(func (export "make_struct") (result anyref)
(struct.new $dummy (i32.const 37))))`);
(table.set (get_local 0) (ref.null))))`);
let x = {};
ins.exports.set_anyref(3, x);
assertEq(ins.exports.t.get(3), x);
ins.exports.set_null(3);
assertEq(ins.exports.t.get(3), null);
let dummy = ins.exports.make_struct();
ins.exports.set_ref(5, dummy);
assertEq(ins.exports.t.get(5), dummy);
assertErrorMessage(() => ins.exports.set_anyref(10, x), RangeError, /index out of bounds/);
assertErrorMessage(() => ins.exports.set_anyref(-1, x), RangeError, /index out of bounds/);
@ -378,22 +369,6 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
WebAssembly.CompileError,
/table index out of range for table.grow/);
// table.grow on table of anyref with non-null ref value
{
let ins = wasmEvalText(
`(module
(gc_feature_opt_in 2)
(type $S (struct (field i32) (field f64)))
(table (export "t") 2 anyref)
(func (export "f") (result i32)
(table.grow (i32.const 1) (struct.new $S (i32.const 0) (f64.const 3.14)))))`);
assertEq(ins.exports.t.length, 2);
assertEq(ins.exports.f(), 2);
assertEq(ins.exports.t.length, 3);
assertEq(typeof ins.exports.t.get(2), "object");
}
// table.size on table of anyref
for (let visibility of ['', '(export "t")', '(import "m" "t")']) {

Просмотреть файл

@ -211,7 +211,7 @@ JitCompileOptions::JitCompileOptions()
: cloneSingletons_(false),
profilerSlowAssertionsEnabled_(false),
offThreadCompilationAvailable_(false)
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
,
wasmGcEnabled_(false)
#endif
@ -224,7 +224,7 @@ JitCompileOptions::JitCompileOptions(JSContext* cx) {
cx->runtime()->geckoProfiler().enabled() &&
cx->runtime()->geckoProfiler().slowAssertionsEnabled();
offThreadCompilationAvailable_ = OffThreadCompilationAvailable(cx);
#ifdef ENABLE_WASM_GC
wasmGcEnabled_ = wasm::HasGcSupport(cx);
#ifdef ENABLE_WASM_REFTYPES
wasmGcEnabled_ = wasm::HasReftypesSupport(cx);
#endif
}

Просмотреть файл

@ -130,7 +130,7 @@ class JitCompileOptions {
return offThreadCompilationAvailable_;
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
bool wasmGcEnabled() const { return wasmGcEnabled_; }
#endif
@ -138,7 +138,7 @@ class JitCompileOptions {
bool cloneSingletons_;
bool profilerSlowAssertionsEnabled_;
bool offThreadCompilationAvailable_;
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
bool wasmGcEnabled_;
#endif
};

Просмотреть файл

@ -6,10 +6,20 @@
# Nightly-only features
if CONFIG['NIGHTLY_BUILD']:
# TypedObject
DEFINES['ENABLE_BINARYDATA'] = True
# The evolving bulk-copy proposal - mem.fill, mem.copy,
# table.copy, etc
DEFINES['ENABLE_WASM_BULKMEM_OPS'] = True
DEFINES['ENABLE_WASM_GC'] = True
# Support the evolving reftypes proposal - anyref, funcref, null,
# and a few other things
DEFINES['ENABLE_WASM_REFTYPES'] = True
# Support table of anyref, multiple tables - requires reftypes
DEFINES['ENABLE_WASM_GENERALIZED_TABLES'] = True
# Support the evolving gc types proposal (struct types, etc)
DEFINES['ENABLE_WASM_GC'] = True
# Prevent (ref T) types from being exposed to JS content so that
# wasm need do no typechecking at the JS/wasm boundary
DEFINES['WASM_PRIVATE_REFTYPES'] = True
# Some huge-mapping optimization instead of bounds checks on supported

Просмотреть файл

@ -398,7 +398,7 @@ class JS_PUBLIC_API ContextOptions {
#ifdef ENABLE_WASM_CRANELIFT
wasmForceCranelift_(false),
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
wasmGc_(false),
#endif
testWasmAwaitTier2_(false),
@ -489,7 +489,7 @@ class JS_PUBLIC_API ContextOptions {
return *this;
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
bool wasmGc() const { return wasmGc_; }
ContextOptions& setWasmGc(bool flag) {
wasmGc_ = flag;
@ -580,7 +580,7 @@ class JS_PUBLIC_API ContextOptions {
setWasm(false);
setWasmBaseline(false);
setWasmIon(false);
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
setWasmGc(false);
#endif
setNativeRegExp(false);
@ -597,7 +597,7 @@ class JS_PUBLIC_API ContextOptions {
#ifdef ENABLE_WASM_CRANELIFT
bool wasmForceCranelift_ : 1;
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
bool wasmGc_ : 1;
#endif
bool testWasmAwaitTier2_ : 1;

Просмотреть файл

@ -494,7 +494,7 @@ static bool enableWasmIon = false;
#ifdef ENABLE_WASM_CRANELIFT
static bool wasmForceCranelift = false;
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
static bool enableWasmGc = false;
#endif
static bool enableWasmVerbose = false;
@ -10173,7 +10173,7 @@ static bool SetContextOptions(JSContext* cx, const OptionParser& op) {
#ifdef ENABLE_WASM_CRANELIFT
wasmForceCranelift = op.getBoolOption("wasm-force-cranelift");
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
enableWasmGc = op.getBoolOption("wasm-gc");
#ifdef ENABLE_WASM_CRANELIFT
if (enableWasmGc && wasmForceCranelift) {
@ -10202,7 +10202,7 @@ static bool SetContextOptions(JSContext* cx, const OptionParser& op) {
#ifdef ENABLE_WASM_CRANELIFT
.setWasmForceCranelift(wasmForceCranelift)
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
.setWasmGc(enableWasmGc)
#endif
.setWasmVerbose(enableWasmVerbose)
@ -10529,7 +10529,7 @@ static void SetWorkerContextOptions(JSContext* cx) {
#ifdef ENABLE_WASM_CRANELIFT
.setWasmForceCranelift(wasmForceCranelift)
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
.setWasmGc(enableWasmGc)
#endif
.setWasmVerbose(enableWasmVerbose)
@ -10932,7 +10932,7 @@ int main(int argc, char** argv, char** envp) {
!op.addBoolOption('\0', "test-wasm-await-tier2",
"Forcibly activate tiering and block "
"instantiation on completion of tier2")
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
|| !op.addBoolOption('\0', "wasm-gc", "Enable wasm GC features")
#else
|| !op.addBoolOption('\0', "wasm-gc", "No-op")

Просмотреть файл

@ -1292,7 +1292,7 @@ class AstModule : public AstNode {
NameVector funcImportNames_;
AstTableVector tables_;
AstMemoryVector memories_;
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
uint32_t gcFeatureOptIn_;
#endif
ExportVector exports_;
@ -1313,7 +1313,7 @@ class AstModule : public AstNode {
funcImportNames_(lifo),
tables_(lifo),
memories_(lifo),
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
gcFeatureOptIn_(0),
#endif
exports_(lifo),
@ -1328,7 +1328,7 @@ class AstModule : public AstNode {
}
bool hasMemory() const { return !!memories_.length(); }
const AstMemoryVector& memories() const { return memories_; }
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
bool addGcFeatureOptIn(uint32_t version) {
gcFeatureOptIn_ = version;
return true;

Просмотреть файл

@ -11454,6 +11454,8 @@ bool BaseCompiler::emitBody() {
}
CHECK_NEXT(
emitComparison(emitCompareRef, ValType::AnyRef, Assembler::Equal));
#endif
#ifdef ENABLE_WASM_REFTYPES
case uint16_t(Op::RefNull):
if (env_.gcTypesEnabled() == HasGcTypes::False) {
return iter_.unrecognizedOpcode(&op);

Просмотреть файл

@ -74,11 +74,7 @@ uint32_t wasm::ObservedCPUFeatures() {
CompileArgs::CompileArgs(JSContext* cx, ScriptedCaller&& scriptedCaller)
: scriptedCaller(std::move(scriptedCaller)) {
#ifdef ENABLE_WASM_GC
bool gcEnabled = HasGcSupport(cx);
#else
bool gcEnabled = false;
#endif
bool gcEnabled = HasReftypesSupport(cx);
baselineEnabled = cx->options().wasmBaseline();
ionEnabled = cx->options().wasmIon();

Просмотреть файл

@ -3650,6 +3650,8 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
#ifdef ENABLE_WASM_GC
case uint16_t(Op::RefEq):
#endif
#ifdef ENABLE_WASM_REFTYPES
case uint16_t(Op::RefNull):
case uint16_t(Op::RefIsNull):
// Not yet supported

Просмотреть файл

@ -57,13 +57,13 @@ using mozilla::RangedPtr;
extern mozilla::Atomic<bool> fuzzingSafe;
bool wasm::HasGcSupport(JSContext* cx) {
bool wasm::HasReftypesSupport(JSContext* cx) {
#ifdef ENABLE_WASM_CRANELIFT
if (cx->options().wasmForceCranelift()) {
return false;
}
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
return cx->options().wasmGc() && cx->options().wasmBaseline();
#else
return false;
@ -2060,7 +2060,7 @@ bool WasmTableObject::isNewborn() const {
tableKind = TableKind::AnyFunction;
#ifdef ENABLE_WASM_GENERALIZED_TABLES
} else if (StringEqualsAscii(elementLinearStr, "anyref")) {
if (!HasGcSupport(cx)) {
if (!HasReftypesSupport(cx)) {
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
JSMSG_WASM_BAD_ELEMENT);
return false;
@ -2472,8 +2472,8 @@ const Class WasmGlobalObject::class_ = {
globalType = ValType::F32;
} else if (StringEqualsAscii(typeLinearStr, "f64")) {
globalType = ValType::F64;
#ifdef ENABLE_WASM_GC
} else if (HasGcSupport(cx) &&
#ifdef ENABLE_WASM_REFTYPES
} else if (HasReftypesSupport(cx) &&
StringEqualsAscii(typeLinearStr, "anyref")) {
globalType = ValType::AnyRef;
#endif

Просмотреть файл

@ -56,7 +56,7 @@ bool HasCachingSupport(JSContext* cx);
// Returns true if WebAssembly as configured by compile-time flags and run-time
// options can support reference types and stack walking.
bool HasGcSupport(JSContext* cx);
bool HasReftypesSupport(JSContext* cx);
// Compiles the given binary wasm module given the ArrayBufferObject
// and links the module's imports with the given import object.

Просмотреть файл

@ -23,15 +23,24 @@ using namespace js::jit;
using namespace js::wasm;
#ifdef ENABLE_WASM_GENERALIZED_TABLES
// Actually we depend only on the reftypes proposal; this guard will change once
// reftypes and GC are pried apart properly.
#ifndef ENABLE_WASM_GC
#error "Generalized tables require the GC feature"
#ifndef ENABLE_WASM_REFTYPES
#error "Generalized tables require the reftypes feature"
#endif
#endif
#ifdef ENABLE_WASM_GC
#ifndef ENABLE_WASM_REFTYPES
#error "GC types require the reftypes feature"
#endif
#endif
#ifdef DEBUG
#ifdef ENABLE_WASM_REFTYPES
#define WASM_REF_OP(code) return code
#else
#define WASM_REF_OP(code) break
#endif
#ifdef ENABLE_WASM_GC
#define WASM_GC_OP(code) return code
#else
@ -172,7 +181,6 @@ OpKind wasm::Classify(OpBytes op) {
case Op::F64Le:
case Op::F64Gt:
case Op::F64Ge:
case Op::RefEq:
return OpKind::Comparison;
case Op::I32Eqz:
case Op::I32WrapI64:
@ -201,7 +209,6 @@ OpKind wasm::Classify(OpBytes op) {
case Op::F64ConvertUI64:
case Op::F64ReinterpretI64:
case Op::F64PromoteF32:
case Op::RefIsNull:
case Op::I32Extend8S:
case Op::I32Extend16S:
case Op::I64Extend8S:
@ -264,7 +271,11 @@ OpKind wasm::Classify(OpBytes op) {
case Op::GrowMemory:
return OpKind::GrowMemory;
case Op::RefNull:
WASM_GC_OP(OpKind::RefNull);
WASM_REF_OP(OpKind::RefNull);
case Op::RefIsNull:
WASM_REF_OP(OpKind::Conversion);
case Op::RefEq:
WASM_GC_OP(OpKind::Comparison);
case Op::MiscPrefix: {
switch (MiscOp(op.b1)) {
case MiscOp::Limit:

Просмотреть файл

@ -222,7 +222,7 @@ static const unsigned NonVolatileRegsPushSize =
NonVolatileRegs.fpus().getPushSizeInBytes();
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
static const unsigned NumExtraPushed = 2; // tls and argv
#else
static const unsigned NumExtraPushed = 1; // argv
@ -346,7 +346,7 @@ static bool GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe,
WasmTlsReg);
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
WasmPush(masm, WasmTlsReg);
#endif
@ -403,7 +403,7 @@ static bool GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe,
// Recover the 'argv' pointer which was saved before aligning the stack.
WasmPop(masm, argv);
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
WasmPop(masm, WasmTlsReg);
#endif

Просмотреть файл

@ -88,7 +88,7 @@ class WasmToken {
Field,
Float,
Func,
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
GcFeatureOptIn,
#endif
GetGlobal,
@ -365,7 +365,7 @@ class WasmToken {
case Field:
case Float:
case Func:
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
case GcFeatureOptIn:
#endif
case Global:
@ -1308,7 +1308,7 @@ WasmToken WasmTokenStream::next() {
break;
case 'g':
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
if (consume(u"gc_feature_opt_in")) {
return WasmToken(WasmToken::GcFeatureOptIn, begin, cur_);
}
@ -4532,7 +4532,7 @@ static bool ParseMemory(WasmParseContext& c, AstModule* module) {
return module->addMemory(name, memory);
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
// Custom section for experimental work. The size of this section should always
// be 1 byte, and that byte is a nonzero varint7 carrying the version number
// being opted into.
@ -5076,7 +5076,7 @@ static AstModule* ParseModule(const char16_t* text, uintptr_t stackLimit,
}
break;
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
case WasmToken::GcFeatureOptIn: {
if (!ParseGcFeatureOptIn(c, module)) {
return nullptr;
@ -6560,7 +6560,7 @@ static bool EncodeExpr(Encoder& e, AstExpr& expr) {
/*****************************************************************************/
// wasm AST binary serialization
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
static bool EncodeGcFeatureOptInSection(Encoder& e, AstModule& module) {
uint32_t optInVersion = module.gcFeatureOptIn();
if (!optInVersion) {
@ -7158,7 +7158,7 @@ static bool EncodeModule(AstModule& module, Uint32Vector* offsets,
return false;
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
if (!EncodeGcFeatureOptInSection(e, module)) {
return false;
}

Просмотреть файл

@ -981,6 +981,8 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
CHECK(iter.readComparison(ValType::AnyRef, &nothing, &nothing));
break;
}
#endif
#ifdef ENABLE_WASM_REFTYPES
case uint16_t(Op::RefNull): {
if (env.gcTypesEnabled() == HasGcTypes::False) {
return iter.unrecognizedOpcode(&op);
@ -1414,7 +1416,7 @@ static bool DecodeStructType(Decoder& d, ModuleEnvironment* env,
return true;
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
static bool DecodeGCFeatureOptInSection(Decoder& d, ModuleEnvironment* env) {
MaybeSectionRange range;
if (!d.startSection(SectionId::GcFeatureOptIn, env, &range, "type")) {
@ -2416,7 +2418,7 @@ bool wasm::DecodeModuleEnvironment(Decoder& d, ModuleEnvironment* env) {
return false;
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
if (!DecodeGCFeatureOptInSection(d, env)) {
return false;
}
@ -2790,9 +2792,9 @@ bool wasm::Validate(JSContext* cx, const ShareableBytes& bytecode,
UniqueChars* error) {
Decoder d(bytecode.bytes, 0, error);
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
HasGcTypes gcTypesConfigured =
HasGcSupport(cx) ? HasGcTypes::True : HasGcTypes::False;
HasReftypesSupport(cx) ? HasGcTypes::True : HasGcTypes::False;
#else
HasGcTypes gcTypesConfigured = HasGcTypes::False;
#endif

Просмотреть файл

@ -144,7 +144,7 @@ struct ModuleEnvironment {
// Module fields decoded from the module environment (or initialized while
// validating an asm.js module) and immutable during compilation:
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
// `gcFeatureOptIn` reflects the presence in a module of a GcFeatureOptIn
// section. This variable will be removed eventually, allowing it to be
// replaced everywhere by the value HasGcTypes::True.
@ -185,7 +185,7 @@ struct ModuleEnvironment {
sharedMemoryEnabled(sharedMemoryEnabled),
gcTypesConfigured(gcTypesConfigured),
compilerEnv(compilerEnv),
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
gcFeatureOptIn(HasGcTypes::False),
#endif
memoryUsage(MemoryUsage::None),

Просмотреть файл

@ -774,7 +774,7 @@ static void ReloadPrefsCallback(const char* pref, XPCJSContext* xpccx) {
bool useWasmCranelift =
Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_cranelift");
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
bool useWasmGc = Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_gc");
#endif
bool useWasmVerbose = Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_verbose");
@ -867,7 +867,7 @@ static void ReloadPrefsCallback(const char* pref, XPCJSContext* xpccx) {
#ifdef ENABLE_WASM_CRANELIFT
.setWasmForceCranelift(useWasmCranelift)
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
.setWasmGc(useWasmGc)
#endif
.setWasmVerbose(useWasmVerbose)

Просмотреть файл

@ -64,4 +64,5 @@ if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
CXXFLAGS += ['-Wno-shadow', '-Werror=format']
if CONFIG['NIGHTLY_BUILD']:
DEFINES['ENABLE_WASM_REFTYPES'] = True
DEFINES['ENABLE_WASM_GC'] = True

Просмотреть файл

@ -1467,7 +1467,7 @@ pref("javascript.options.wasm_baselinejit", true);
#ifdef ENABLE_WASM_CRANELIFT
pref("javascript.options.wasm_cranelift", false);
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
pref("javascript.options.wasm_gc", false);
#endif
pref("javascript.options.native_regexp", true);

Просмотреть файл

@ -46,6 +46,7 @@ if CONFIG['MOZ_ENABLE_WEBRENDER']:
DEFINES['MOZ_ENABLE_WEBRENDER'] = True
if CONFIG['NIGHTLY_BUILD']:
DEFINES['ENABLE_WASM_REFTYPES'] = True
DEFINES['ENABLE_WASM_GC'] = True
FINAL_TARGET_PP_FILES += [