Bug 1505774 - Update test cases for NullRef. r=luke
authorLars T Hansen <lhansen@mozilla.com>
Fri, 16 Nov 2018 13:45:22 +0100
changeset 507188 f03c9e85b401ed8c488f5e98f90e50451c1cb1cb
parent 507187 45b378c260d9308b6b067e42da3412961d431128
child 507189 5219f57277c4b6b76b61d435227bd666afee59ea
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1505774
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1505774 - Update test cases for NullRef. r=luke Two major changes: - ref.null no longer carries a type - because the encoding is backwards-incompatible, all test cases must gc_feature_opt_in with version 2 instead of 1
js/src/jit-test/tests/wasm/gc/TypedObject.js
js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js
js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js
js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js
js/src/jit-test/tests/wasm/gc/anyref.js
js/src/jit-test/tests/wasm/gc/binary.js
js/src/jit-test/tests/wasm/gc/debugger.js
js/src/jit-test/tests/wasm/gc/disabled.js
js/src/jit-test/tests/wasm/gc/gc-feature-opt-in.js
js/src/jit-test/tests/wasm/gc/ion-and-baseline.js
js/src/jit-test/tests/wasm/gc/ref-global.js
js/src/jit-test/tests/wasm/gc/ref-restrict.js
js/src/jit-test/tests/wasm/gc/ref-struct.js
js/src/jit-test/tests/wasm/gc/ref.js
js/src/jit-test/tests/wasm/gc/structs.js
js/src/jit-test/tests/wasm/gc/tables-generalized.js
js/src/jit-test/tests/wasm/gc/tables-multiple.js
js/src/jit-test/tests/wasm/gc/tables-stress.js
--- a/js/src/jit-test/tests/wasm/gc/TypedObject.js
+++ b/js/src/jit-test/tests/wasm/gc/TypedObject.js
@@ -1,15 +1,15 @@
 // |jit-test| skip-if: !wasmGcEnabled()
 
 // We can read the object fields from JS, and write them if they are mutable.
 
 {
     let ins = wasmEvalText(`(module
-                             (gc_feature_opt_in 1)
+                             (gc_feature_opt_in 2)
 
                              (type $p (struct (field f64) (field (mut i32))))
 
                              (func (export "mkp") (result anyref)
                               (struct.new $p (f64.const 1.5) (i32.const 33))))`).exports;
 
     let p = ins.mkp();
     assertEq(p._0, 1.5);
@@ -19,17 +19,17 @@
     p._1 = 44;
     assertEq(p._1, 44);
 }
 
 // Writing an immutable field from JS throws.
 
 {
     let ins = wasmEvalText(`(module
-                             (gc_feature_opt_in 1)
+                             (gc_feature_opt_in 2)
 
                              (type $p (struct (field f64)))
 
                              (func (export "mkp") (result anyref)
                               (struct.new $p (f64.const 1.5))))`).exports;
 
     let p = ins.mkp();
     assertErrorMessage(() => p._0 = 5.7,
@@ -39,28 +39,28 @@
 
 // MVA v1 restriction: structs that expose ref-typed fields should not be
 // constructible from JS.
 //
 // However, if the fields are anyref the structs can be constructed from JS.
 
 {
     let ins = wasmEvalText(`(module
-                             (gc_feature_opt_in 1)
+                             (gc_feature_opt_in 2)
 
                              (type $q (struct (field (mut f64))))
                              (type $p (struct (field (mut (ref $q)))))
 
                              (type $r (struct (field (mut anyref))))
 
                              (func (export "mkp") (result anyref)
-                              (struct.new $p (ref.null (ref $q))))
+                              (struct.new $p (ref.null)))
 
                              (func (export "mkr") (result anyref)
-                              (struct.new $r (ref.null anyref))))`).exports;
+                              (struct.new $r (ref.null))))`).exports;
 
     assertEq(typeof ins.mkp().constructor, "function");
     assertErrorMessage(() => new (ins.mkp().constructor)({_0:null}),
                        TypeError,
                        /not constructible/);
 
     assertEq(typeof ins.mkr().constructor, "function");
     let r = new (ins.mkr().constructor)({_0:null});
@@ -69,26 +69,26 @@
 
 // MVA v1 restriction: structs that expose ref-typed fields make those fields
 // immutable from JS even if we're trying to store the correct type.
 //
 // However, anyref fields are mutable from JS.
 
 {
     let ins = wasmEvalText(`(module
-                             (gc_feature_opt_in 1)
+                             (gc_feature_opt_in 2)
 
                              (type $q (struct (field (mut f64))))
                              (type $p (struct (field (mut (ref $q))) (field (mut anyref))))
 
                              (func (export "mkq") (result anyref)
                               (struct.new $q (f64.const 1.5)))
 
                              (func (export "mkp") (result anyref)
-                              (struct.new $p (ref.null (ref $q)) (ref.null anyref))))`).exports;
+                              (struct.new $p (ref.null) (ref.null))))`).exports;
     let q = ins.mkq();
     assertEq(typeof q, "object");
     assertEq(q._0, 1.5);
     let p = ins.mkp();
     assertEq(typeof p, "object");
     assertEq(p._0, null);
 
     assertErrorMessage(() => { p._0 = q },
@@ -99,17 +99,17 @@
     assertEq(p._1, q);
 }
 
 // MVA v1 restriction: structs that expose i64 fields make those fields
 // immutable from JS, and the structs are not constructible from JS.
 
 {
     let ins = wasmEvalText(`(module
-                             (gc_feature_opt_in 1)
+                             (gc_feature_opt_in 2)
                              (type $p (struct (field (mut i64))))
                              (func (export "mkp") (result anyref)
                               (struct.new $p (i64.const 0x1234567887654321))))`).exports;
 
     let p = ins.mkp();
     assertEq(typeof p, "object");
     assertEq(p._0_high, 0x12345678)
     assertEq(p._0_low, 0x87654321|0);
@@ -128,17 +128,17 @@
 }
 
 // A consequence of the current mapping of i64 as two i32 fields is that we run
 // a risk of struct.narrow not recognizing the difference.  So check this.
 
 {
     let ins = wasmEvalText(
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
           (type $p (struct (field i64)))
           (type $q (struct (field i32) (field i32)))
           (func $f (param anyref) (result i32)
            (ref.is_null (struct.narrow anyref (ref $q) (get_local 0))))
           (func $g (param anyref) (result i32)
            (ref.is_null (struct.narrow anyref (ref $p) (get_local 0))))
           (func (export "t1") (result i32)
            (call $f (struct.new $p (i64.const 0))))
--- a/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js
+++ b/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js
@@ -5,38 +5,38 @@ const { startProfiling, endProfiling, as
 // Dummy constructor.
 function Baguette(calories) {
     this.calories = calories;
 }
 
 // Ensure the baseline compiler sync's before the postbarrier.
 (function() {
     wasmEvalText(`(module
-        (gc_feature_opt_in 1)
-        (global (mut anyref) (ref.null anyref))
+        (gc_feature_opt_in 2)
+        (global (mut anyref) (ref.null))
         (func (export "f")
             get_global 0
-            ref.null anyref
+            ref.null
             set_global 0
             set_global 0
         )
     )`).exports.f();
 })();
 
 let exportsPlain = wasmEvalText(`(module
-    (gc_feature_opt_in 1)
+    (gc_feature_opt_in 2)
     (global i32 (i32.const 42))
-    (global $g (mut anyref) (ref.null anyref))
+    (global $g (mut anyref) (ref.null))
     (func (export "set") (param anyref) get_local 0 set_global $g)
     (func (export "get") (result anyref) get_global $g)
 )`).exports;
 
 let exportsObj = wasmEvalText(`(module
-    (gc_feature_opt_in 1)
-    (global $g (export "g") (mut anyref) (ref.null anyref))
+    (gc_feature_opt_in 2)
+    (global $g (export "g") (mut anyref) (ref.null))
     (func (export "set") (param anyref) get_local 0 set_global $g)
     (func (export "get") (result anyref) get_global $g)
 )`).exports;
 
 // 7 => Generational GC zeal.
 gczeal(7, 1);
 
 for (var i = 0; i < 100; i++) {
--- a/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js
+++ b/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js
@@ -1,15 +1,15 @@
 // |jit-test| skip-if: !wasmGcEnabled()
 
 const { startProfiling, endProfiling, assertEqPreciseStacks, isSingleStepProfilingEnabled } = WasmHelpers;
 
 let e = wasmEvalText(`(module
-    (gc_feature_opt_in 1)
-    (global $g (mut anyref) (ref.null anyref))
+    (gc_feature_opt_in 2)
+    (global $g (mut anyref) (ref.null))
     (func (export "set") (param anyref) get_local 0 set_global $g)
 )`).exports;
 
 let obj = { field: null };
 
 // GCZeal mode 4 implies that prebarriers are being verified at many
 // locations in the interpreter, during interrupt checks, etc. It can be ultra
 // slow, so disable it with gczeal(0) when it's not strictly needed.
--- a/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js
+++ b/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js
@@ -1,13 +1,13 @@
 // |jit-test| skip-if: !wasmGcEnabled()
 
 gczeal(14, 1);
 let { exports } = wasmEvalText(`(module
-    (gc_feature_opt_in 1)
+    (gc_feature_opt_in 2)
     (global $anyref (import "glob" "anyref") anyref)
     (func (export "get") (result anyref) get_global $anyref)
 )`, {
     glob: {
         anyref: { sentinel: "lol" },
     }
 });
 assertEq(exports.get().sentinel, "lol");
--- a/js/src/jit-test/tests/wasm/gc/anyref.js
+++ b/js/src/jit-test/tests/wasm/gc/anyref.js
@@ -6,88 +6,88 @@ function Baguette(calories) {
     this.calories = calories;
 }
 
 // Type checking.
 
 const { validate, CompileError } = WebAssembly;
 
 assertErrorMessage(() => wasmEvalText(`(module
-    (gc_feature_opt_in 1)
+    (gc_feature_opt_in 2)
     (func (result anyref)
         i32.const 42
     )
 )`), CompileError, mismatchError('i32', 'anyref'));
 
 assertErrorMessage(() => wasmEvalText(`(module
-    (gc_feature_opt_in 1)
+    (gc_feature_opt_in 2)
     (func (result anyref)
         i32.const 0
-        ref.null anyref
+        ref.null
         i32.const 42
         select
     )
 )`), CompileError, /select operand types/);
 
 assertErrorMessage(() => wasmEvalText(`(module
-    (gc_feature_opt_in 1)
+    (gc_feature_opt_in 2)
     (func (result i32)
-        ref.null anyref
+        ref.null
         if
             i32.const 42
         end
     )
-)`), CompileError, mismatchError('anyref', 'i32'));
+)`), CompileError, mismatchError('nullref', 'i32'));
 
 
 // Basic compilation tests.
 
 let simpleTests = [
-    "(module (gc_feature_opt_in 1) (func (drop (ref.null anyref))))",
-    "(module (gc_feature_opt_in 1) (func $test (local anyref)))",
-    "(module (gc_feature_opt_in 1) (func $test (param anyref)))",
-    "(module (gc_feature_opt_in 1) (func $test (result anyref) (ref.null anyref)))",
-    "(module (gc_feature_opt_in 1) (func $test (block anyref (unreachable)) unreachable))",
-    "(module (gc_feature_opt_in 1) (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))",
-    `(module (gc_feature_opt_in 1) (import "a" "b" (param anyref)))`,
-    `(module (gc_feature_opt_in 1) (import "a" "b" (result anyref)))`,
-    `(module (gc_feature_opt_in 1) (global anyref (ref.null anyref)))`,
-    `(module (gc_feature_opt_in 1) (global (mut anyref) (ref.null anyref)))`,
+    "(module (gc_feature_opt_in 2) (func (drop (ref.null))))",
+    "(module (gc_feature_opt_in 2) (func $test (local anyref)))",
+    "(module (gc_feature_opt_in 2) (func $test (param anyref)))",
+    "(module (gc_feature_opt_in 2) (func $test (result anyref) (ref.null)))",
+    "(module (gc_feature_opt_in 2) (func $test (block anyref (unreachable)) unreachable))",
+    "(module (gc_feature_opt_in 2) (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))",
+    `(module (gc_feature_opt_in 2) (import "a" "b" (param anyref)))`,
+    `(module (gc_feature_opt_in 2) (import "a" "b" (result anyref)))`,
+    `(module (gc_feature_opt_in 2) (global anyref (ref.null)))`,
+    `(module (gc_feature_opt_in 2) (global (mut anyref) (ref.null)))`,
 ];
 
 for (let src of simpleTests) {
     wasmEvalText(src, {a:{b(){}}});
     assertEq(validate(wasmTextToBinary(src)), true);
 }
 
 // Basic behavioral tests.
 
 let { exports } = wasmEvalText(`(module
-    (gc_feature_opt_in 1)
+    (gc_feature_opt_in 2)
     (func (export "is_null") (result i32)
-        ref.null anyref
+        ref.null
         ref.is_null
     )
 
     (func $sum (result i32) (param i32)
         get_local 0
         i32.const 42
         i32.add
     )
 
     (func (export "is_null_spill") (result i32)
-        ref.null anyref
+        ref.null
         i32.const 58
         call $sum
         drop
         ref.is_null
     )
 
     (func (export "is_null_local") (result i32) (local anyref)
-        ref.null anyref
+        ref.null
         set_local 0
         i32.const 58
         call $sum
         drop
         get_local 0
         ref.is_null
     )
 
@@ -108,25 +108,25 @@ 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.
 
 exports = wasmEvalText(`(module
-    (gc_feature_opt_in 1)
+    (gc_feature_opt_in 2)
     (func (export "is_null") (result i32) (param $ref anyref)
         get_local $ref
         ref.is_null
     )
 
     (func (export "ref_or_null") (result anyref) (param $ref anyref) (param $selector i32)
         get_local $ref
-        ref.null anyref
+        ref.null
         get_local $selector
         select
     )
 
     (func $recursive (export "nested") (result anyref) (param $ref anyref) (param $i i32)
         ;; i == 10 => ret $ref
         get_local $i
         i32.const 10
@@ -166,33 +166,33 @@ assertEq(ref.calories, baguette.calories
 
 ref = exports.nested(baguette, 0);
 assertEq(ref, baguette);
 assertEq(ref.calories, baguette.calories);
 
 // Make sure grow-memory isn't blocked by the lack of gc.
 (function() {
     assertEq(wasmEvalText(`(module
-    (gc_feature_opt_in 1)
+    (gc_feature_opt_in 2)
     (memory 0 64)
     (func (export "f") (param anyref) (result i32)
         i32.const 10
         grow_memory
         drop
         current_memory
     )
 )`).exports.f({}), 10);
 })();
 
 // More interesting use cases about control flow joins.
 
 function assertJoin(body) {
     let val = { i: -1 };
     assertEq(wasmEvalText(`(module
-        (gc_feature_opt_in 1)
+        (gc_feature_opt_in 2)
         (func (export "test") (param $ref anyref) (param $i i32) (result anyref)
             ${body}
         )
     )`).exports.test(val), val);
     assertEq(val.i, -1);
 }
 
 assertJoin("(block anyref get_local $ref)");
@@ -249,17 +249,17 @@ assertJoin(`(block $out anyref (block $u
     i32.add
     tee_local $i
     br_table $unreachable $out
     ) unreachable))
 `);
 
 let x = { i: 42 }, y = { f: 53 };
 exports = wasmEvalText(`(module
-    (gc_feature_opt_in 1)
+    (gc_feature_opt_in 2)
     (func (export "test") (param $lhs anyref) (param $rhs anyref) (param $i i32) (result anyref)
         get_local $lhs
         get_local $rhs
         get_local $i
         select
     )
 )`).exports;
 
@@ -304,17 +304,17 @@ let imports = {
         },
         ret() {
             return imports.myBaguette;
         }
     }
 };
 
 exports = wasmEvalText(`(module
-    (gc_feature_opt_in 1)
+    (gc_feature_opt_in 2)
     (import $ret "funcs" "ret" (result anyref))
     (import $param "funcs" "param" (param anyref))
 
     (func (export "param") (param $x anyref) (param $y anyref)
         get_local $y
         get_local $x
         call $param
         call $param
@@ -333,17 +333,17 @@ imports.myBaguette = null;
 assertEq(exports.ret(), null);
 
 imports.myBaguette = new Baguette(1337);
 assertEq(exports.ret(), imports.myBaguette);
 
 // Check lazy stubs generation.
 
 exports = wasmEvalText(`(module
-    (gc_feature_opt_in 1)
+    (gc_feature_opt_in 2)
     (import $mirror "funcs" "mirror" (param anyref) (result anyref))
     (import $augment "funcs" "augment" (param anyref) (result anyref))
 
     (global $count_f (mut i32) (i32.const 0))
     (global $count_g (mut i32) (i32.const 0))
 
     (func $f (param $param anyref) (result anyref)
         i32.const 1
@@ -417,48 +417,48 @@ assertEq(x.i, 24);
 assertEq(x.newProp, "hello");
 assertEq(exports.count_f(), 1);
 assertEq(exports.count_g(), 1);
 
 // Globals.
 
 // Anyref globals in wasm modules.
 
-assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 1) (global (import "glob" "anyref") anyref))`, { glob: { anyref: 42 } }),
+assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 2) (global (import "glob" "anyref") anyref))`, { glob: { anyref: 42 } }),
     WebAssembly.LinkError,
     /import object field 'anyref' is not a Object-or-null/);
 
-assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 1) (global (import "glob" "anyref") anyref))`, { glob: { anyref: new WebAssembly.Global({ value: 'i32' }, 42) } }),
+assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 2) (global (import "glob" "anyref") anyref))`, { glob: { anyref: new WebAssembly.Global({ value: 'i32' }, 42) } }),
     WebAssembly.LinkError,
     /imported global type mismatch/);
 
-assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 1) (global (import "glob" "i32") i32))`, { glob: { i32: {} } }),
+assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 2) (global (import "glob" "i32") i32))`, { glob: { i32: {} } }),
     WebAssembly.LinkError,
     /import object field 'i32' is not a Number/);
 
 imports = {
     constants: {
         imm_null: null,
         imm_bread: new Baguette(321),
         mut_null: new WebAssembly.Global({ value: "anyref", mutable: true }, null),
         mut_bread: new WebAssembly.Global({ value: "anyref", mutable: true }, new Baguette(123))
     }
 };
 
 exports = wasmEvalText(`(module
-    (gc_feature_opt_in 1)
+    (gc_feature_opt_in 2)
     (global $g_imp_imm_null  (import "constants" "imm_null") anyref)
     (global $g_imp_imm_bread (import "constants" "imm_bread") anyref)
 
     (global $g_imp_mut_null   (import "constants" "mut_null") (mut anyref))
     (global $g_imp_mut_bread  (import "constants" "mut_bread") (mut anyref))
 
-    (global $g_imm_null     anyref (ref.null anyref))
+    (global $g_imm_null     anyref (ref.null))
     (global $g_imm_getglob  anyref (get_global $g_imp_imm_bread))
-    (global $g_mut         (mut anyref) (ref.null anyref))
+    (global $g_mut         (mut anyref) (ref.null))
 
     (func (export "imm_null")      (result anyref) get_global $g_imm_null)
     (func (export "imm_getglob")   (result anyref) get_global $g_imm_getglob)
 
     (func (export "imp_imm_null")  (result anyref) get_global $g_imp_imm_null)
     (func (export "imp_imm_bread") (result anyref) get_global $g_imp_imm_bread)
     (func (export "imp_mut_null")  (result anyref) get_global $g_imp_mut_null)
     (func (export "imp_mut_bread") (result anyref) get_global $g_imp_mut_bread)
--- a/js/src/jit-test/tests/wasm/gc/binary.js
+++ b/js/src/jit-test/tests/wasm/gc/binary.js
@@ -2,39 +2,21 @@
 
 load(libdir + "wasm-binary.js");
 
 const v2vSig = {args:[], ret:VoidCode};
 const v2vSigSection = sigSection([v2vSig]);
 
 function checkInvalid(body, errorMessage) {
     assertErrorMessage(() => new WebAssembly.Module(
-        moduleWithSections([gcFeatureOptInSection(1), v2vSigSection, declSection([0]), bodySection([body])])),
+        moduleWithSections([gcFeatureOptInSection(2), v2vSigSection, declSection([0]), bodySection([body])])),
                        WebAssembly.CompileError,
                        errorMessage);
 }
 
-const invalidRefNullBody = funcBody({locals:[], body:[
-    RefNull,
-    RefCode,
-    0x42,
-
-    RefNull,
-    RefCode,
-    0x10,
-
-    // Condition code;
-    I32ConstCode,
-    0x10,
-
-    SelectCode,
-    DropCode
-]});
-checkInvalid(invalidRefNullBody, /invalid reference type for ref.null/);
-
 const invalidRefBlockType = funcBody({locals:[], body:[
     BlockCode,
     RefCode,
     0x42,
     EndCode,
 ]});
 checkInvalid(invalidRefBlockType, /invalid inline block type/);
 
--- a/js/src/jit-test/tests/wasm/gc/debugger.js
+++ b/js/src/jit-test/tests/wasm/gc/debugger.js
@@ -1,23 +1,23 @@
 // |jit-test| skip-if: !wasmGcEnabled() || !wasmDebuggingIsSupported()
 
 (function() {
     let g = newGlobal();
     let dbg = new Debugger(g);
-    g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (gc_feature_opt_in 1) (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`);
+    g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (gc_feature_opt_in 2) (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`);
 })();
 
 (function() {
     var g = newGlobal();
     g.parent = this;
 
     let src = `
       (module
-        (gc_feature_opt_in 1)
+        (gc_feature_opt_in 2)
         (func (export "func") (result anyref) (param $ref anyref)
             get_local $ref
         )
       )
     `;
 
     g.eval(`
         var obj = { somekey: 'somevalue' };
--- a/js/src/jit-test/tests/wasm/gc/disabled.js
+++ b/js/src/jit-test/tests/wasm/gc/disabled.js
@@ -4,25 +4,25 @@ const { CompileError, validate } = WebAs
 
 const UNRECOGNIZED_OPCODE_OR_BAD_TYPE = /unrecognized opcode|(Structure|reference) types not enabled|invalid inline block type/;
 
 function assertValidateError(text) {
     assertEq(validate(wasmTextToBinary(text)), false);
 }
 
 let simpleTests = [
-    "(module (gc_feature_opt_in 1) (func (drop (ref.null anyref))))",
-    "(module (gc_feature_opt_in 1) (func $test (local anyref)))",
-    "(module (gc_feature_opt_in 1) (func $test (param anyref)))",
-    "(module (gc_feature_opt_in 1) (func $test (result anyref) (ref.null anyref)))",
-    "(module (gc_feature_opt_in 1) (func $test (block anyref (unreachable)) unreachable))",
-    "(module (gc_feature_opt_in 1) (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))",
-    `(module (gc_feature_opt_in 1) (import "a" "b" (param anyref)))`,
-    `(module (gc_feature_opt_in 1) (import "a" "b" (result anyref)))`,
-    `(module (gc_feature_opt_in 1) (type $s (struct)))`,
+    "(module (gc_feature_opt_in 2) (func (drop (ref.null))))",
+    "(module (gc_feature_opt_in 2) (func $test (local anyref)))",
+    "(module (gc_feature_opt_in 2) (func $test (param anyref)))",
+    "(module (gc_feature_opt_in 2) (func $test (result anyref) (ref.null)))",
+    "(module (gc_feature_opt_in 2) (func $test (block anyref (unreachable)) unreachable))",
+    "(module (gc_feature_opt_in 2) (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))",
+    `(module (gc_feature_opt_in 2) (import "a" "b" (param anyref)))`,
+    `(module (gc_feature_opt_in 2) (import "a" "b" (result anyref)))`,
+    `(module (gc_feature_opt_in 2) (type $s (struct)))`,
 ];
 
 // Two distinct failure modes:
 //
 // - if we have no compiled-in support for wasm-gc we'll get a syntax error when
 //   parsing the test programs that use ref types and structures.
 //
 // - if we have compiled-in support for wasm-gc, but wasm-gc is not currently
--- a/js/src/jit-test/tests/wasm/gc/gc-feature-opt-in.js
+++ b/js/src/jit-test/tests/wasm/gc/gc-feature-opt-in.js
@@ -1,122 +1,132 @@
 // |jit-test| skip-if: !wasmGcEnabled()
 
+// Version numbers
+
+let CURRENT_VERSION = 2;
+let OLDER_INCOMPATIBLE_VERSION = 1; // v1 incompatible with v2
+let FUTURE_VERSION = 3;
+
 // Encoding.  If the section is present it must be first.
 
 var bad_order =
     new Uint8Array([0x00, 0x61, 0x73, 0x6d,
                     0x01, 0x00, 0x00, 0x00,
 
                     0x01,                   // Type section
                     0x01,                   // Section size
                     0x00,                   // Zero types
 
                     0x2a,                   // GcFeatureOptIn section
                     0x01,                   // Section size
-                    0x01]);                 // Version
+                    CURRENT_VERSION]);      // Version
 
 assertErrorMessage(() => new WebAssembly.Module(bad_order),
                    WebAssembly.CompileError,
                    /expected custom section/);
 
-// Version numbers.  Version 1 and 2 are good, version 3 is bad.
-
 new WebAssembly.Module(wasmTextToBinary(
     `(module
-      (gc_feature_opt_in 1))`));
+      (gc_feature_opt_in ${CURRENT_VERSION}))`));
 
 new WebAssembly.Module(wasmTextToBinary(
     `(module
-      (gc_feature_opt_in 1))`));
+      (gc_feature_opt_in ${CURRENT_VERSION}))`));
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
-      (gc_feature_opt_in 3))`)),
+      (gc_feature_opt_in ${OLDER_INCOMPATIBLE_VERSION}))`)),
                    WebAssembly.CompileError,
-                   /unsupported version of the gc feature/);
+                   /GC feature version \d+ is no longer supported by this engine/);
+
+assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
+    `(module
+      (gc_feature_opt_in ${FUTURE_VERSION}))`)),
+                   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 1)
+      (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(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in ${CURRENT_VERSION})
       (type (func (param anyref))))`));
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
       (type (func (param anyref))))`)),
                    WebAssembly.CompileError,
                    /reference types not enabled/);
 
 // Ditto returns
 
 new WebAssembly.Module(wasmTextToBinary(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in ${CURRENT_VERSION})
       (type (func (result anyref))))`));
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
       (type (func (result anyref))))`)),
                    WebAssembly.CompileError,
                    /reference types not enabled/);
 
 // Ditto locals
 
 new WebAssembly.Module(wasmTextToBinary(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in ${CURRENT_VERSION})
       (func (result i32)
        (local anyref)
        (i32.const 0)))`));
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
       (func (result i32)
        (local anyref)
        (i32.const 0)))`)),
                    WebAssembly.CompileError,
                    /reference types not enabled/);
 
 // Ditto globals
 
 new WebAssembly.Module(wasmTextToBinary(
     `(module
-      (gc_feature_opt_in 1)
-      (global (mut anyref) (ref.null anyref)))`));
+      (gc_feature_opt_in ${CURRENT_VERSION})
+      (global (mut anyref) (ref.null)))`));
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
-      (global (mut anyref) (ref.null anyref)))`)),
+      (global (mut anyref) (ref.null)))`)),
                    WebAssembly.CompileError,
                    /reference types not enabled/);
 
 // Ref instructions are only available if we opt in.
 //
 // When testing these we need to avoid struct types or parameters, locals,
 // returns, or globals of ref type, or guards on those will preempt the guards
 // on the instructions.
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
-      (func (ref.null anyref)))`)),
+      (func ref.null))`)),
                    WebAssembly.CompileError,
                    /unrecognized opcode/);
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
       (func ref.is_null))`)),
                    WebAssembly.CompileError,
                    /unrecognized opcode/);
--- a/js/src/jit-test/tests/wasm/gc/ion-and-baseline.js
+++ b/js/src/jit-test/tests/wasm/gc/ion-and-baseline.js
@@ -15,35 +15,35 @@
 // Ion can't talk about references yet *but* we can call indirect from Ion to a
 // baseline module that has exported a function that accepts or returns anyref,
 // without the caller knowing this or having to declare it.  All such calls
 // should fail in an orderly manner with a type mismatch, at the point of the
 // call.
 
 var refmod = new WebAssembly.Module(wasmTextToBinary(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
 
       (import $tbl "" "tbl" (table 4 anyfunc))
       (import $print "" "print" (func (param i32)))
 
       (type $htype (func (param anyref)))
       (type $itype (func (result anyref)))
 
       (elem (i32.const 0) $f $g)
 
       (func $f (param anyref)
        (call $print (i32.const 1)))
 
       (func $g (result anyref)
        (call $print (i32.const 2))
-       (ref.null anyref))
+       (ref.null))
 
       (func (export "test_h")
-       (call_indirect $htype (ref.null anyref) (i32.const 2)))
+       (call_indirect $htype (ref.null) (i32.const 2)))
 
       (func (export "test_i")
        (drop (call_indirect $itype (i32.const 3))))
 
      )`));
 
 var nonrefmod = new WebAssembly.Module(wasmTextToBinary(
     `(module
--- a/js/src/jit-test/tests/wasm/gc/ref-global.js
+++ b/js/src/jit-test/tests/wasm/gc/ref-global.js
@@ -1,68 +1,68 @@
 // |jit-test| skip-if: !wasmGcEnabled()
 
 // Basic private-to-module functionality.  At the moment all we have is null
 // pointers, not very exciting.
 
 {
     let bin = wasmTextToBinary(
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
 
           (type $point (struct
                         (field $x f64)
                         (field $y f64)))
 
-          (global $g1 (mut (ref $point)) (ref.null (ref $point)))
-          (global $g2 (mut (ref $point)) (ref.null (ref $point)))
-          (global $g3 (ref $point) (ref.null (ref $point)))
+          (global $g1 (mut (ref $point)) (ref.null))
+          (global $g2 (mut (ref $point)) (ref.null))
+          (global $g3 (ref $point) (ref.null))
 
           ;; Restriction: cannot expose Refs outside the module, not even
           ;; as a return value.  See ref-restrict.js.
 
           (func (export "get") (result anyref)
            (get_global $g1))
 
           (func (export "copy")
            (set_global $g2 (get_global $g1)))
 
           (func (export "clear")
            (set_global $g1 (get_global $g3))
-           (set_global $g2 (ref.null (ref $point)))))`);
+           (set_global $g2 (ref.null))))`);
 
     let mod = new WebAssembly.Module(bin);
     let ins = new WebAssembly.Instance(mod).exports;
 
     assertEq(ins.get(), null);
     ins.copy();                 // Should not crash
     ins.clear();                // Should not crash
 }
 
 // Global with struct type
 
 {
     let bin = wasmTextToBinary(
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
 
           (type $point (struct
                         (field $x f64)
                         (field $y f64)))
 
-          (global $glob (mut (ref $point)) (ref.null (ref $point)))
+          (global $glob (mut (ref $point)) (ref.null))
 
           (func (export "init")
            (set_global $glob (struct.new $point (f64.const 0.5) (f64.const 2.75))))
 
           (func (export "change")
            (set_global $glob (struct.new $point (f64.const 3.5) (f64.const 37.25))))
 
           (func (export "clear")
-           (set_global $glob (ref.null (ref $point))))
+           (set_global $glob (ref.null)))
 
           (func (export "x") (result f64)
            (struct.get $point 0 (get_global $glob)))
 
           (func (export "y") (result f64)
            (struct.get $point 1 (get_global $glob))))`);
 
     let mod = new WebAssembly.Module(bin);
@@ -82,17 +82,17 @@
     assertErrorMessage(() => ins.x(), WebAssembly.RuntimeError, /dereferencing null pointer/);
 }
 
 // Global value of type anyref for initializer from a WebAssembly.Global,
 // just check that it works.
 {
     let bin = wasmTextToBinary(
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
           (import $g "" "g" (global anyref))
           (global $glob anyref (get_global $g))
           (func (export "get") (result anyref)
            (get_global $glob)))`);
 
     let mod = new WebAssembly.Module(bin);
     let obj = {zappa:37};
     let g = new WebAssembly.Global({value: "anyref"}, obj);
@@ -100,30 +100,30 @@
     assertEq(ins.get(), obj);
 }
 
 // We can't import a global of a reference type because we don't have a good
 // notion of structural type compatibility yet.
 {
     let bin = wasmTextToBinary(
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
           (type $box (struct (field $val i32)))
           (import "m" "g" (global (mut (ref $box)))))`);
 
     assertErrorMessage(() => new WebAssembly.Module(bin), WebAssembly.CompileError,
                        /cannot expose reference type/);
 }
 
 // We can't export a global of a reference type because we can't later import
 // it.  (Once we can export it, the value setter must also perform the necessary
 // subtype check, which implies we have some notion of exporting types, and we
 // don't have that yet.)
 {
     let bin = wasmTextToBinary(
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
           (type $box (struct (field $val i32)))
-          (global $boxg (export "box") (mut (ref $box)) (ref.null (ref $box))))`);
+          (global $boxg (export "box") (mut (ref $box)) (ref.null)))`);
 
     assertErrorMessage(() => new WebAssembly.Module(bin), WebAssembly.CompileError,
                        /cannot expose reference type/);
 }
--- a/js/src/jit-test/tests/wasm/gc/ref-restrict.js
+++ b/js/src/jit-test/tests/wasm/gc/ref-restrict.js
@@ -46,304 +46,304 @@
 function wasmCompile(text) {
     return new WebAssembly.Module(wasmTextToBinary(text));
 }
 
 // Exported function can't take ref type parameter, but anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $x i32)))
       (func (export "f") (param (ref $box)) (unreachable)))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (func (export "f") (param anyref) (unreachable)))`),
          "object");
 
 // Exported function can't return ref result, but anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $x i32)))
-      (func (export "f") (result (ref $box)) (ref.null (ref $box))))`),
+      (func (export "f") (result (ref $box)) (ref.null)))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
-      (func (export "f") (result anyref) (ref.null anyref)))`),
+      (gc_feature_opt_in 2)
+      (func (export "f") (result anyref) (ref.null)))`),
          "object");
 
 // Imported function can't take ref parameter, but anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $x i32)))
       (import "m" "f" (param (ref $box))))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (import "m" "f" (param anyref)))`),
          "object");
 
 // Imported function can't return ref type, but anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $x i32)))
       (import "m" "f" (param i32) (result (ref $box))))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (import "m" "f" (param i32) (result anyref)))`),
          "object");
 
 // Imported global can't be of Ref type (irrespective of mutability), though anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $val i32)))
       (import "m" "g" (global (mut (ref $box)))))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $val i32)))
       (import "m" "g" (global (ref $box))))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (import "m" "g" (global (mut anyref))))`),
          "object");
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (import "m" "g" (global anyref)))`),
          "object");
 
 // Exported global can't be of Ref type (irrespective of mutability), though anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $val i32)))
-      (global $boxg (export "box") (mut (ref $box)) (ref.null (ref $box))))`),
+      (global $boxg (export "box") (mut (ref $box)) (ref.null)))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $val i32)))
-      (global $boxg (export "box") (ref $box) (ref.null (ref $box))))`),
+      (global $boxg (export "box") (ref $box) (ref.null)))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
-      (global $boxg (export "box") (mut anyref) (ref.null anyref)))`),
+      (gc_feature_opt_in 2)
+      (global $boxg (export "box") (mut anyref) (ref.null)))`),
          "object");
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
-      (global $boxg (export "box") anyref (ref.null anyref)))`),
+      (gc_feature_opt_in 2)
+      (global $boxg (export "box") anyref (ref.null)))`),
          "object");
 
 // Exported table cannot reference functions that are exposed for Ref, but anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $val i32)))
       (table (export "tbl") 1 anyfunc)
       (elem (i32.const 0) $f1)
       (func $f1 (param (ref $box)) (unreachable)))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $val i32)))
       (table (export "tbl") 1 anyfunc)
       (elem (i32.const 0) $f1)
-      (func $f1 (result (ref $box)) (ref.null (ref $box))))`),
+      (func $f1 (result (ref $box)) (ref.null)))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (table (export "tbl") 1 anyfunc)
       (elem (i32.const 0) $f1)
       (func $f1 (param anyref) (unreachable)))`),
          "object");
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (table (export "tbl") 1 anyfunc)
       (elem (i32.const 0) $f1)
-      (func $f1 (result anyref) (ref.null anyref)))`),
+      (func $f1 (result anyref) (ref.null)))`),
          "object");
 
 // Imported table cannot reference functions that are exposed for Ref, though anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $val i32)))
       (import "m" "tbl" (table 1 anyfunc))
       (elem (i32.const 0) $f1)
       (func $f1 (param (ref $box)) (unreachable)))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $val i32)))
       (import "m" "tbl" (table 1 anyfunc))
       (elem (i32.const 0) $f1)
-      (func $f1 (result (ref $box)) (ref.null (ref $box))))`),
+      (func $f1 (result (ref $box)) (ref.null)))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (import "m" "tbl" (table 1 anyfunc))
       (elem (i32.const 0) $f1)
       (func $f1 (param anyref) (unreachable)))`),
          "object");
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (import "m" "tbl" (table 1 anyfunc))
       (elem (i32.const 0) $f1)
-      (func $f1 (result anyref) (ref.null anyref)))`),
+      (func $f1 (result anyref) (ref.null)))`),
          "object");
 
 // Can't call via exported table with type that is exposed for Ref, though anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $val i32)))
       (type $fn (func (param (ref $box))))
       (table (export "tbl") 1 anyfunc)
       (func (param i32)
-       (call_indirect $fn (ref.null (ref $box)) (get_local 0))))`),
+       (call_indirect $fn (ref.null) (get_local 0))))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $val i32)))
       (type $fn (func (result (ref $box))))
       (table (export "tbl") 1 anyfunc)
       (func (param i32) (result (ref $box))
        (call_indirect $fn (get_local 0))))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $fn (func (param anyref)))
       (table (export "tbl") 1 anyfunc)
       (func (param i32)
-       (call_indirect $fn (ref.null anyref) (get_local 0))))`),
+       (call_indirect $fn (ref.null) (get_local 0))))`),
          "object");
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $fn (func (result anyref)))
       (table (export "tbl") 1 anyfunc)
       (func (param i32) (result anyref)
        (call_indirect $fn (get_local 0))))`),
          "object");
 
 // Can't call via imported table with type that is exposed for Ref, though anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $val i32)))
       (type $fn (func (param (ref $box))))
       (import "m" "tbl" (table 1 anyfunc))
       (func (param i32)
-       (call_indirect $fn (ref.null (ref $box)) (get_local 0))))`),
+       (call_indirect $fn (ref.null) (get_local 0))))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertErrorMessage(() => wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $box (struct (field $val i32)))
       (type $fn (func (result (ref $box))))
       (import "m" "tbl" (table 1 anyfunc))
       (func (param i32) (result (ref $box))
        (call_indirect $fn (get_local 0))))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $fn (func (param anyref)))
       (import "m" "tbl" (table 1 anyfunc))
       (func (param i32)
-       (call_indirect $fn (ref.null anyref) (get_local 0))))`),
+       (call_indirect $fn (ref.null) (get_local 0))))`),
          "object");
 
 assertEq(typeof wasmCompile(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $fn (func (result anyref)))
       (import "m" "tbl" (table 1 anyfunc))
       (func (param i32) (result anyref)
        (call_indirect $fn (get_local 0))))`),
          "object");
 
 // We can call via a private table with a type that is exposed for Ref.
 
 {
     let m = wasmCompile(
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
           (type $box (struct (field $val i32)))
           (type $fn (func (param (ref $box)) (result i32)))
           (table 1 anyfunc)
           (elem (i32.const 0) $f1)
           (func $f1 (param (ref $box)) (result i32) (i32.const 37))
           (func (export "f") (param i32) (result i32)
-           (call_indirect $fn (ref.null (ref $box)) (get_local 0))))`);
+           (call_indirect $fn (ref.null) (get_local 0))))`);
     let i = new WebAssembly.Instance(m).exports;
     assertEq(i.f(0), 37);
 }
--- a/js/src/jit-test/tests/wasm/gc/ref-struct.js
+++ b/js/src/jit-test/tests/wasm/gc/ref-struct.js
@@ -3,54 +3,54 @@
 // We'll be running some binary-format tests shortly.
 
 load(libdir + "wasm-binary.js");
 
 const v2vSigSection = sigSection([{args:[], ret:VoidCode}]);
 
 function checkInvalid(body, errorMessage) {
     assertErrorMessage(() => new WebAssembly.Module(
-        moduleWithSections([gcFeatureOptInSection(1),
+        moduleWithSections([gcFeatureOptInSection(2),
                             v2vSigSection,
                             declSection([0]),
                             bodySection([body])])),
                        WebAssembly.CompileError,
                        errorMessage);
 }
 
 // General test case for struct.new, struct.get, and struct.set: binary tree
 // manipulation.
 
 {
     let bin = wasmTextToBinary(
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
 
           (import $print_lp "" "print_lp" (func))
           (import $print_rp "" "print_rp" (func))
           (import $print_int "" "print_int" (func (param i32)))
 
           (type $wabbit (struct
                          (field $x (mut i32))
                          (field $left (mut (ref $wabbit)))
                          (field $right (mut (ref $wabbit)))))
 
-          (global $g (mut (ref $wabbit)) (ref.null (ref $wabbit)))
+          (global $g (mut (ref $wabbit)) (ref.null))
 
           (global $k (mut i32) (i32.const 0))
 
           (func (export "init") (param $n i32)
                 (set_global $g (call $make (get_local $n))))
 
           (func $make (param $n i32) (result (ref $wabbit))
                 (local $tmp i32)
                 (set_local $tmp (get_global $k))
                 (set_global $k (i32.add (get_local $tmp) (i32.const 1)))
                 (if (ref $wabbit) (i32.le_s (get_local $n) (i32.const 2))
-                    (struct.new $wabbit (get_local $tmp) (ref.null (ref $wabbit)) (ref.null (ref $wabbit)))
+                    (struct.new $wabbit (get_local $tmp) (ref.null) (ref.null))
                     (block (ref $wabbit)
                       (struct.new $wabbit
                                   (get_local $tmp)
                                   (call $make (i32.sub (get_local $n) (i32.const 1)))
                                   (call $make (i32.sub (get_local $n) (i32.const 2)))))))
 
           (func (export "accumulate") (result i32)
                 (call $accum (get_global $g)))
@@ -114,55 +114,55 @@ function checkInvalid(body, errorMessage
 }
 
 // Sanity check for struct.set: we /can/ store a (ref T) into a (ref U) field
 // with struct.set if T <: U; this should fall out of normal coercion but good
 // to test.
 
 wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field (mut (ref $node)))))
       (type $nix (struct (field (mut (ref $node))) (field i32)))
       (func $f (param $p (ref $node)) (param $q (ref $nix))
        (struct.set $node 0 (get_local $p) (get_local $q))))`);
 
 // struct.narrow: if the pointer's null we get null
 
 assertEq(wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (type $node2 (struct (field i32) (field f32)))
       (func $f (param $p (ref $node)) (result (ref $node2))
        (struct.narrow (ref $node) (ref $node2) (get_local $p)))
       (func (export "test") (result anyref)
-       (call $f (ref.null (ref $node)))))`).exports.test(),
+       (call $f (ref.null))))`).exports.test(),
          null);
 
 // struct.narrow: if the downcast succeeds we get the original pointer
 
 assertEq(wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (type $node2 (struct (field i32) (field f32)))
       (func $f (param $p (ref $node)) (result (ref $node2))
        (struct.narrow (ref $node) (ref $node2) (get_local $p)))
       (func (export "test") (result i32)
        (local $n (ref $node))
        (set_local $n (struct.new $node2 (i32.const 0) (f32.const 12)))
        (ref.eq (call $f (get_local $n)) (get_local $n))))`).exports.test(),
          1);
 
 // And once more with mutable fields
 
 assertEq(wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field (mut i32))))
       (type $node2 (struct (field (mut i32)) (field f32)))
       (func $f (param $p (ref $node)) (result (ref $node2))
        (struct.narrow (ref $node) (ref $node2) (get_local $p)))
       (func (export "test") (result i32)
        (local $n (ref $node))
        (set_local $n (struct.new $node2 (i32.const 0) (f32.const 12)))
        (ref.eq (call $f (get_local $n)) (get_local $n))))`).exports.test(),
@@ -174,111 +174,111 @@ assertEq(wasmEvalText(
 //
 // We use ref-typed fields here because they have the trickiest equality rules,
 // and we have two cases: one where the ref types are the same, and one where
 // they reference different structures that look the same; this latter case
 // should fail because our structural compatibility is shallow.
 
 assertEq(wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
 
       (type $node (struct (field i32)))
       (type $node2a (struct (field i32) (field (ref $node))))
       (type $node2b (struct (field i32) (field (ref $node))))
 
       (func $f (param $p (ref $node)) (result (ref $node2b))
        (struct.narrow (ref $node) (ref $node2b) (get_local $p)))
 
       (func (export "test") (result i32)
        (local $n (ref $node))
-       (set_local $n (struct.new $node2a (i32.const 0) (ref.null (ref $node))))
+       (set_local $n (struct.new $node2a (i32.const 0) (ref.null)))
        (ref.eq (call $f (get_local $n)) (get_local $n))))`).exports.test(),
          1);
 
 assertEq(wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
 
       (type $node (struct (field i32)))
       (type $nodeCopy (struct (field i32)))
       (type $node2a (struct (field i32) (field (ref $node))))
       (type $node2b (struct (field i32) (field (ref $nodeCopy))))
 
       (func $f (param $p (ref $node)) (result (ref $node2b))
        (struct.narrow (ref $node) (ref $node2b) (get_local $p)))
 
       (func (export "test") (result i32)
        (local $n (ref $node))
-       (set_local $n (struct.new $node2a (i32.const 0) (ref.null (ref $node))))
+       (set_local $n (struct.new $node2a (i32.const 0) (ref.null)))
        (ref.eq (call $f (get_local $n)) (get_local $n))))`).exports.test(),
          0);
 
 // Another subtle case: struct.narrow can target a type that is not the concrete
 // type of the object, but a prefix of that concrete type.
 
 assertEq(wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (type $node2 (struct (field i32) (field f32)))
       (type $node3 (struct (field i32) (field f32) (field f64)))
       (func $f (param $p (ref $node)) (result (ref $node2))
        (struct.narrow (ref $node) (ref $node2) (get_local $p)))
       (func (export "test") (result i32)
        (local $n (ref $node))
        (set_local $n (struct.new $node3 (i32.const 0) (f32.const 12) (f64.const 17)))
        (ref.eq (call $f (get_local $n)) (get_local $n))))`).exports.test(),
          1);
 
 // struct.narrow: if the downcast fails we get null
 
 assertEq(wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (type $node2 (struct (field i32) (field f32)))
       (type $snort (struct (field i32) (field f64)))
       (func $f (param $p (ref $node)) (result (ref $node2))
        (struct.narrow (ref $node) (ref $node2) (get_local $p)))
       (func (export "test") (result anyref)
        (call $f (struct.new $snort (i32.const 0) (f64.const 12)))))`).exports.test(),
          null);
 
 // struct.narrow: anyref -> struct when the anyref is the right struct;
 // special case since anyref requires unboxing
 
 assertEq(wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (func $f (param $p anyref) (result (ref $node))
        (struct.narrow anyref (ref $node) (get_local $p)))
       (func (export "test") (result i32)
        (local $n (ref $node))
        (set_local $n (struct.new $node (i32.const 0)))
        (ref.eq (call $f (get_local $n)) (get_local $n))))`).exports.test(),
          1);
 
 // struct.narrow: anyref -> struct when the anyref is some random gunk.
 
 assertEq(wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (func (export "test") (param $p anyref) (result anyref)
        (struct.narrow anyref (ref $node) (get_local $p))))`).exports.test({hi:37}),
          null);
 
 // Types are private to an instance and struct.narrow can't break this
 
 {
     let txt =
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
           (type $node (struct (field i32)))
           (func (export "make") (param $n i32) (result anyref)
            (struct.new $node (get_local $n)))
           (func (export "coerce") (param $p anyref) (result i32)
            (ref.is_null (struct.narrow anyref (ref $node) (get_local $p)))))`;
     let mod = new WebAssembly.Module(wasmTextToBinary(txt));
     let ins1 = new WebAssembly.Instance(mod).exports;
     let ins2 = new WebAssembly.Instance(mod).exports;
@@ -288,201 +288,199 @@ assertEq(wasmEvalText(
 }
 
 // Negative tests
 
 // Attempting to mutate immutable field with struct.set
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (func $f (param $p (ref $node))
        (struct.set $node 0 (get_local $p) (i32.const 37))))`),
                    WebAssembly.CompileError,
                    /field is not mutable/);
 
 // Attempting to store incompatible value in mutable field with struct.set
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field (mut i32))))
       (func $f (param $p (ref $node))
        (struct.set $node 0 (get_local $p) (f32.const 37))))`),
                    WebAssembly.CompileError,
                    /expression has type f32 but expected i32/);
 
 // Out-of-bounds reference for struct.get
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (func $f (param $p (ref $node)) (result i32)
        (struct.get $node 1 (get_local $p))))`),
                    WebAssembly.CompileError,
                    /field index out of range/);
 
 // Out-of-bounds reference for struct.set
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field (mut i32))))
       (func $f (param $p (ref $node))
        (struct.set $node 1 (get_local $p) (i32.const 37))))`),
                    WebAssembly.CompileError,
                    /field index out of range/);
 
 // Base pointer is of unrelated type to stated type in struct.get
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (type $snort (struct (field f64)))
       (func $f (param $p (ref $snort)) (result i32)
        (struct.get $node 0 (get_local $p))))`),
                    WebAssembly.CompileError,
                    /expression has type.*but expected.*/);
 
 // Base pointer is of unrelated type to stated type in struct.set
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field (mut i32))))
       (type $snort (struct (field f64)))
       (func $f (param $p (ref $snort)) (result i32)
        (struct.set $node 0 (get_local $p) (i32.const 0))))`),
                    WebAssembly.CompileError,
                    /expression has type.*but expected.*/);
 
 // Base pointer is of unrelated type to stated type in struct.narrow
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (type $node2 (struct (field i32) (field f32)))
       (type $snort (struct (field f64)))
       (func $f (param $p (ref $snort)) (result (ref $node2))
        (struct.narrow (ref $node) (ref $node2) (get_local 0))))`),
                    WebAssembly.CompileError,
                    /expression has type.*but expected.*/);
 
 // source and target types are compatible except for mutability
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (type $node2 (struct (field (mut i32)) (field f32)))
       (func $f (param $p (ref $node)) (result (ref $node2))
        (struct.narrow (ref $node) (ref $node2) (get_local 0))))`),
                    WebAssembly.CompileError,
                    /invalid narrowing operation/);
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field (mut i32))))
       (type $node2 (struct (field i32) (field f32)))
       (func $f (param $p (ref $node)) (result (ref $node2))
        (struct.narrow (ref $node) (ref $node2) (get_local 0))))`),
                    WebAssembly.CompileError,
                    /invalid narrowing operation/);
 
 // source and target types must be ref types: source syntax
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (func $f (param $p (ref $node)) (result anyref)
        (struct.narrow i32 anyref (get_local 0))))`),
                    SyntaxError,
                    /struct.narrow requires ref type/);
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (func $f (param $p (ref $node)) (result anyref)
        (struct.narrow anyref i32 (get_local 0))))`),
                    SyntaxError,
                    /struct.narrow requires ref type/);
 
 // source and target types must be ref types: binary format
 
 checkInvalid(funcBody({locals:[],
                        body:[
                            RefNull,
-                           AnyrefCode,
                            MiscPrefix, StructNarrow, I32Code, AnyrefCode,
                            DropCode
                        ]}),
              /invalid reference type for struct.narrow/);
 
 checkInvalid(funcBody({locals:[],
                        body:[
                            RefNull,
-                           AnyrefCode,
                            MiscPrefix, StructNarrow, AnyrefCode, I32Code,
                            DropCode
                        ]}),
              /invalid reference type for struct.narrow/);
 
 // target type is anyref so source type must be anyref as well (no upcasts)
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (func $f (param $p (ref $node)) (result anyref)
        (struct.narrow (ref $node) anyref (get_local 0))))`),
                    WebAssembly.CompileError,
                    /invalid type combination in struct.narrow/);
 
 // target type must be subtype of source type (no upcasts)
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32)))
       (type $node2 (struct (field i32) (field f32)))
       (func $f (param $p (ref $node2)) (result anyref)
        (struct.narrow (ref $node2) (ref $node) (get_local 0))))`),
                    WebAssembly.CompileError,
                    /invalid narrowing operation/);
 
 // Null pointer dereference in struct.get
 
 assertErrorMessage(function() {
     let ins = wasmEvalText(
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
           (type $node (struct (field i32)))
           (func (export "test")
-           (drop (call $f (ref.null (ref $node)))))
+           (drop (call $f (ref.null))))
           (func $f (param $p (ref $node)) (result i32)
            (struct.get $node 0 (get_local $p))))`);
     ins.exports.test();
 },
                    WebAssembly.RuntimeError,
                    /dereferencing null pointer/);
 
 // Null pointer dereference in struct.set
 
 assertErrorMessage(function() {
     let ins = wasmEvalText(
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
           (type $node (struct (field (mut i32))))
           (func (export "test")
-           (call $f (ref.null (ref $node))))
+           (call $f (ref.null)))
           (func $f (param $p (ref $node))
            (struct.set $node 0 (get_local $p) (i32.const 0))))`);
     ins.exports.test();
 },
                    WebAssembly.RuntimeError,
                    /dereferencing null pointer/);
--- a/js/src/jit-test/tests/wasm/gc/ref.js
+++ b/js/src/jit-test/tests/wasm/gc/ref.js
@@ -3,17 +3,17 @@ if (!wasmGcEnabled()) {
                        WebAssembly.CompileError, /reference types not enabled/);
     quit(0);
 }
 
 // Parsing and resolving.
 
 var bin = wasmTextToBinary(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $cons (struct
                    (field $car i32)
                    (field $cdr (ref $cons))))
 
       (type $odd (struct
                   (field $odd.x i32)
                   (field $to_even (ref $even))))
 
@@ -29,191 +29,191 @@ var bin = wasmTextToBinary(
       ;; Note none of these functions are exported, as they use Ref types in their signatures.
 
       (func (param (ref $cons)) (result i32)
        (i32.const 0))
 
       (func $cdr (param $p (ref $cons)) (result (ref $cons))
        (local $l (ref $cons))
        ;; store null value of correct type
-       (set_local $l (ref.null (ref $cons)))
+       (set_local $l (ref.null))
        ;; store local of correct type
        (set_local $l (get_local $p))
        ;; store call result of correct type
        (set_local $l (call $cdr (get_local $p)))
        ;; TODO: eventually also a test with get_global
        ;; blocks and if with result type
        (block (ref $cons)
         (if (ref $cons) (i32.eqz (i32.const 0))
             (unreachable)
-            (ref.null (ref $cons)))))
+            (ref.null))))
 
       (func (param (ref $even)) (result (ref $odd))
-       (ref.null (ref $odd)))
+       (ref.null))
 
       (func (param (ref $odd)) (result (ref $even))
-       (ref.null (ref $even)))
+       (ref.null))
 
       (func (param (ref $cons))
        (call $cdr (get_local 0))
        drop
        (call $imp (get_local 0))
        drop)
 
       (func (param (ref $cons))
-       (drop (ref.eq (get_local 0) (ref.null (ref $cons))))
-       (drop (ref.eq (ref.null (ref $cons)) (get_local 0)))
-       (drop (ref.eq (get_local 0) (ref.null anyref)))
-       (drop (ref.eq (ref.null anyref) (get_local 0))))
+       (drop (ref.eq (get_local 0) (ref.null)))
+       (drop (ref.eq (ref.null) (get_local 0)))
+       (drop (ref.eq (get_local 0) (ref.null)))
+       (drop (ref.eq (ref.null) (get_local 0))))
      )`);
 
 // Validation
 
 assertEq(WebAssembly.validate(bin), true);
 
 // ref.is_null should work on any reference type
 
 new WebAssembly.Module(wasmTextToBinary(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct))
  (func $null (param (ref $s)) (result i32)
    (ref.is_null (get_local 0))))
 `))
 
 // Automatic upcast to anyref
 
 new WebAssembly.Module(wasmTextToBinary(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field i32)))
  (func $f (param (ref $s)) (call $g (get_local 0)))
  (func $g (param anyref) (unreachable)))
 `));
 
 // Misc failure modes
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (func (param (ref $odd)) (unreachable)))
 `),
 SyntaxError, /Type label.*not found/);
 
 // Ref type mismatch in parameter is allowed through the prefix rule
 // but not if the structs are incompatible.
 
 wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field i32)))
  (type $t (struct (field i32)))
  (func $f (param (ref $s)) (unreachable))
  (func $g (param (ref $t)) (call $f (get_local 0)))
 )`);
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field i32)))
  (type $t (struct (field f32))) ;; Incompatible type
  (func $f (param (ref $s)) (unreachable))
  (func $g (param (ref $t)) (call $f (get_local 0)))
 )`),
 WebAssembly.CompileError, /expression has type ref.*but expected ref/);
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field i32)))
  (type $t (struct (field (mut i32)))) ;; Incompatible mutability
  (func $f (param (ref $s)) (unreachable))
  (func $g (param (ref $t)) (call $f (get_local 0)))
 )`),
 WebAssembly.CompileError, /expression has type ref.*but expected ref/);
 
 // Ref type mismatch in assignment to local but the prefix rule allows
 // the assignment to succeed if the structs are the same.
 
 wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field i32)))
  (type $t (struct (field i32)))
  (func $f (param (ref $s)) (local (ref $t)) (set_local 1 (get_local 0))))
 `)
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field i32)))
  (type $t (struct (field f32)))
  (func $f (param (ref $s)) (local (ref $t)) (set_local 1 (get_local 0))))
 `),
 WebAssembly.CompileError, /expression has type ref.*but expected ref/);
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field i32)))
  (type $t (struct (field (mut i32))))
  (func $f (param (ref $s)) (unreachable))
  (func $g (param (ref $t)) (call $f (get_local 0)))
 )`),
 WebAssembly.CompileError, /expression has type ref.*but expected ref/);
 
 // Ref type mismatch in return but the prefix rule allows the return
 // to succeed if the structs are the same.
 
 wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field i32)))
  (type $t (struct (field i32)))
  (func $f (param (ref $s)) (result (ref $t)) (get_local 0)))
 `);
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field i32)))
  (type $t (struct (field f32)))
  (func $f (param (ref $s)) (result (ref $t)) (get_local 0)))
 `),
 WebAssembly.CompileError, /expression has type ref.*but expected ref/);
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field i32)))
  (type $t (struct (field (mut i32))))
  (func $f (param (ref $s)) (result (ref $t)) (get_local 0)))
 `),
 WebAssembly.CompileError, /expression has type ref.*but expected ref/);
 
 // Ref type can't reference a function type
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $x (func (param i32)))
  (func $f (param (ref $x)) (unreachable)))
 `),
 SyntaxError, /Type label.*not found/);
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type (func (param i32)))
  (func $f (param (ref 0)) (unreachable)))
 `),
 WebAssembly.CompileError, /does not reference a struct type/);
 
 // No automatic downcast from anyref
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field i32)))
  (func $f (param anyref) (call $g (get_local 0)))
  (func $g (param (ref $s)) (unreachable)))
 `),
 WebAssembly.CompileError, /expression has type anyref but expected ref/);
--- a/js/src/jit-test/tests/wasm/gc/structs.js
+++ b/js/src/jit-test/tests/wasm/gc/structs.js
@@ -1,15 +1,15 @@
 // |jit-test| skip-if: !wasmGcEnabled()
 
 var conf = getBuildConfiguration();
 
 var bin = wasmTextToBinary(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
 
       (table 2 anyfunc)
       (elem (i32.const 0) $doit $doitagain)
 
       ;; Type array has a mix of types
 
       (type $f1 (func (param i32) (result i32)))
 
@@ -221,17 +221,17 @@ assertEq(withfloats._1, Math.PI);
 assertEq(withfloats._2, bigger);
 assertEq(withfloats._3, Math.fround(5/6));
 assertEq(withfloats._4, 0x1337);
 
 // A simple stress test
 
 var stress = wasmTextToBinary(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
       (type $node (struct (field i32) (field (ref $node))))
       (func (export "iota1") (param $n i32) (result anyref)
        (local $list (ref $node))
        (block $exit
         (loop $loop
          (br_if $exit (i32.eqz (get_local $n)))
          (set_local $list (struct.new $node (get_local $n) (get_local $list)))
          (set_local $n (i32.sub (get_local $n) (i32.const 1)))
@@ -249,17 +249,17 @@ assertEq(the_list, null);
 // Fields and their exposure in JS.  We can't export types yet so hide them
 // inside the module with globals.
 
 // i64 fields.
 
 {
     let txt =
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
 
           (type $big (struct
                       (field (mut i32))
                       (field (mut i64))
                       (field (mut i32))))
 
           (func (export "set") (param anyref)
            (local (ref $big))
@@ -309,24 +309,24 @@ assertEq(the_list, null);
     assertEq(v._1_high, 0x31415926)
     assertEq(ins.low(v), 0x53589793);
     assertEq(ins.high(v), 0x31415926)
 }
 
 {
     let txt =
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
 
           (type $big (struct
                       (field (mut i32))
                       (field (mut i64))
                       (field (mut i32))))
 
-          (global $g (mut (ref $big)) (ref.null (ref $big)))
+          (global $g (mut (ref $big)) (ref.null))
 
           (func (export "make") (result anyref)
            (set_global $g
             (struct.new $big (i32.const 0x7aaaaaaa) (i64.const 0x4201020337) (i32.const 0x6bbbbbbb)))
            (get_global $g))
 
           (func (export "update0") (param $x i32)
            (struct.set $big 0 (get_global $g) (get_local $x)))
@@ -384,21 +384,21 @@ assertEq(the_list, null);
     assertEq(ins.get1_high(), 0x77777777);
     assertEq(v._1_high, 0x77777777);
     assertEq(v._2, 0x62345123);
 }
 
 
 var bin = wasmTextToBinary(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
 
       (type $cons (struct (field i32) (field (ref $cons))))
 
-      (global $g (mut (ref $cons)) (ref.null (ref $cons)))
+      (global $g (mut (ref $cons)) (ref.null))
 
       (func (export "push") (param i32)
        (set_global $g (struct.new $cons (get_local 0) (get_global $g))))
 
       (func (export "top") (result i32)
        (struct.get $cons 0 (get_global $g)))
 
       (func (export "pop")
@@ -427,17 +427,17 @@ assertErrorMessage(() => ins.pop(),
 
 // Check that a wrapped object cannot be unboxed from anyref even if the wrapper
 // points to the right type.  This is a temporary restriction, until we're able
 // to avoid dealing with wrappers inside the engine.
 
 {
     var ins = wasmEvalText(
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
           (type $Node (struct (field i32)))
           (func (export "mk") (result anyref)
            (struct.new $Node (i32.const 37)))
           (func (export "f") (param $n anyref) (result anyref)
            (struct.narrow anyref (ref $Node) (get_local $n))))`).exports;
     var n = ins.mk();
     assertEq(ins.f(n), n);
     assertEq(ins.f(wrapWithProto(n, {})), null);
@@ -445,17 +445,17 @@ assertErrorMessage(() => ins.pop(),
 
 // Field names.
 
 // Test that names map to the right fields.
 
 {
     let ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
 
           (type $s (struct
                     (field $x i32)
                     (field $y i32)))
 
           (func $f (param $p (ref $s)) (result i32)
            (struct.get $s $x (get_local $p)))
 
@@ -473,165 +473,165 @@ assertErrorMessage(() => ins.pop(),
     assertEq(ins.testf(10), 10);
     assertEq(ins.testg(10), 20);
 }
 
 // Test that field names must be unique in the module.
 
 assertErrorMessage(() => wasmTextToBinary(
     `(module
-      (gc_feature_opt_in 1)
+      (gc_feature_opt_in 2)
 
       (type $s (struct (field $x i32)))
       (type $t (struct (field $x i32)))
      )`),
                   SyntaxError,
                   /duplicate field name/);
 
 // negative tests
 
 // Wrong type passed as initializer
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(`
 (module
-  (gc_feature_opt_in 1)
+  (gc_feature_opt_in 2)
   (type $r (struct (field i32)))
   (func $f (param f64) (result anyref)
     (struct.new $r (get_local 0)))
 )`)),
 WebAssembly.CompileError, /type mismatch/);
 
 // Too few values passed for initializer
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(`
 (module
-  (gc_feature_opt_in 1)
+  (gc_feature_opt_in 2)
   (type $r (struct (field i32) (field i32)))
   (func $f (result anyref)
     (struct.new $r (i32.const 0)))
 )`)),
 WebAssembly.CompileError, /popping value from empty stack/);
 
 // Too many values passed for initializer, sort of
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(`
 (module
-  (gc_feature_opt_in 1)
+  (gc_feature_opt_in 2)
   (type $r (struct (field i32) (field i32)))
   (func $f (result anyref)
     (i32.const 0)
     (i32.const 1)
     (i32.const 2)
     struct.new $r)
 )`)),
 WebAssembly.CompileError, /unused values/);
 
 // Not referencing a structure type
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(`
 (module
-  (gc_feature_opt_in 1)
+  (gc_feature_opt_in 2)
   (type (func (param i32) (result i32)))
   (func $f (result anyref)
     (struct.new 0))
 )`)),
 WebAssembly.CompileError, /not a struct type/);
 
 // Nominal type equivalence for structs, but the prefix rule allows this
 // conversion to succeed.
 
 wasmEvalText(`
  (module
-   (gc_feature_opt_in 1)
+   (gc_feature_opt_in 2)
    (type $p (struct (field i32)))
    (type $q (struct (field i32)))
    (func $f (result (ref $p))
     (struct.new $q (i32.const 0))))
 `);
 
 // The field name is optional, so this should work.
 
 wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field i32))))
 `)
 
 // Empty structs are OK.
 
 wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct)))
 `)
 
 // Multiply defined structures.
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field $x i32)))
  (type $s (struct (field $y i32))))
 `),
 SyntaxError, /duplicate type name/);
 
 // Bogus type definition syntax.
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s))
 `),
 SyntaxError, /parsing wasm text/);
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (field $x i32)))
 `),
 SyntaxError, /bad type definition/);
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (field $x i31))))
 `),
 SyntaxError, /parsing wasm text/);
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct (fjeld $x i32))))
 `),
 SyntaxError, /parsing wasm text/);
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct abracadabra)))
 `),
 SyntaxError, /parsing wasm text/);
 
 // Function should not reference struct type: syntactic test
 
 assertErrorMessage(() => wasmEvalText(`
 (module
- (gc_feature_opt_in 1)
+ (gc_feature_opt_in 2)
  (type $s (struct))
  (type $f (func (param i32) (result i32)))
  (func (type 0) (param i32) (result i32) (unreachable)))
 `),
 WebAssembly.CompileError, /signature index references non-signature/);
 
 // Can't set immutable fields from JS
 
 {
     let ins = wasmEvalText(
         `(module
-          (gc_feature_opt_in 1)
+          (gc_feature_opt_in 2)
           (type $s (struct
                     (field i32)
                     (field (mut i64))))
           (func (export "make") (result anyref)
            (struct.new $s (i32.const 37) (i64.const 42))))`).exports;
     let v = ins.make();
     assertErrorMessage(() => v._0 = 12,
                        Error,
@@ -646,17 +646,17 @@ WebAssembly.CompileError, /signature ind
 
 // Function should not reference struct type: binary test
 
 var bad = new Uint8Array([0x00, 0x61, 0x73, 0x6d,
                           0x01, 0x00, 0x00, 0x00,
 
                           0x2a,                   // GcFeatureOptIn section
                           0x01,                   // Section size
-                          0x01,                   // Version
+                          0x02,                   // Version
 
                           0x01,                   // Type section
                           0x03,                   // Section size
                           0x01,                   // One type
                           0x50,                   // Struct
                           0x00,                   // Zero fields
 
                           0x03,                   // Function section
--- a/js/src/jit-test/tests/wasm/gc/tables-generalized.js
+++ b/js/src/jit-test/tests/wasm/gc/tables-generalized.js
@@ -3,53 +3,53 @@
 ///////////////////////////////////////////////////////////////////////////
 //
 // General table management in wasm
 
 // Wasm: Create table-of-anyref
 
 new WebAssembly.Module(wasmTextToBinary(
     `(module
-       (gc_feature_opt_in 1)
+       (gc_feature_opt_in 2)
        (table 10 anyref))`));
 
 // Wasm: Import table-of-anyref
 // JS: create table-of-anyref
 
 new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(
     `(module
-       (gc_feature_opt_in 1)
+       (gc_feature_opt_in 2)
        (table (import "m" "t") 10 anyref))`)),
                          {m:{t: new WebAssembly.Table({element:"anyref", initial:10})}});
 
 new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(
     `(module
-       (gc_feature_opt_in 1)
+       (gc_feature_opt_in 2)
        (import "m" "t" (table 10 anyref)))`)),
                          {m:{t: new WebAssembly.Table({element:"anyref", initial:10})}});
 
 // Wasm: Export table-of-anyref, initial values shall be null
 
 {
     let ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(
     `(module
-       (gc_feature_opt_in 1)
+       (gc_feature_opt_in 2)
        (table (export "t") 10 anyref))`)));
     let t = ins.exports.t;
     assertEq(t.length, 10);
     for (let i=0; i < t.length; i++)
         assertEq(t.get(0), null);
 }
 
 // JS: Exported table can be grown, and values are preserved
 
 {
     let ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(
     `(module
-       (gc_feature_opt_in 1)
+       (gc_feature_opt_in 2)
        (table (export "t") 10 anyref))`)));
     let t = ins.exports.t;
     let objs = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}];
     for (let i in objs)
         t.set(i, objs[i]);
     ins.exports.t.grow(10);
     assertEq(ins.exports.t.length, 20);
     for (let i in objs)
@@ -57,17 +57,17 @@ new WebAssembly.Instance(new WebAssembly
 }
 
 // Wasm: table.copy between tables of anyref (currently source and destination
 // are both table zero)
 
 {
     let ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(
     `(module
-       (gc_feature_opt_in 1)
+       (gc_feature_opt_in 2)
        (table (export "t") 10 anyref)
        (func (export "f")
          (table.copy (i32.const 5) (i32.const 0) (i32.const 3))))`)));
     let t = ins.exports.t;
     let objs = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}];
     for (let i in objs)
         t.set(i, objs[i]);
     ins.exports.f();
@@ -82,52 +82,52 @@ new WebAssembly.Instance(new WebAssembly
     assertEq(t.get(8), objs[8]);
     assertEq(t.get(9), objs[9]);
 }
 
 // Wasm: element segments targeting table-of-anyref is forbidden
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
-       (gc_feature_opt_in 1)
+       (gc_feature_opt_in 2)
        (func $f1 (result i32) (i32.const 0))
        (table 10 anyref)
        (elem (i32.const 0) $f1))`)),
                    WebAssembly.CompileError,
                    /only tables of 'anyfunc' may have element segments/);
 
 // Wasm: table.init on table-of-anyref is forbidden
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
-       (gc_feature_opt_in 1)
+       (gc_feature_opt_in 2)
        (func $f1 (result i32) (i32.const 0))
        (table 10 anyref)
        (elem passive $f1)
        (func
          (table.init 0 (i32.const 0) (i32.const 0) (i32.const 0))))`)),
                    WebAssembly.CompileError,
                    /only tables of 'anyfunc' may have element segments/);
 
 // Wasm: table types must match at link time
 
 assertErrorMessage(
     () => new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(
     `(module
-       (gc_feature_opt_in 1)
+       (gc_feature_opt_in 2)
        (import "m" "t" (table 10 anyref)))`)),
                                    {m:{t: new WebAssembly.Table({element:"anyfunc", initial:10})}}),
     WebAssembly.LinkError,
     /imported table type mismatch/);
 
 // call_indirect cannot reference table-of-anyref
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
-       (gc_feature_opt_in 1)
+       (gc_feature_opt_in 2)
        (table 10 anyref)
        (type $t (func (param i32) (result i32)))
        (func (result i32)
          (call_indirect $t (i32.const 37))))`)),
                    WebAssembly.CompileError,
                    /indirect calls must go through a table of 'anyfunc'/);
 
 ///////////////////////////////////////////////////////////////////////////
@@ -237,17 +237,17 @@ assertErrorMessage(() => new WebAssembly
     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 anyref)))
+             (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);
@@ -262,17 +262,17 @@ assertErrorMessage(() => new WebAssembly
 
 // table.set with non-i32 index - fails validation
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
        (gc_feature_opt_in 2)
        (table 10 anyref)
        (func (export "f") (param f64)
-         (table.set (get_local 0) (ref.null anyref))))`)),
+         (table.set (get_local 0) (ref.null))))`)),
                    WebAssembly.CompileError,
                    /type mismatch/);
 
 // table.set with non-anyref value - fails validation
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
        (gc_feature_opt_in 2)
@@ -311,17 +311,17 @@ assertErrorMessage(() => new WebAssembly
 // table.grow with delta at upper limit - fails
 // table.grow with negative delta - fails
 
 let ins = wasmEvalText(
     `(module
       (gc_feature_opt_in 2)
       (table (export "t") 10 20 anyref)
       (func (export "grow") (param i32) (result i32)
-       (table.grow (get_local 0) (ref.null anyref))))`);
+       (table.grow (get_local 0) (ref.null))))`);
 assertEq(ins.exports.grow(0), 10);
 assertEq(ins.exports.t.length, 10);
 assertEq(ins.exports.grow(1), 10);
 assertEq(ins.exports.t.length, 11);
 assertEq(ins.exports.t.get(10), null);
 assertEq(ins.exports.grow(9), 11);
 assertEq(ins.exports.t.length, 20);
 assertEq(ins.exports.t.get(19), null);
@@ -340,52 +340,52 @@ assertEq(ins.exports.t.length, 20)
 // Special case for private tables without a maximum
 
 {
     let ins = wasmEvalText(
         `(module
           (gc_feature_opt_in 2)
           (table 10 anyref)
           (func (export "grow") (param i32) (result i32)
-           (table.grow (get_local 0) (ref.null anyref))))`);
+           (table.grow (get_local 0) (ref.null))))`);
     assertEq(ins.exports.grow(0), 10);
     assertEq(ins.exports.grow(1), 10);
     assertEq(ins.exports.grow(9), 11);
     assertEq(ins.exports.grow(0), 20);
 }
 
 // Can't grow table of anyfunc yet
 
 assertErrorMessage(() => wasmEvalText(
     `(module
       (gc_feature_opt_in 2)     ;; Required because of the 'anyref' null value below
       (table $t 2 anyfunc)
       (func $f
-       (drop (table.grow (i32.const 1) (ref.null anyref)))))`),
+       (drop (table.grow (i32.const 1) (ref.null)))))`),
                    WebAssembly.CompileError,
                    /table.grow only on tables of anyref/);
 
 // table.grow with non-i32 argument - fails validation
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
        (gc_feature_opt_in 2)
        (table 10 anyref)
        (func (export "f") (param f64)
-        (table.grow (get_local 0) (ref.null anyref))))`)),
+        (table.grow (get_local 0) (ref.null))))`)),
                    WebAssembly.CompileError,
                    /type mismatch/);
 
 // table.grow when there are no tables - fails validation
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
        (gc_feature_opt_in 2)
        (func (export "f") (param i32)
-        (table.grow (get_local 0) (ref.null anyref))))`)),
+        (table.grow (get_local 0) (ref.null))))`)),
                    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
@@ -406,17 +406,17 @@ for (let visibility of ['', '(export "t"
     let exp = {m:{t: new WebAssembly.Table({element:"anyref",
                                             initial: 10,
                                             maximum: 20})}};
     let ins = wasmEvalText(
         `(module
           (gc_feature_opt_in 2)
           (table ${visibility} 10 20 anyref)
           (func (export "grow") (param i32) (result i32)
-           (table.grow (get_local 0) (ref.null anyref)))
+           (table.grow (get_local 0) (ref.null)))
           (func (export "size") (result i32)
            (table.size)))`,
         exp);
     assertEq(ins.exports.grow(0), 10);
     assertEq(ins.exports.size(), 10);
     assertEq(ins.exports.grow(1), 10);
     assertEq(ins.exports.size(), 11);
     assertEq(ins.exports.grow(9), 11);
--- a/js/src/jit-test/tests/wasm/gc/tables-multiple.js
+++ b/js/src/jit-test/tests/wasm/gc/tables-multiple.js
@@ -113,17 +113,17 @@ var exp = {m:{t0: new WebAssembly.Table(
               t1: new WebAssembly.Table({element:"anyref", initial:3})}};
 var ins = wasmEvalText(
     `(module
       (gc_feature_opt_in 2)
 
       (table $t0 (import "m" "t0") 2 anyref)
       (table $t1 (import "m" "t1") 3 anyref)
       (func (export "f") (result i32)
-       (table.grow $t1 (i32.const 5) (ref.null anyref)))
+       (table.grow $t1 (i32.const 5) (ref.null)))
       (func (export "size0") (result i32)
        (table.size $t0))
       (func (export "size1") (result i32)
        (table.size $t1)))`,
     exp);
 
 assertEq(ins.exports.f(), 3);
 assertEq(exp.m.t1.length, 8);
@@ -229,19 +229,19 @@ var exp = {m: {t0: tbl, t1:tbl}};
 
 var ins = wasmEvalText(
     `(module
       (gc_feature_opt_in 2)
       (import $t0 "m" "t0" (table 1 anyref))
       (import $t1 "m" "t1" (table 1 anyref))
       (table $t2 (export "t2") 1 anyfunc)
       (func (export "f") (result i32)
-       (table.grow $t0 (i32.const 1) (ref.null anyref)))
+       (table.grow $t0 (i32.const 1) (ref.null)))
       (func (export "g") (result i32)
-       (table.grow $t1 (i32.const 1) (ref.null anyref)))
+       (table.grow $t1 (i32.const 1) (ref.null)))
       (func (export "size") (result i32)
        (table.size $t2)))`,
     exp);
 
 assertEq(ins.exports.f(), 1);
 assertEq(ins.exports.g(), 2);
 assertEq(ins.exports.f(), 3);
 assertEq(ins.exports.g(), 4);
@@ -382,17 +382,17 @@ assertErrorMessage(() => wasmEvalText(
                    /table index out of range for table.size/);
 
 assertErrorMessage(() => wasmEvalText(
     `(module
       (gc_feature_opt_in 2)
       (table $t0 2 anyref)
       (table $t1 2 anyref)
       (func $f (result i32)
-       (table.grow 2 (i32.const 1) (ref.null anyref))))`),
+       (table.grow 2 (i32.const 1) (ref.null))))`),
                    WebAssembly.CompileError,
                    /table index out of range for table.grow/);
 
 assertErrorMessage(() => wasmEvalText(
     `(module
       (table $t0 2 anyfunc)
       (elem passive) ;; 0
       (func $f (result i32)
--- a/js/src/jit-test/tests/wasm/gc/tables-stress.js
+++ b/js/src/jit-test/tests/wasm/gc/tables-stress.js
@@ -8,17 +8,17 @@ for ( let prefix of ['', '(table $prefix
        (table $tbl 0 anyref)
        (import $item "m" "item" (func (result anyref)))
        (func (export "run") (param $numiters i32)
          (local $i i32)
          (local $j i32)
          (local $last i32)
          (local $iters i32)
          (local $tmp anyref)
-         (set_local $last (table.grow $tbl (i32.const 1) (ref.null anyref)))
+         (set_local $last (table.grow $tbl (i32.const 1) (ref.null)))
          (table.set $tbl (get_local $last) (call $item))
          (loop $iter_continue
            (set_local $i (i32.const 0))
            (set_local $j (get_local $last))
            (block $l_break
              (loop $l_continue
                (br_if $l_break (i32.ge_s (get_local $j) (get_local $i)))
                (set_local $tmp (table.get $tbl (get_local $i)))