summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/spec/multi-memory
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/wasm/spec/multi-memory')
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/address0.wast.js392
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/address1.wast.js538
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/align0.wast.js65
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/binary0.wast.js88
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/data0.wast.js93
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/data1.wast.js170
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/data_drop0.wast.js63
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/directives.txt1
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/exports0.wast.js78
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/float_exprs0.wast.js80
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/float_exprs1.wast.js128
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/float_memory.wast.js361
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/float_memory0.wast.js137
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/harness/directives.txt1
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/harness/harness.js448
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/imports0.wast.js73
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/imports1.wast.js40
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/imports2.wast.js120
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/imports3.wast.js109
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/imports4.wast.js93
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/linking0.wast.js68
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/linking1.wast.js104
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/linking2.wast.js67
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/linking3.wast.js120
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/load.wast.js845
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/load0.wast.js38
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/load1.wast.js90
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/load2.wast.js289
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/memory-multi.wast.js62
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/memory.wast.js390
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/memory_copy0.wast.js117
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/memory_fill0.wast.js77
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/memory_grow.wast.js773
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/memory_init0.wast.js70
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/memory_size.wast.js208
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/memory_size0.wast.js49
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/memory_size1.wast.js73
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/memory_size2.wast.js90
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/memory_size3.wast.js43
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/memory_trap0.wast.js78
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/memory_trap1.wast.js602
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/simd_load.wast.js295
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/simd_memory-multi.wast.js58
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/simd_store.wast.js238
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/start0.wast.js73
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/store.wast.js803
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/store0.wast.js48
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/store1.wast.js92
-rw-r--r--js/src/jit-test/tests/wasm/spec/multi-memory/traps0.wast.js80
49 files changed, 9018 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/address0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/address0.wast.js
new file mode 100644
index 0000000000..62b3c985d6
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/address0.wast.js
@@ -0,0 +1,392 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/address0.wast
+
+// ./test/core/multi-memory/address0.wast:3
+let $0 = instantiate(`(module
+ (memory $$mem0 0)
+ (memory $$mem1 1)
+ (data (memory $$mem1) (i32.const 0) "abcdefghijklmnopqrstuvwxyz")
+
+ (func (export "8u_good1") (param $$i i32) (result i32)
+ (i32.load8_u $$mem1 offset=0 (local.get $$i)) ;; 97 'a'
+ )
+ (func (export "8u_good2") (param $$i i32) (result i32)
+ (i32.load8_u $$mem1 align=1 (local.get $$i)) ;; 97 'a'
+ )
+ (func (export "8u_good3") (param $$i i32) (result i32)
+ (i32.load8_u $$mem1 offset=1 align=1 (local.get $$i)) ;; 98 'b'
+ )
+ (func (export "8u_good4") (param $$i i32) (result i32)
+ (i32.load8_u $$mem1 offset=2 align=1 (local.get $$i)) ;; 99 'c'
+ )
+ (func (export "8u_good5") (param $$i i32) (result i32)
+ (i32.load8_u $$mem1 offset=25 align=1 (local.get $$i)) ;; 122 'z'
+ )
+
+ (func (export "8s_good1") (param $$i i32) (result i32)
+ (i32.load8_s $$mem1 offset=0 (local.get $$i)) ;; 97 'a'
+ )
+ (func (export "8s_good2") (param $$i i32) (result i32)
+ (i32.load8_s $$mem1 align=1 (local.get $$i)) ;; 97 'a'
+ )
+ (func (export "8s_good3") (param $$i i32) (result i32)
+ (i32.load8_s $$mem1 offset=1 align=1 (local.get $$i)) ;; 98 'b'
+ )
+ (func (export "8s_good4") (param $$i i32) (result i32)
+ (i32.load8_s $$mem1 offset=2 align=1 (local.get $$i)) ;; 99 'c'
+ )
+ (func (export "8s_good5") (param $$i i32) (result i32)
+ (i32.load8_s $$mem1 offset=25 align=1 (local.get $$i)) ;; 122 'z'
+ )
+
+ (func (export "16u_good1") (param $$i i32) (result i32)
+ (i32.load16_u $$mem1 offset=0 (local.get $$i)) ;; 25185 'ab'
+ )
+ (func (export "16u_good2") (param $$i i32) (result i32)
+ (i32.load16_u $$mem1 align=1 (local.get $$i)) ;; 25185 'ab'
+ )
+ (func (export "16u_good3") (param $$i i32) (result i32)
+ (i32.load16_u $$mem1 offset=1 align=1 (local.get $$i)) ;; 25442 'bc'
+ )
+ (func (export "16u_good4") (param $$i i32) (result i32)
+ (i32.load16_u $$mem1 offset=2 align=2 (local.get $$i)) ;; 25699 'cd'
+ )
+ (func (export "16u_good5") (param $$i i32) (result i32)
+ (i32.load16_u $$mem1 offset=25 align=2 (local.get $$i)) ;; 122 'z\\0'
+ )
+
+ (func (export "16s_good1") (param $$i i32) (result i32)
+ (i32.load16_s $$mem1 offset=0 (local.get $$i)) ;; 25185 'ab'
+ )
+ (func (export "16s_good2") (param $$i i32) (result i32)
+ (i32.load16_s $$mem1 align=1 (local.get $$i)) ;; 25185 'ab'
+ )
+ (func (export "16s_good3") (param $$i i32) (result i32)
+ (i32.load16_s $$mem1 offset=1 align=1 (local.get $$i)) ;; 25442 'bc'
+ )
+ (func (export "16s_good4") (param $$i i32) (result i32)
+ (i32.load16_s $$mem1 offset=2 align=2 (local.get $$i)) ;; 25699 'cd'
+ )
+ (func (export "16s_good5") (param $$i i32) (result i32)
+ (i32.load16_s $$mem1 offset=25 align=2 (local.get $$i)) ;; 122 'z\\0'
+ )
+
+ (func (export "32_good1") (param $$i i32) (result i32)
+ (i32.load $$mem1 offset=0 (local.get $$i)) ;; 1684234849 'abcd'
+ )
+ (func (export "32_good2") (param $$i i32) (result i32)
+ (i32.load $$mem1 align=1 (local.get $$i)) ;; 1684234849 'abcd'
+ )
+ (func (export "32_good3") (param $$i i32) (result i32)
+ (i32.load $$mem1 offset=1 align=1 (local.get $$i)) ;; 1701077858 'bcde'
+ )
+ (func (export "32_good4") (param $$i i32) (result i32)
+ (i32.load $$mem1 offset=2 align=2 (local.get $$i)) ;; 1717920867 'cdef'
+ )
+ (func (export "32_good5") (param $$i i32) (result i32)
+ (i32.load $$mem1 offset=25 align=4 (local.get $$i)) ;; 122 'z\\0\\0\\0'
+ )
+
+ (func (export "8u_bad") (param $$i i32)
+ (drop (i32.load8_u $$mem1 offset=4294967295 (local.get $$i)))
+ )
+ (func (export "8s_bad") (param $$i i32)
+ (drop (i32.load8_s $$mem1 offset=4294967295 (local.get $$i)))
+ )
+ (func (export "16u_bad") (param $$i i32)
+ (drop (i32.load16_u $$mem1 offset=4294967295 (local.get $$i)))
+ )
+ (func (export "16s_bad") (param $$i i32)
+ (drop (i32.load16_s $$mem1 offset=4294967295 (local.get $$i)))
+ )
+ (func (export "32_bad") (param $$i i32)
+ (drop (i32.load $$mem1 offset=4294967295 (local.get $$i)))
+ )
+)`);
+
+// ./test/core/multi-memory/address0.wast:105
+assert_return(() => invoke($0, `8u_good1`, [0]), [value("i32", 97)]);
+
+// ./test/core/multi-memory/address0.wast:106
+assert_return(() => invoke($0, `8u_good2`, [0]), [value("i32", 97)]);
+
+// ./test/core/multi-memory/address0.wast:107
+assert_return(() => invoke($0, `8u_good3`, [0]), [value("i32", 98)]);
+
+// ./test/core/multi-memory/address0.wast:108
+assert_return(() => invoke($0, `8u_good4`, [0]), [value("i32", 99)]);
+
+// ./test/core/multi-memory/address0.wast:109
+assert_return(() => invoke($0, `8u_good5`, [0]), [value("i32", 122)]);
+
+// ./test/core/multi-memory/address0.wast:111
+assert_return(() => invoke($0, `8s_good1`, [0]), [value("i32", 97)]);
+
+// ./test/core/multi-memory/address0.wast:112
+assert_return(() => invoke($0, `8s_good2`, [0]), [value("i32", 97)]);
+
+// ./test/core/multi-memory/address0.wast:113
+assert_return(() => invoke($0, `8s_good3`, [0]), [value("i32", 98)]);
+
+// ./test/core/multi-memory/address0.wast:114
+assert_return(() => invoke($0, `8s_good4`, [0]), [value("i32", 99)]);
+
+// ./test/core/multi-memory/address0.wast:115
+assert_return(() => invoke($0, `8s_good5`, [0]), [value("i32", 122)]);
+
+// ./test/core/multi-memory/address0.wast:117
+assert_return(() => invoke($0, `16u_good1`, [0]), [value("i32", 25185)]);
+
+// ./test/core/multi-memory/address0.wast:118
+assert_return(() => invoke($0, `16u_good2`, [0]), [value("i32", 25185)]);
+
+// ./test/core/multi-memory/address0.wast:119
+assert_return(() => invoke($0, `16u_good3`, [0]), [value("i32", 25442)]);
+
+// ./test/core/multi-memory/address0.wast:120
+assert_return(() => invoke($0, `16u_good4`, [0]), [value("i32", 25699)]);
+
+// ./test/core/multi-memory/address0.wast:121
+assert_return(() => invoke($0, `16u_good5`, [0]), [value("i32", 122)]);
+
+// ./test/core/multi-memory/address0.wast:123
+assert_return(() => invoke($0, `16s_good1`, [0]), [value("i32", 25185)]);
+
+// ./test/core/multi-memory/address0.wast:124
+assert_return(() => invoke($0, `16s_good2`, [0]), [value("i32", 25185)]);
+
+// ./test/core/multi-memory/address0.wast:125
+assert_return(() => invoke($0, `16s_good3`, [0]), [value("i32", 25442)]);
+
+// ./test/core/multi-memory/address0.wast:126
+assert_return(() => invoke($0, `16s_good4`, [0]), [value("i32", 25699)]);
+
+// ./test/core/multi-memory/address0.wast:127
+assert_return(() => invoke($0, `16s_good5`, [0]), [value("i32", 122)]);
+
+// ./test/core/multi-memory/address0.wast:129
+assert_return(() => invoke($0, `32_good1`, [0]), [value("i32", 1684234849)]);
+
+// ./test/core/multi-memory/address0.wast:130
+assert_return(() => invoke($0, `32_good2`, [0]), [value("i32", 1684234849)]);
+
+// ./test/core/multi-memory/address0.wast:131
+assert_return(() => invoke($0, `32_good3`, [0]), [value("i32", 1701077858)]);
+
+// ./test/core/multi-memory/address0.wast:132
+assert_return(() => invoke($0, `32_good4`, [0]), [value("i32", 1717920867)]);
+
+// ./test/core/multi-memory/address0.wast:133
+assert_return(() => invoke($0, `32_good5`, [0]), [value("i32", 122)]);
+
+// ./test/core/multi-memory/address0.wast:135
+assert_return(() => invoke($0, `8u_good1`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:136
+assert_return(() => invoke($0, `8u_good2`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:137
+assert_return(() => invoke($0, `8u_good3`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:138
+assert_return(() => invoke($0, `8u_good4`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:139
+assert_return(() => invoke($0, `8u_good5`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:141
+assert_return(() => invoke($0, `8s_good1`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:142
+assert_return(() => invoke($0, `8s_good2`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:143
+assert_return(() => invoke($0, `8s_good3`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:144
+assert_return(() => invoke($0, `8s_good4`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:145
+assert_return(() => invoke($0, `8s_good5`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:147
+assert_return(() => invoke($0, `16u_good1`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:148
+assert_return(() => invoke($0, `16u_good2`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:149
+assert_return(() => invoke($0, `16u_good3`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:150
+assert_return(() => invoke($0, `16u_good4`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:151
+assert_return(() => invoke($0, `16u_good5`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:153
+assert_return(() => invoke($0, `16s_good1`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:154
+assert_return(() => invoke($0, `16s_good2`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:155
+assert_return(() => invoke($0, `16s_good3`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:156
+assert_return(() => invoke($0, `16s_good4`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:157
+assert_return(() => invoke($0, `16s_good5`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:159
+assert_return(() => invoke($0, `32_good1`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:160
+assert_return(() => invoke($0, `32_good2`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:161
+assert_return(() => invoke($0, `32_good3`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:162
+assert_return(() => invoke($0, `32_good4`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:163
+assert_return(() => invoke($0, `32_good5`, [65507]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:165
+assert_return(() => invoke($0, `8u_good1`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:166
+assert_return(() => invoke($0, `8u_good2`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:167
+assert_return(() => invoke($0, `8u_good3`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:168
+assert_return(() => invoke($0, `8u_good4`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:169
+assert_return(() => invoke($0, `8u_good5`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:171
+assert_return(() => invoke($0, `8s_good1`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:172
+assert_return(() => invoke($0, `8s_good2`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:173
+assert_return(() => invoke($0, `8s_good3`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:174
+assert_return(() => invoke($0, `8s_good4`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:175
+assert_return(() => invoke($0, `8s_good5`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:177
+assert_return(() => invoke($0, `16u_good1`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:178
+assert_return(() => invoke($0, `16u_good2`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:179
+assert_return(() => invoke($0, `16u_good3`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:180
+assert_return(() => invoke($0, `16u_good4`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:181
+assert_return(() => invoke($0, `16u_good5`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:183
+assert_return(() => invoke($0, `16s_good1`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:184
+assert_return(() => invoke($0, `16s_good2`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:185
+assert_return(() => invoke($0, `16s_good3`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:186
+assert_return(() => invoke($0, `16s_good4`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:187
+assert_return(() => invoke($0, `16s_good5`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:189
+assert_return(() => invoke($0, `32_good1`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:190
+assert_return(() => invoke($0, `32_good2`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:191
+assert_return(() => invoke($0, `32_good3`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:192
+assert_return(() => invoke($0, `32_good4`, [65508]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/address0.wast:193
+assert_trap(() => invoke($0, `32_good5`, [65508]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:195
+assert_trap(() => invoke($0, `8u_good3`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:196
+assert_trap(() => invoke($0, `8s_good3`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:197
+assert_trap(() => invoke($0, `16u_good3`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:198
+assert_trap(() => invoke($0, `16s_good3`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:199
+assert_trap(() => invoke($0, `32_good3`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:200
+assert_trap(() => invoke($0, `32_good3`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:202
+assert_trap(() => invoke($0, `8u_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:203
+assert_trap(() => invoke($0, `8s_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:204
+assert_trap(() => invoke($0, `16u_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:205
+assert_trap(() => invoke($0, `16s_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:206
+assert_trap(() => invoke($0, `32_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:208
+assert_trap(() => invoke($0, `8u_bad`, [1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:209
+assert_trap(() => invoke($0, `8s_bad`, [1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:210
+assert_trap(() => invoke($0, `16u_bad`, [1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:211
+assert_trap(() => invoke($0, `16s_bad`, [1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address0.wast:212
+assert_trap(() => invoke($0, `32_bad`, [1]), `out of bounds memory access`);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/address1.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/address1.wast.js
new file mode 100644
index 0000000000..602de2a5ce
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/address1.wast.js
@@ -0,0 +1,538 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/address1.wast
+
+// ./test/core/multi-memory/address1.wast:3
+let $0 = instantiate(`(module
+ (memory $$mem0 0)
+ (memory $$mem1 0)
+ (memory $$mem2 0)
+ (memory $$mem3 0)
+ (memory $$mem4 1)
+ (data (memory $$mem4) (i32.const 0) "abcdefghijklmnopqrstuvwxyz")
+
+ (func (export "8u_good1") (param $$i i32) (result i64)
+ (i64.load8_u $$mem4 offset=0 (local.get $$i)) ;; 97 'a'
+ )
+ (func (export "8u_good2") (param $$i i32) (result i64)
+ (i64.load8_u $$mem4 align=1 (local.get $$i)) ;; 97 'a'
+ )
+ (func (export "8u_good3") (param $$i i32) (result i64)
+ (i64.load8_u $$mem4 offset=1 align=1 (local.get $$i)) ;; 98 'b'
+ )
+ (func (export "8u_good4") (param $$i i32) (result i64)
+ (i64.load8_u $$mem4 offset=2 align=1 (local.get $$i)) ;; 99 'c'
+ )
+ (func (export "8u_good5") (param $$i i32) (result i64)
+ (i64.load8_u $$mem4 offset=25 align=1 (local.get $$i)) ;; 122 'z'
+ )
+
+ (func (export "8s_good1") (param $$i i32) (result i64)
+ (i64.load8_s $$mem4 offset=0 (local.get $$i)) ;; 97 'a'
+ )
+ (func (export "8s_good2") (param $$i i32) (result i64)
+ (i64.load8_s $$mem4 align=1 (local.get $$i)) ;; 97 'a'
+ )
+ (func (export "8s_good3") (param $$i i32) (result i64)
+ (i64.load8_s $$mem4 offset=1 align=1 (local.get $$i)) ;; 98 'b'
+ )
+ (func (export "8s_good4") (param $$i i32) (result i64)
+ (i64.load8_s $$mem4 offset=2 align=1 (local.get $$i)) ;; 99 'c'
+ )
+ (func (export "8s_good5") (param $$i i32) (result i64)
+ (i64.load8_s $$mem4 offset=25 align=1 (local.get $$i)) ;; 122 'z'
+ )
+
+ (func (export "16u_good1") (param $$i i32) (result i64)
+ (i64.load16_u $$mem4 offset=0 (local.get $$i)) ;; 25185 'ab'
+ )
+ (func (export "16u_good2") (param $$i i32) (result i64)
+ (i64.load16_u $$mem4 align=1 (local.get $$i)) ;; 25185 'ab'
+ )
+ (func (export "16u_good3") (param $$i i32) (result i64)
+ (i64.load16_u $$mem4 offset=1 align=1 (local.get $$i)) ;; 25442 'bc'
+ )
+ (func (export "16u_good4") (param $$i i32) (result i64)
+ (i64.load16_u $$mem4 offset=2 align=2 (local.get $$i)) ;; 25699 'cd'
+ )
+ (func (export "16u_good5") (param $$i i32) (result i64)
+ (i64.load16_u $$mem4 offset=25 align=2 (local.get $$i)) ;; 122 'z\\0'
+ )
+
+ (func (export "16s_good1") (param $$i i32) (result i64)
+ (i64.load16_s $$mem4 offset=0 (local.get $$i)) ;; 25185 'ab'
+ )
+ (func (export "16s_good2") (param $$i i32) (result i64)
+ (i64.load16_s $$mem4 align=1 (local.get $$i)) ;; 25185 'ab'
+ )
+ (func (export "16s_good3") (param $$i i32) (result i64)
+ (i64.load16_s $$mem4 offset=1 align=1 (local.get $$i)) ;; 25442 'bc'
+ )
+ (func (export "16s_good4") (param $$i i32) (result i64)
+ (i64.load16_s $$mem4 offset=2 align=2 (local.get $$i)) ;; 25699 'cd'
+ )
+ (func (export "16s_good5") (param $$i i32) (result i64)
+ (i64.load16_s $$mem4 offset=25 align=2 (local.get $$i)) ;; 122 'z\\0'
+ )
+
+ (func (export "32u_good1") (param $$i i32) (result i64)
+ (i64.load32_u $$mem4 offset=0 (local.get $$i)) ;; 1684234849 'abcd'
+ )
+ (func (export "32u_good2") (param $$i i32) (result i64)
+ (i64.load32_u $$mem4 align=1 (local.get $$i)) ;; 1684234849 'abcd'
+ )
+ (func (export "32u_good3") (param $$i i32) (result i64)
+ (i64.load32_u $$mem4 offset=1 align=1 (local.get $$i)) ;; 1701077858 'bcde'
+ )
+ (func (export "32u_good4") (param $$i i32) (result i64)
+ (i64.load32_u $$mem4 offset=2 align=2 (local.get $$i)) ;; 1717920867 'cdef'
+ )
+ (func (export "32u_good5") (param $$i i32) (result i64)
+ (i64.load32_u $$mem4 offset=25 align=4 (local.get $$i)) ;; 122 'z\\0\\0\\0'
+ )
+
+ (func (export "32s_good1") (param $$i i32) (result i64)
+ (i64.load32_s $$mem4 offset=0 (local.get $$i)) ;; 1684234849 'abcd'
+ )
+ (func (export "32s_good2") (param $$i i32) (result i64)
+ (i64.load32_s $$mem4 align=1 (local.get $$i)) ;; 1684234849 'abcd'
+ )
+ (func (export "32s_good3") (param $$i i32) (result i64)
+ (i64.load32_s $$mem4 offset=1 align=1 (local.get $$i)) ;; 1701077858 'bcde'
+ )
+ (func (export "32s_good4") (param $$i i32) (result i64)
+ (i64.load32_s $$mem4 offset=2 align=2 (local.get $$i)) ;; 1717920867 'cdef'
+ )
+ (func (export "32s_good5") (param $$i i32) (result i64)
+ (i64.load32_s $$mem4 offset=25 align=4 (local.get $$i)) ;; 122 'z\\0\\0\\0'
+ )
+
+ (func (export "64_good1") (param $$i i32) (result i64)
+ (i64.load $$mem4 offset=0 (local.get $$i)) ;; 0x6867666564636261 'abcdefgh'
+ )
+ (func (export "64_good2") (param $$i i32) (result i64)
+ (i64.load $$mem4 align=1 (local.get $$i)) ;; 0x6867666564636261 'abcdefgh'
+ )
+ (func (export "64_good3") (param $$i i32) (result i64)
+ (i64.load $$mem4 offset=1 align=1 (local.get $$i)) ;; 0x6968676665646362 'bcdefghi'
+ )
+ (func (export "64_good4") (param $$i i32) (result i64)
+ (i64.load $$mem4 offset=2 align=2 (local.get $$i)) ;; 0x6a69686766656463 'cdefghij'
+ )
+ (func (export "64_good5") (param $$i i32) (result i64)
+ (i64.load $$mem4 offset=25 align=8 (local.get $$i)) ;; 122 'z\\0\\0\\0\\0\\0\\0\\0'
+ )
+
+ (func (export "8u_bad") (param $$i i32)
+ (drop (i64.load8_u $$mem4 offset=4294967295 (local.get $$i)))
+ )
+ (func (export "8s_bad") (param $$i i32)
+ (drop (i64.load8_s $$mem4 offset=4294967295 (local.get $$i)))
+ )
+ (func (export "16u_bad") (param $$i i32)
+ (drop (i64.load16_u $$mem4 offset=4294967295 (local.get $$i)))
+ )
+ (func (export "16s_bad") (param $$i i32)
+ (drop (i64.load16_s $$mem4 offset=4294967295 (local.get $$i)))
+ )
+ (func (export "32u_bad") (param $$i i32)
+ (drop (i64.load32_u $$mem4 offset=4294967295 (local.get $$i)))
+ )
+ (func (export "32s_bad") (param $$i i32)
+ (drop (i64.load32_s $$mem4 offset=4294967295 (local.get $$i)))
+ )
+ (func (export "64_bad") (param $$i i32)
+ (drop (i64.load $$mem4 offset=4294967295 (local.get $$i)))
+ )
+)`);
+
+// ./test/core/multi-memory/address1.wast:146
+assert_return(() => invoke($0, `8u_good1`, [0]), [value("i64", 97n)]);
+
+// ./test/core/multi-memory/address1.wast:147
+assert_return(() => invoke($0, `8u_good2`, [0]), [value("i64", 97n)]);
+
+// ./test/core/multi-memory/address1.wast:148
+assert_return(() => invoke($0, `8u_good3`, [0]), [value("i64", 98n)]);
+
+// ./test/core/multi-memory/address1.wast:149
+assert_return(() => invoke($0, `8u_good4`, [0]), [value("i64", 99n)]);
+
+// ./test/core/multi-memory/address1.wast:150
+assert_return(() => invoke($0, `8u_good5`, [0]), [value("i64", 122n)]);
+
+// ./test/core/multi-memory/address1.wast:152
+assert_return(() => invoke($0, `8s_good1`, [0]), [value("i64", 97n)]);
+
+// ./test/core/multi-memory/address1.wast:153
+assert_return(() => invoke($0, `8s_good2`, [0]), [value("i64", 97n)]);
+
+// ./test/core/multi-memory/address1.wast:154
+assert_return(() => invoke($0, `8s_good3`, [0]), [value("i64", 98n)]);
+
+// ./test/core/multi-memory/address1.wast:155
+assert_return(() => invoke($0, `8s_good4`, [0]), [value("i64", 99n)]);
+
+// ./test/core/multi-memory/address1.wast:156
+assert_return(() => invoke($0, `8s_good5`, [0]), [value("i64", 122n)]);
+
+// ./test/core/multi-memory/address1.wast:158
+assert_return(() => invoke($0, `16u_good1`, [0]), [value("i64", 25185n)]);
+
+// ./test/core/multi-memory/address1.wast:159
+assert_return(() => invoke($0, `16u_good2`, [0]), [value("i64", 25185n)]);
+
+// ./test/core/multi-memory/address1.wast:160
+assert_return(() => invoke($0, `16u_good3`, [0]), [value("i64", 25442n)]);
+
+// ./test/core/multi-memory/address1.wast:161
+assert_return(() => invoke($0, `16u_good4`, [0]), [value("i64", 25699n)]);
+
+// ./test/core/multi-memory/address1.wast:162
+assert_return(() => invoke($0, `16u_good5`, [0]), [value("i64", 122n)]);
+
+// ./test/core/multi-memory/address1.wast:164
+assert_return(() => invoke($0, `16s_good1`, [0]), [value("i64", 25185n)]);
+
+// ./test/core/multi-memory/address1.wast:165
+assert_return(() => invoke($0, `16s_good2`, [0]), [value("i64", 25185n)]);
+
+// ./test/core/multi-memory/address1.wast:166
+assert_return(() => invoke($0, `16s_good3`, [0]), [value("i64", 25442n)]);
+
+// ./test/core/multi-memory/address1.wast:167
+assert_return(() => invoke($0, `16s_good4`, [0]), [value("i64", 25699n)]);
+
+// ./test/core/multi-memory/address1.wast:168
+assert_return(() => invoke($0, `16s_good5`, [0]), [value("i64", 122n)]);
+
+// ./test/core/multi-memory/address1.wast:170
+assert_return(() => invoke($0, `32u_good1`, [0]), [value("i64", 1684234849n)]);
+
+// ./test/core/multi-memory/address1.wast:171
+assert_return(() => invoke($0, `32u_good2`, [0]), [value("i64", 1684234849n)]);
+
+// ./test/core/multi-memory/address1.wast:172
+assert_return(() => invoke($0, `32u_good3`, [0]), [value("i64", 1701077858n)]);
+
+// ./test/core/multi-memory/address1.wast:173
+assert_return(() => invoke($0, `32u_good4`, [0]), [value("i64", 1717920867n)]);
+
+// ./test/core/multi-memory/address1.wast:174
+assert_return(() => invoke($0, `32u_good5`, [0]), [value("i64", 122n)]);
+
+// ./test/core/multi-memory/address1.wast:176
+assert_return(() => invoke($0, `32s_good1`, [0]), [value("i64", 1684234849n)]);
+
+// ./test/core/multi-memory/address1.wast:177
+assert_return(() => invoke($0, `32s_good2`, [0]), [value("i64", 1684234849n)]);
+
+// ./test/core/multi-memory/address1.wast:178
+assert_return(() => invoke($0, `32s_good3`, [0]), [value("i64", 1701077858n)]);
+
+// ./test/core/multi-memory/address1.wast:179
+assert_return(() => invoke($0, `32s_good4`, [0]), [value("i64", 1717920867n)]);
+
+// ./test/core/multi-memory/address1.wast:180
+assert_return(() => invoke($0, `32s_good5`, [0]), [value("i64", 122n)]);
+
+// ./test/core/multi-memory/address1.wast:182
+assert_return(() => invoke($0, `64_good1`, [0]), [value("i64", 7523094288207667809n)]);
+
+// ./test/core/multi-memory/address1.wast:183
+assert_return(() => invoke($0, `64_good2`, [0]), [value("i64", 7523094288207667809n)]);
+
+// ./test/core/multi-memory/address1.wast:184
+assert_return(() => invoke($0, `64_good3`, [0]), [value("i64", 7595434461045744482n)]);
+
+// ./test/core/multi-memory/address1.wast:185
+assert_return(() => invoke($0, `64_good4`, [0]), [value("i64", 7667774633883821155n)]);
+
+// ./test/core/multi-memory/address1.wast:186
+assert_return(() => invoke($0, `64_good5`, [0]), [value("i64", 122n)]);
+
+// ./test/core/multi-memory/address1.wast:188
+assert_return(() => invoke($0, `8u_good1`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:189
+assert_return(() => invoke($0, `8u_good2`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:190
+assert_return(() => invoke($0, `8u_good3`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:191
+assert_return(() => invoke($0, `8u_good4`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:192
+assert_return(() => invoke($0, `8u_good5`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:194
+assert_return(() => invoke($0, `8s_good1`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:195
+assert_return(() => invoke($0, `8s_good2`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:196
+assert_return(() => invoke($0, `8s_good3`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:197
+assert_return(() => invoke($0, `8s_good4`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:198
+assert_return(() => invoke($0, `8s_good5`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:200
+assert_return(() => invoke($0, `16u_good1`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:201
+assert_return(() => invoke($0, `16u_good2`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:202
+assert_return(() => invoke($0, `16u_good3`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:203
+assert_return(() => invoke($0, `16u_good4`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:204
+assert_return(() => invoke($0, `16u_good5`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:206
+assert_return(() => invoke($0, `16s_good1`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:207
+assert_return(() => invoke($0, `16s_good2`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:208
+assert_return(() => invoke($0, `16s_good3`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:209
+assert_return(() => invoke($0, `16s_good4`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:210
+assert_return(() => invoke($0, `16s_good5`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:212
+assert_return(() => invoke($0, `32u_good1`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:213
+assert_return(() => invoke($0, `32u_good2`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:214
+assert_return(() => invoke($0, `32u_good3`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:215
+assert_return(() => invoke($0, `32u_good4`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:216
+assert_return(() => invoke($0, `32u_good5`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:218
+assert_return(() => invoke($0, `32s_good1`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:219
+assert_return(() => invoke($0, `32s_good2`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:220
+assert_return(() => invoke($0, `32s_good3`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:221
+assert_return(() => invoke($0, `32s_good4`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:222
+assert_return(() => invoke($0, `32s_good5`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:224
+assert_return(() => invoke($0, `64_good1`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:225
+assert_return(() => invoke($0, `64_good2`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:226
+assert_return(() => invoke($0, `64_good3`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:227
+assert_return(() => invoke($0, `64_good4`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:228
+assert_return(() => invoke($0, `64_good5`, [65503]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:230
+assert_return(() => invoke($0, `8u_good1`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:231
+assert_return(() => invoke($0, `8u_good2`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:232
+assert_return(() => invoke($0, `8u_good3`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:233
+assert_return(() => invoke($0, `8u_good4`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:234
+assert_return(() => invoke($0, `8u_good5`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:236
+assert_return(() => invoke($0, `8s_good1`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:237
+assert_return(() => invoke($0, `8s_good2`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:238
+assert_return(() => invoke($0, `8s_good3`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:239
+assert_return(() => invoke($0, `8s_good4`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:240
+assert_return(() => invoke($0, `8s_good5`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:242
+assert_return(() => invoke($0, `16u_good1`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:243
+assert_return(() => invoke($0, `16u_good2`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:244
+assert_return(() => invoke($0, `16u_good3`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:245
+assert_return(() => invoke($0, `16u_good4`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:246
+assert_return(() => invoke($0, `16u_good5`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:248
+assert_return(() => invoke($0, `16s_good1`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:249
+assert_return(() => invoke($0, `16s_good2`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:250
+assert_return(() => invoke($0, `16s_good3`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:251
+assert_return(() => invoke($0, `16s_good4`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:252
+assert_return(() => invoke($0, `16s_good5`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:254
+assert_return(() => invoke($0, `32u_good1`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:255
+assert_return(() => invoke($0, `32u_good2`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:256
+assert_return(() => invoke($0, `32u_good3`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:257
+assert_return(() => invoke($0, `32u_good4`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:258
+assert_return(() => invoke($0, `32u_good5`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:260
+assert_return(() => invoke($0, `32s_good1`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:261
+assert_return(() => invoke($0, `32s_good2`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:262
+assert_return(() => invoke($0, `32s_good3`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:263
+assert_return(() => invoke($0, `32s_good4`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:264
+assert_return(() => invoke($0, `32s_good5`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:266
+assert_return(() => invoke($0, `64_good1`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:267
+assert_return(() => invoke($0, `64_good2`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:268
+assert_return(() => invoke($0, `64_good3`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:269
+assert_return(() => invoke($0, `64_good4`, [65504]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/address1.wast:270
+assert_trap(() => invoke($0, `64_good5`, [65504]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:272
+assert_trap(() => invoke($0, `8u_good3`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:273
+assert_trap(() => invoke($0, `8s_good3`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:274
+assert_trap(() => invoke($0, `16u_good3`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:275
+assert_trap(() => invoke($0, `16s_good3`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:276
+assert_trap(() => invoke($0, `32u_good3`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:277
+assert_trap(() => invoke($0, `32s_good3`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:278
+assert_trap(() => invoke($0, `64_good3`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:280
+assert_trap(() => invoke($0, `8u_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:281
+assert_trap(() => invoke($0, `8s_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:282
+assert_trap(() => invoke($0, `16u_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:283
+assert_trap(() => invoke($0, `16s_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:284
+assert_trap(() => invoke($0, `32u_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:285
+assert_trap(() => invoke($0, `32s_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:286
+assert_trap(() => invoke($0, `64_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:288
+assert_trap(() => invoke($0, `8u_bad`, [1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:289
+assert_trap(() => invoke($0, `8s_bad`, [1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:290
+assert_trap(() => invoke($0, `16u_bad`, [1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:291
+assert_trap(() => invoke($0, `16s_bad`, [1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:292
+assert_trap(() => invoke($0, `32u_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:293
+assert_trap(() => invoke($0, `32s_bad`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/address1.wast:294
+assert_trap(() => invoke($0, `64_bad`, [1]), `out of bounds memory access`);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/align0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/align0.wast.js
new file mode 100644
index 0000000000..bafbd476e2
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/align0.wast.js
@@ -0,0 +1,65 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/align0.wast
+
+// ./test/core/multi-memory/align0.wast:3
+let $0 = instantiate(`(module
+ (memory $$mem0 0)
+ (memory $$mem1 1)
+ (memory $$mem2 0)
+
+ ;; $$default: natural alignment, $$1: align=1, $$2: align=2, $$4: align=4, $$8: align=8
+
+ (func (export "f32_align_switch") (param i32) (result f32)
+ (local f32 f32)
+ (local.set 1 (f32.const 10.0))
+ (block $$4
+ (block $$2
+ (block $$1
+ (block $$default
+ (block $$0
+ (br_table $$0 $$default $$1 $$2 $$4 (local.get 0))
+ ) ;; 0
+ (f32.store $$mem1 (i32.const 0) (local.get 1))
+ (local.set 2 (f32.load $$mem1 (i32.const 0)))
+ (br $$4)
+ ) ;; default
+ (f32.store $$mem1 align=1 (i32.const 0) (local.get 1))
+ (local.set 2 (f32.load $$mem1 align=1 (i32.const 0)))
+ (br $$4)
+ ) ;; 1
+ (f32.store $$mem1 align=2 (i32.const 0) (local.get 1))
+ (local.set 2 (f32.load $$mem1 align=2 (i32.const 0)))
+ (br $$4)
+ ) ;; 2
+ (f32.store $$mem1 align=4 (i32.const 0) (local.get 1))
+ (local.set 2 (f32.load $$mem1 align=4 (i32.const 0)))
+ ) ;; 4
+ (local.get 2)
+ )
+)`);
+
+// ./test/core/multi-memory/align0.wast:39
+assert_return(() => invoke($0, `f32_align_switch`, [0]), [value("f32", 10)]);
+
+// ./test/core/multi-memory/align0.wast:40
+assert_return(() => invoke($0, `f32_align_switch`, [1]), [value("f32", 10)]);
+
+// ./test/core/multi-memory/align0.wast:41
+assert_return(() => invoke($0, `f32_align_switch`, [2]), [value("f32", 10)]);
+
+// ./test/core/multi-memory/align0.wast:42
+assert_return(() => invoke($0, `f32_align_switch`, [3]), [value("f32", 10)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/binary0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/binary0.wast.js
new file mode 100644
index 0000000000..db6f0bd879
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/binary0.wast.js
@@ -0,0 +1,88 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/binary0.wast
+
+// ./test/core/multi-memory/binary0.wast:2
+let $0 = instantiate(`(module binary
+ "\\00asm" "\\01\\00\\00\\00"
+ "\\05\\07\\02" ;; Memory section with 2 entries
+ "\\00\\82\\00" ;; no max, minimum 2
+ "\\00\\82\\00" ;; no max, minimum 2
+)`);
+
+// ./test/core/multi-memory/binary0.wast:8
+let $1 = instantiate(`(module binary
+ "\\00asm" "\\01\\00\\00\\00"
+ "\\05\\13\\03" ;; Memory section with 3 entries
+ "\\00\\83\\80\\80\\80\\00" ;; no max, minimum 3
+ "\\00\\84\\80\\80\\80\\00" ;; no max, minimum 4
+ "\\00\\85\\80\\80\\80\\00" ;; no max, minimum 5
+)`);
+
+// ./test/core/multi-memory/binary0.wast:16
+let $2 = instantiate(`(module binary
+ "\\00asm" "\\01\\00\\00\\00"
+ "\\05\\05\\02" ;; Memory section with 2 entries
+ "\\00\\00" ;; no max, minimum 0
+ "\\00\\00" ;; no max, minimum 0
+ "\\0b\\06\\01" ;; Data section with 1 entry
+ "\\00" ;; Memory index 0
+ "\\41\\00\\0b\\00" ;; (i32.const 0) with contents ""
+)`);
+
+// ./test/core/multi-memory/binary0.wast:26
+let $3 = instantiate(`(module binary
+ "\\00asm" "\\01\\00\\00\\00"
+ "\\05\\05\\02" ;; Memory section with 2 entries
+ "\\00\\00" ;; no max, minimum 0
+ "\\00\\01" ;; no max, minimum 1
+ "\\0b\\07\\01" ;; Data section with 1 entry
+ "\\02\\01" ;; Memory index 1
+ "\\41\\00\\0b\\00" ;; (i32.const 0) with contents ""
+)`);
+
+// ./test/core/multi-memory/binary0.wast:36
+let $4 = instantiate(`(module binary
+ "\\00asm" "\\01\\00\\00\\00"
+ "\\05\\05\\02" ;; Memory section with 2 entries
+ "\\00\\00" ;; no max, minimum 0
+ "\\00\\01" ;; no max, minimum 1
+ "\\0b\\0a\\01" ;; Data section with 1 entry
+ "\\02\\81\\80\\80\\00" ;; Memory index 1
+ "\\41\\00\\0b\\00" ;; (i32.const 0) with contents ""
+)`);
+
+// ./test/core/multi-memory/binary0.wast:47
+assert_malformed(
+ () => instantiate(`(module binary
+ "\\00asm" "\\01\\00\\00\\00"
+ "\\05\\0a\\02" ;; Memory section with 2 entries
+ "\\00\\01" ;; no max, minimum 1
+ "\\00\\82\\80\\80\\80\\80\\00" ;; no max, minimum 2 with one byte too many
+ )`),
+ `integer representation too long`,
+);
+
+// ./test/core/multi-memory/binary0.wast:58
+assert_malformed(
+ () => instantiate(`(module binary
+ "\\00asm" "\\01\\00\\00\\00"
+ "\\05\\03\\02" ;; memory section with inconsistent count (1 declared, 0 given)
+ "\\00\\00" ;; memory 0 (missed)
+ ;; "\\00\\00" ;; memory 1 (missing)
+ )`),
+ `unexpected end of section or function`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/data0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/data0.wast.js
new file mode 100644
index 0000000000..5fa85e426c
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/data0.wast.js
@@ -0,0 +1,93 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/data0.wast
+
+// ./test/core/multi-memory/data0.wast:5
+let $0 = instantiate(`(module
+ (memory $$mem0 1)
+ (memory $$mem1 1)
+ (memory $$mem2 1)
+
+ (data (i32.const 0))
+ (data (i32.const 1) "a" "" "bcd")
+ (data (offset (i32.const 0)))
+ (data (offset (i32.const 0)) "" "a" "bc" "")
+ (data (memory 0) (i32.const 0))
+ (data (memory 0x0) (i32.const 1) "a" "" "bcd")
+ (data (memory 0x000) (offset (i32.const 0)))
+ (data (memory 0) (offset (i32.const 0)) "" "a" "bc" "")
+ (data (memory $$mem0) (i32.const 0))
+ (data (memory $$mem1) (i32.const 1) "a" "" "bcd")
+ (data (memory $$mem2) (offset (i32.const 0)))
+ (data (memory $$mem0) (offset (i32.const 0)) "" "a" "bc" "")
+
+ (data $$d1 (i32.const 0))
+ (data $$d2 (i32.const 1) "a" "" "bcd")
+ (data $$d3 (offset (i32.const 0)))
+ (data $$d4 (offset (i32.const 0)) "" "a" "bc" "")
+ (data $$d5 (memory 0) (i32.const 0))
+ (data $$d6 (memory 0x0) (i32.const 1) "a" "" "bcd")
+ (data $$d7 (memory 0x000) (offset (i32.const 0)))
+ (data $$d8 (memory 0) (offset (i32.const 0)) "" "a" "bc" "")
+ (data $$d9 (memory $$mem0) (i32.const 0))
+ (data $$d10 (memory $$mem1) (i32.const 1) "a" "" "bcd")
+ (data $$d11 (memory $$mem2) (offset (i32.const 0)))
+ (data $$d12 (memory $$mem0) (offset (i32.const 0)) "" "a" "bc" "")
+)`);
+
+// ./test/core/multi-memory/data0.wast:39
+let $1 = instantiate(`(module
+ (memory 1)
+ (data (i32.const 0) "a")
+)`);
+
+// ./test/core/multi-memory/data0.wast:43
+let $2 = instantiate(`(module
+ (import "spectest" "memory" (memory 1))
+ (import "spectest" "memory" (memory 1))
+ (import "spectest" "memory" (memory 1))
+ (data (memory 0) (i32.const 0) "a")
+ (data (memory 1) (i32.const 0) "a")
+ (data (memory 2) (i32.const 0) "a")
+)`);
+
+// ./test/core/multi-memory/data0.wast:52
+let $3 = instantiate(`(module
+ (global (import "spectest" "global_i32") i32)
+ (memory 1)
+ (data (global.get 0) "a")
+)`);
+
+// ./test/core/multi-memory/data0.wast:57
+let $4 = instantiate(`(module
+ (global (import "spectest" "global_i32") i32)
+ (import "spectest" "memory" (memory 1))
+ (data (global.get 0) "a")
+)`);
+
+// ./test/core/multi-memory/data0.wast:63
+let $5 = instantiate(`(module
+ (global $$g (import "spectest" "global_i32") i32)
+ (memory 1)
+ (data (global.get $$g) "a")
+)`);
+
+// ./test/core/multi-memory/data0.wast:68
+let $6 = instantiate(`(module
+ (global $$g (import "spectest" "global_i32") i32)
+ (import "spectest" "memory" (memory 1))
+ (data (global.get $$g) "a")
+)`);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/data1.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/data1.wast.js
new file mode 100644
index 0000000000..953cc7c729
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/data1.wast.js
@@ -0,0 +1,170 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/data1.wast
+
+// ./test/core/multi-memory/data1.wast:3
+assert_trap(
+ () => instantiate(`(module
+ (memory 1)
+ (memory 0)
+ (memory 2)
+ (data (memory 1) (i32.const 0) "a")
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/data1.wast:13
+assert_trap(
+ () => instantiate(`(module
+ (memory 1 1)
+ (memory 1 1)
+ (memory 0 0)
+ (data (memory 2) (i32.const 0) "a")
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/data1.wast:23
+assert_trap(
+ () => instantiate(`(module
+ (memory 1 1)
+ (memory 0 1)
+ (memory 1 1)
+ (data (memory 1) (i32.const 0) "a")
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/data1.wast:32
+assert_trap(
+ () => instantiate(`(module
+ (memory 1)
+ (memory 1)
+ (memory 0)
+ (data (memory 2) (i32.const 1))
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/data1.wast:41
+assert_trap(
+ () => instantiate(`(module
+ (memory 1 1)
+ (memory 1 1)
+ (memory 0 1)
+ (data (memory 2) (i32.const 1))
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/data1.wast:60
+assert_trap(
+ () => instantiate(`(module
+ (global (import "spectest" "global_i32") i32)
+ (memory 3)
+ (memory 0)
+ (memory 3)
+ (data (memory 1) (global.get 0) "a")
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/data1.wast:71
+assert_trap(
+ () => instantiate(`(module
+ (memory 2 2)
+ (memory 1 2)
+ (memory 2 2)
+ (data (memory 1) (i32.const 0x1_0000) "a")
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/data1.wast:80
+assert_trap(
+ () => instantiate(`(module
+ (import "spectest" "memory" (memory 1))
+ (data (i32.const 0x1_0000) "a")
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/data1.wast:88
+assert_trap(
+ () => instantiate(`(module
+ (memory 3)
+ (memory 3)
+ (memory 2)
+ (data (memory 2) (i32.const 0x2_0000) "a")
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/data1.wast:98
+assert_trap(
+ () => instantiate(`(module
+ (memory 3 3)
+ (memory 2 3)
+ (memory 3 3)
+ (data (memory 1) (i32.const 0x2_0000) "a")
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/data1.wast:108
+assert_trap(
+ () => instantiate(`(module
+ (memory 0)
+ (memory 0)
+ (memory 1)
+ (data (memory 2) (i32.const -1) "a")
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/data1.wast:117
+assert_trap(
+ () => instantiate(`(module
+ (import "spectest" "memory" (memory 1))
+ (import "spectest" "memory" (memory 1))
+ (import "spectest" "memory" (memory 1))
+ (data (memory 2) (i32.const -1) "a")
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/data1.wast:127
+assert_trap(
+ () => instantiate(`(module
+ (memory 2)
+ (memory 2)
+ (memory 2)
+ (data (memory 2) (i32.const -100) "a")
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/data1.wast:136
+assert_trap(
+ () => instantiate(`(module
+ (import "spectest" "memory" (memory 1))
+ (import "spectest" "memory" (memory 1))
+ (import "spectest" "memory" (memory 1))
+ (import "spectest" "memory" (memory 1))
+ (data (memory 3) (i32.const -100) "a")
+ )`),
+ `out of bounds memory access`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/data_drop0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/data_drop0.wast.js
new file mode 100644
index 0000000000..7e0b28f4ac
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/data_drop0.wast.js
@@ -0,0 +1,63 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/data_drop0.wast
+
+// ./test/core/multi-memory/data_drop0.wast:2
+let $0 = instantiate(`(module
+ (memory $$mem0 0)
+ (memory $$mem1 1)
+ (memory $$mem2 0)
+ (data $$p "x")
+ (data $$a (memory 1) (i32.const 0) "x")
+
+ (func (export "drop_passive") (data.drop $$p))
+ (func (export "init_passive") (param $$len i32)
+ (memory.init $$mem1 $$p (i32.const 0) (i32.const 0) (local.get $$len)))
+
+ (func (export "drop_active") (data.drop $$a))
+ (func (export "init_active") (param $$len i32)
+ (memory.init $$mem1 $$a (i32.const 0) (i32.const 0) (local.get $$len)))
+)`);
+
+// ./test/core/multi-memory/data_drop0.wast:18
+invoke($0, `init_passive`, [1]);
+
+// ./test/core/multi-memory/data_drop0.wast:19
+invoke($0, `drop_passive`, []);
+
+// ./test/core/multi-memory/data_drop0.wast:20
+invoke($0, `drop_passive`, []);
+
+// ./test/core/multi-memory/data_drop0.wast:21
+assert_return(() => invoke($0, `init_passive`, [0]), []);
+
+// ./test/core/multi-memory/data_drop0.wast:22
+assert_trap(() => invoke($0, `init_passive`, [1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/data_drop0.wast:23
+invoke($0, `init_passive`, [0]);
+
+// ./test/core/multi-memory/data_drop0.wast:24
+invoke($0, `drop_active`, []);
+
+// ./test/core/multi-memory/data_drop0.wast:25
+assert_return(() => invoke($0, `init_active`, [0]), []);
+
+// ./test/core/multi-memory/data_drop0.wast:26
+assert_trap(() => invoke($0, `init_active`, [1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/data_drop0.wast:27
+invoke($0, `init_active`, [0]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/directives.txt b/js/src/jit-test/tests/wasm/spec/multi-memory/directives.txt
new file mode 100644
index 0000000000..9211583549
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/directives.txt
@@ -0,0 +1 @@
+|jit-test| test-also=--wasm-compiler=optimizing; test-also=--wasm-compiler=baseline; test-also=--wasm-test-serialization; test-also=--test-wasm-await-tier2; test-also=--disable-wasm-huge-memory; skip-variant-if: --disable-wasm-huge-memory, !wasmHugeMemorySupported(); local-include:harness/harness.js; --wasm-multi-memory; skip-if: !wasmMultiMemoryEnabled() \ No newline at end of file
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/exports0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/exports0.wast.js
new file mode 100644
index 0000000000..2d94a23440
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/exports0.wast.js
@@ -0,0 +1,78 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/exports0.wast
+
+// ./test/core/multi-memory/exports0.wast:3
+let $0 = instantiate(`(module (memory 0) (export "a" (memory 0)))`);
+
+// ./test/core/multi-memory/exports0.wast:4
+let $1 = instantiate(`(module (memory 0) (export "a" (memory 0)) (export "b" (memory 0)))`);
+
+// ./test/core/multi-memory/exports0.wast:5
+let $2 = instantiate(`(module (memory 0) (memory 0) (export "a" (memory 0)) (export "b" (memory 1)))`);
+
+// ./test/core/multi-memory/exports0.wast:6
+let $3 = instantiate(`(module
+ (memory $$mem0 0)
+ (memory $$mem1 0)
+ (memory $$mem2 0)
+ (memory $$mem3 0)
+ (memory $$mem4 0)
+ (memory $$mem5 0)
+ (memory $$mem6 0)
+
+ (export "a" (memory $$mem0))
+ (export "b" (memory $$mem1))
+ (export "ac" (memory $$mem2))
+ (export "bc" (memory $$mem3))
+ (export "ad" (memory $$mem4))
+ (export "bd" (memory $$mem5))
+ (export "be" (memory $$mem6))
+
+ (export "za" (memory $$mem0))
+ (export "zb" (memory $$mem1))
+ (export "zac" (memory $$mem2))
+ (export "zbc" (memory $$mem3))
+ (export "zad" (memory $$mem4))
+ (export "zbd" (memory $$mem5))
+ (export "zbe" (memory $$mem6))
+)`);
+
+// ./test/core/multi-memory/exports0.wast:32
+let $4 = instantiate(`(module
+ (export "a" (memory 0))
+ (memory 6)
+
+ (export "b" (memory 1))
+ (memory 3)
+)`);
+
+// ./test/core/multi-memory/exports0.wast:40
+let $5 = instantiate(`(module
+ (export "a" (memory 0))
+ (memory 0 1)
+ (memory 0 1)
+ (memory 0 1)
+ (memory 0 1)
+
+ (export "b" (memory 3))
+)`);
+
+// ./test/core/multi-memory/exports0.wast:49
+let $6 = instantiate(`(module (export "a" (memory $$a)) (memory $$a 0))`);
+
+// ./test/core/multi-memory/exports0.wast:50
+let $7 = instantiate(`(module (export "a" (memory $$a)) (memory $$a 0 1))`);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/float_exprs0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/float_exprs0.wast.js
new file mode 100644
index 0000000000..fe1c12a5ee
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/float_exprs0.wast.js
@@ -0,0 +1,80 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/float_exprs0.wast
+
+// ./test/core/multi-memory/float_exprs0.wast:1
+let $0 = instantiate(`(module
+ (memory 0 0)
+ (memory $$m 1 1)
+ (memory 0 0)
+ (func (export "init") (param $$i i32) (param $$x f64)
+ (f64.store $$m (local.get $$i) (local.get $$x)))
+
+ (func (export "run") (param $$n i32) (param $$z f64)
+ (local $$i i32)
+ (block $$exit
+ (loop $$cont
+ (f64.store $$m
+ (local.get $$i)
+ (f64.div (f64.load $$m (local.get $$i)) (local.get $$z))
+ )
+ (local.set $$i (i32.add (local.get $$i) (i32.const 8)))
+ (br_if $$cont (i32.lt_u (local.get $$i) (local.get $$n)))
+ )
+ )
+ )
+
+ (func (export "check") (param $$i i32) (result f64) (f64.load $$m (local.get $$i)))
+)`);
+
+// ./test/core/multi-memory/float_exprs0.wast:25
+invoke($0, `init`, [0, value("f64", 15.1)]);
+
+// ./test/core/multi-memory/float_exprs0.wast:26
+invoke($0, `init`, [8, value("f64", 15.2)]);
+
+// ./test/core/multi-memory/float_exprs0.wast:27
+invoke($0, `init`, [16, value("f64", 15.3)]);
+
+// ./test/core/multi-memory/float_exprs0.wast:28
+invoke($0, `init`, [24, value("f64", 15.4)]);
+
+// ./test/core/multi-memory/float_exprs0.wast:29
+assert_return(() => invoke($0, `check`, [0]), [value("f64", 15.1)]);
+
+// ./test/core/multi-memory/float_exprs0.wast:30
+assert_return(() => invoke($0, `check`, [8]), [value("f64", 15.2)]);
+
+// ./test/core/multi-memory/float_exprs0.wast:31
+assert_return(() => invoke($0, `check`, [16]), [value("f64", 15.3)]);
+
+// ./test/core/multi-memory/float_exprs0.wast:32
+assert_return(() => invoke($0, `check`, [24]), [value("f64", 15.4)]);
+
+// ./test/core/multi-memory/float_exprs0.wast:33
+invoke($0, `run`, [32, value("f64", 3)]);
+
+// ./test/core/multi-memory/float_exprs0.wast:34
+assert_return(() => invoke($0, `check`, [0]), [value("f64", 5.033333333333333)]);
+
+// ./test/core/multi-memory/float_exprs0.wast:35
+assert_return(() => invoke($0, `check`, [8]), [value("f64", 5.066666666666666)]);
+
+// ./test/core/multi-memory/float_exprs0.wast:36
+assert_return(() => invoke($0, `check`, [16]), [value("f64", 5.1000000000000005)]);
+
+// ./test/core/multi-memory/float_exprs0.wast:37
+assert_return(() => invoke($0, `check`, [24]), [value("f64", 5.133333333333334)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/float_exprs1.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/float_exprs1.wast.js
new file mode 100644
index 0000000000..3f7c1052fa
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/float_exprs1.wast.js
@@ -0,0 +1,128 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/float_exprs1.wast
+
+// ./test/core/multi-memory/float_exprs1.wast:4
+let $0 = instantiate(`(module
+ (memory 0 0)
+ (memory 0 0)
+ (memory 0 0)
+ (memory 0 0)
+ (memory 0 0)
+ (memory $$m (data
+ "\\c4\\c5\\57\\24\\a5\\84\\c8\\0b\\6d\\b8\\4b\\2e\\f2\\76\\17\\1c\\ca\\4a\\56\\1e\\1b\\6e\\71\\22"
+ "\\5d\\17\\1e\\6e\\bf\\cd\\14\\5c\\c7\\21\\55\\51\\39\\9c\\1f\\b2\\51\\f0\\a3\\93\\d7\\c1\\2c\\ae"
+ "\\7e\\a8\\28\\3a\\01\\21\\f4\\0a\\58\\93\\f8\\42\\77\\9f\\83\\39\\6a\\5f\\ba\\f7\\0a\\d8\\51\\6a"
+ "\\34\\ca\\ad\\c6\\34\\0e\\d8\\26\\dc\\4c\\33\\1c\\ed\\29\\90\\a8\\78\\0f\\d1\\ce\\76\\31\\23\\83"
+ "\\b8\\35\\e8\\f2\\44\\b0\\d3\\a1\\fc\\bb\\32\\e1\\b0\\ba\\69\\44\\09\\d6\\d9\\7d\\ff\\2e\\c0\\5a"
+ "\\36\\14\\33\\14\\3e\\a9\\fa\\87\\6d\\8b\\bc\\ce\\9d\\a7\\fd\\c4\\e9\\85\\3f\\dd\\d7\\e1\\18\\a6"
+ "\\50\\26\\72\\6e\\3f\\73\\0f\\f8\\12\\93\\23\\34\\61\\76\\12\\48\\c0\\9b\\05\\93\\eb\\ac\\86\\de"
+ "\\94\\3e\\55\\e8\\8c\\e8\\dd\\e4\\fc\\95\\47\\be\\56\\03\\21\\20\\4c\\e6\\bf\\7b\\f6\\7f\\d5\\ba"
+ "\\73\\1c\\c1\\14\\8f\\c4\\27\\96\\b3\\bd\\33\\ff\\78\\41\\5f\\c0\\5a\\ce\\f6\\67\\6e\\73\\9a\\17"
+ "\\66\\70\\03\\f8\\ce\\27\\a3\\52\\b2\\9f\\3b\\bf\\fb\\ae\\ed\\d3\\5a\\f8\\37\\57\\f0\\f5\\6e\\ef"
+ "\\b1\\4d\\70\\3d\\54\\a7\\01\\9a\\85\\08\\48\\91\\f5\\9d\\0c\\60\\87\\5b\\d9\\54\\1e\\51\\6d\\88"
+ "\\8e\\08\\8c\\a5\\71\\3a\\56\\08\\67\\46\\8f\\8f\\13\\2a\\2c\\ec\\2c\\1f\\b4\\62\\2b\\6f\\41\\0a"
+ "\\c4\\65\\42\\a2\\31\\6b\\2c\\7d\\3e\\bb\\75\\ac\\86\\97\\30\\d9\\48\\cd\\9a\\1f\\56\\c4\\c6\\e4"
+ "\\12\\c0\\9d\\fb\\ee\\02\\8c\\ce\\1c\\f2\\1e\\a1\\78\\23\\db\\c4\\1e\\49\\03\\d3\\71\\cc\\08\\50"
+ "\\c5\\d8\\5c\\ed\\d5\\b5\\65\\ac\\b5\\c9\\21\\d2\\c9\\29\\76\\de\\f0\\30\\1a\\5b\\3c\\f2\\3b\\db"
+ "\\3a\\39\\82\\3a\\16\\08\\6f\\a8\\f1\\be\\69\\69\\99\\71\\a6\\05\\d3\\14\\93\\2a\\16\\f2\\2f\\11"
+ "\\c7\\7e\\20\\bb\\91\\44\\ee\\f8\\e4\\01\\53\\c0\\b9\\7f\\f0\\bf\\f0\\03\\9c\\6d\\b1\\df\\a2\\44"
+ "\\01\\6d\\6b\\71\\2b\\5c\\b3\\21\\19\\46\\5e\\8f\\db\\91\\d3\\7c\\78\\6b\\b7\\12\\00\\8f\\eb\\bd"
+ "\\8a\\f5\\d4\\2e\\c4\\c1\\1e\\df\\73\\63\\59\\47\\49\\03\\0a\\b7\\cf\\24\\cf\\9c\\0e\\44\\7a\\9e"
+ "\\14\\fb\\42\\bf\\9d\\39\\30\\9e\\a0\\ab\\2f\\d1\\ae\\9e\\6a\\83\\43\\e3\\55\\7d\\85\\bf\\63\\8a"
+ "\\f8\\96\\10\\1f\\fe\\6d\\e7\\22\\1b\\e1\\69\\46\\8a\\44\\c8\\c8\\f9\\0c\\2b\\19\\07\\a5\\02\\3e"
+ "\\f2\\30\\10\\9a\\85\\8a\\5f\\ef\\81\\45\\a0\\77\\b1\\03\\10\\73\\4b\\ae\\98\\9d\\47\\bf\\9a\\2d"
+ "\\3a\\d5\\0f\\03\\66\\e3\\3d\\53\\d9\\40\\ce\\1f\\6f\\32\\2f\\21\\2b\\23\\21\\6c\\62\\d4\\a7\\3e"
+ "\\a8\\ce\\28\\31\\2d\\00\\3d\\67\\5e\\af\\a0\\cf\\2e\\d2\\b9\\6b\\84\\eb\\69\\08\\3c\\62\\36\\be"
+ "\\12\\fd\\36\\7f\\88\\3e\\ad\\bc\\0b\\c0\\41\\c4\\50\\b6\\e3\\50\\31\\e8\\ce\\e2\\96\\65\\55\\9c"
+ "\\16\\46\\e6\\b0\\2d\\3a\\e8\\81\\05\\b0\\bf\\34\\f7\\bc\\10\\1c\\fb\\cc\\3c\\f1\\85\\97\\42\\9f"
+ "\\eb\\14\\8d\\3c\\bf\\d7\\17\\88\\49\\9d\\8b\\2b\\b2\\3a\\83\\d1\\4f\\04\\9e\\a1\\0f\\ad\\08\\9d"
+ "\\54\\af\\d1\\82\\c3\\ec\\32\\2f\\02\\8f\\05\\21\\2d\\a2\\b7\\e4\\f4\\6f\\2e\\81\\2b\\0b\\9c\\fc"
+ "\\cb\\fe\\74\\02\\f9\\db\\f4\\f3\\ea\\00\\a8\\ec\\d1\\99\\74\\26\\dd\\d6\\34\\d5\\25\\b1\\46\\dd"
+ "\\9c\\aa\\71\\f5\\60\\b0\\88\\c8\\e0\\0b\\59\\5a\\25\\4f\\29\\66\\f9\\e3\\2e\\fe\\e9\\da\\e5\\18"
+ "\\4f\\27\\62\\f4\\ce\\a4\\21\\95\\74\\c7\\57\\64\\27\\9a\\4c\\fd\\54\\7d\\61\\ce\\c3\\ac\\87\\46"
+ "\\9c\\fa\\ff\\09\\ca\\79\\97\\67\\24\\74\\ca\\d4\\21\\83\\26\\25\\19\\12\\37\\64\\19\\e5\\65\\e0"
+ "\\74\\75\\8e\\dd\\c8\\ef\\74\\c7\\d8\\21\\2b\\79\\04\\51\\46\\65\\60\\03\\5d\\fa\\d8\\f4\\65\\a4"
+ "\\9e\\5d\\23\\da\\d7\\8a\\92\\80\\a4\\de\\78\\3c\\f1\\57\\42\\6d\\cd\\c9\\2f\\d5\\a4\\9e\\ab\\40"
+ "\\f4\\cb\\1b\\d7\\a3\\ca\\fc\\eb\\a7\\01\\b2\\9a\\69\\4e\\46\\9b\\18\\4e\\dd\\79\\a7\\aa\\a6\\52"
+ "\\39\\1e\\ef\\30\\cc\\9b\\bd\\5b\\ee\\4c\\21\\6d\\30\\00\\72\\b0\\46\\5f\\08\\cf\\c5\\b9\\e0\\3e"
+ "\\c2\\b3\\0c\\dc\\8e\\64\\de\\19\\42\\79\\cf\\43\\ea\\43\\5d\\8e\\88\\f7\\ab\\15\\dc\\3f\\c8\\67"
+ "\\20\\db\\b8\\64\\b1\\47\\1f\\de\\f2\\cb\\3f\\59\\9f\\d8\\46\\90\\dc\\ae\\2f\\22\\f9\\e2\\31\\89"
+ "\\d9\\9c\\1c\\4c\\d3\\a9\\4a\\57\\84\\9c\\9f\\ea\\2c\\3c\\ae\\3c\\c3\\1e\\8b\\e5\\4e\\17\\01\\25"
+ "\\db\\34\\46\\5f\\15\\ea\\05\\0c\\7c\\d9\\45\\8c\\19\\d0\\73\\8a\\96\\16\\dd\\44\\f9\\05\\b7\\5b"
+ "\\71\\b0\\e6\\21\\36\\5f\\75\\89\\91\\73\\75\\ab\\7d\\ae\\d3\\73\\ec\\37\\c6\\ea\\55\\75\\ef\\ea"
+ "\\ab\\8b\\7b\\11\\dc\\6d\\1a\\b2\\6a\\c4\\25\\cf\\aa\\e3\\9f\\49\\49\\89\\cb\\37\\9b\\0a\\a7\\01"
+ "\\60\\70\\dc\\b7\\c8\\83\\e1\\42\\f5\\be\\ad\\62\\94\\ad\\8d\\a1"
+ ))
+ (memory 0 0)
+ (memory 0 0)
+ (memory 0 0)
+
+ (func (export "f32.kahan_sum") (param $$p i32) (param $$n i32) (result f32)
+ (local $$sum f32)
+ (local $$c f32)
+ (local $$t f32)
+ (block $$exit
+ (loop $$top
+ (local.set $$t
+ (f32.sub
+ (f32.sub
+ (local.tee $$sum
+ (f32.add
+ (local.get $$c)
+ (local.tee $$t
+ (f32.sub (f32.load $$m (local.get $$p)) (local.get $$t))
+ )
+ )
+ )
+ (local.get $$c)
+ )
+ (local.get $$t)
+ )
+ )
+ (local.set $$p (i32.add (local.get $$p) (i32.const 4)))
+ (local.set $$c (local.get $$sum))
+ (br_if $$top (local.tee $$n (i32.add (local.get $$n) (i32.const -1))))
+ )
+ )
+ (local.get $$sum)
+ )
+
+ (func (export "f32.plain_sum") (param $$p i32) (param $$n i32) (result f32)
+ (local $$sum f32)
+ (block $$exit
+ (loop $$top
+ (local.set $$sum (f32.add (local.get $$sum) (f32.load $$m (local.get $$p))))
+ (local.set $$p (i32.add (local.get $$p) (i32.const 4)))
+ (local.set $$n (i32.add (local.get $$n) (i32.const -1)))
+ (br_if $$top (local.get $$n))
+ )
+ )
+ (local.get $$sum)
+ )
+)`);
+
+// ./test/core/multi-memory/float_exprs1.wast:103
+assert_return(
+ () => invoke($0, `f32.kahan_sum`, [0, 256]),
+ [value("f32", -21558138000000000000000000000000)],
+);
+
+// ./test/core/multi-memory/float_exprs1.wast:104
+assert_return(
+ () => invoke($0, `f32.plain_sum`, [0, 256]),
+ [value("f32", -16487540000000000000000000000000)],
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/float_memory.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/float_memory.wast.js
new file mode 100644
index 0000000000..8f01f424e8
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/float_memory.wast.js
@@ -0,0 +1,361 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/float_memory.wast
+
+// ./test/core/float_memory.wast:5
+let $0 = instantiate(`(module
+ (memory (data "\\00\\00\\a0\\7f"))
+
+ (func (export "f32.load") (result f32) (f32.load (i32.const 0)))
+ (func (export "i32.load") (result i32) (i32.load (i32.const 0)))
+ (func (export "f32.store") (f32.store (i32.const 0) (f32.const nan:0x200000)))
+ (func (export "i32.store") (i32.store (i32.const 0) (i32.const 0x7fa00000)))
+ (func (export "reset") (i32.store (i32.const 0) (i32.const 0)))
+)`);
+
+// ./test/core/float_memory.wast:15
+assert_return(() => invoke($0, `i32.load`, []), [value("i32", 2141192192)]);
+
+// ./test/core/float_memory.wast:16
+assert_return(() => invoke($0, `f32.load`, []), [bytes("f32", [0x0, 0x0, 0xa0, 0x7f])]);
+
+// ./test/core/float_memory.wast:17
+invoke($0, `reset`, []);
+
+// ./test/core/float_memory.wast:18
+assert_return(() => invoke($0, `i32.load`, []), [value("i32", 0)]);
+
+// ./test/core/float_memory.wast:19
+assert_return(() => invoke($0, `f32.load`, []), [value("f32", 0)]);
+
+// ./test/core/float_memory.wast:20
+invoke($0, `f32.store`, []);
+
+// ./test/core/float_memory.wast:21
+assert_return(() => invoke($0, `i32.load`, []), [value("i32", 2141192192)]);
+
+// ./test/core/float_memory.wast:22
+assert_return(() => invoke($0, `f32.load`, []), [bytes("f32", [0x0, 0x0, 0xa0, 0x7f])]);
+
+// ./test/core/float_memory.wast:23
+invoke($0, `reset`, []);
+
+// ./test/core/float_memory.wast:24
+assert_return(() => invoke($0, `i32.load`, []), [value("i32", 0)]);
+
+// ./test/core/float_memory.wast:25
+assert_return(() => invoke($0, `f32.load`, []), [value("f32", 0)]);
+
+// ./test/core/float_memory.wast:26
+invoke($0, `i32.store`, []);
+
+// ./test/core/float_memory.wast:27
+assert_return(() => invoke($0, `i32.load`, []), [value("i32", 2141192192)]);
+
+// ./test/core/float_memory.wast:28
+assert_return(() => invoke($0, `f32.load`, []), [bytes("f32", [0x0, 0x0, 0xa0, 0x7f])]);
+
+// ./test/core/float_memory.wast:30
+let $1 = instantiate(`(module
+ (memory (data "\\00\\00\\00\\00\\00\\00\\f4\\7f"))
+
+ (func (export "f64.load") (result f64) (f64.load (i32.const 0)))
+ (func (export "i64.load") (result i64) (i64.load (i32.const 0)))
+ (func (export "f64.store") (f64.store (i32.const 0) (f64.const nan:0x4000000000000)))
+ (func (export "i64.store") (i64.store (i32.const 0) (i64.const 0x7ff4000000000000)))
+ (func (export "reset") (i64.store (i32.const 0) (i64.const 0)))
+)`);
+
+// ./test/core/float_memory.wast:40
+assert_return(() => invoke($1, `i64.load`, []), [value("i64", 9219994337134247936n)]);
+
+// ./test/core/float_memory.wast:41
+assert_return(
+ () => invoke($1, `f64.load`, []),
+ [bytes("f64", [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x7f])],
+);
+
+// ./test/core/float_memory.wast:42
+invoke($1, `reset`, []);
+
+// ./test/core/float_memory.wast:43
+assert_return(() => invoke($1, `i64.load`, []), [value("i64", 0n)]);
+
+// ./test/core/float_memory.wast:44
+assert_return(() => invoke($1, `f64.load`, []), [value("f64", 0)]);
+
+// ./test/core/float_memory.wast:45
+invoke($1, `f64.store`, []);
+
+// ./test/core/float_memory.wast:46
+assert_return(() => invoke($1, `i64.load`, []), [value("i64", 9219994337134247936n)]);
+
+// ./test/core/float_memory.wast:47
+assert_return(
+ () => invoke($1, `f64.load`, []),
+ [bytes("f64", [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x7f])],
+);
+
+// ./test/core/float_memory.wast:48
+invoke($1, `reset`, []);
+
+// ./test/core/float_memory.wast:49
+assert_return(() => invoke($1, `i64.load`, []), [value("i64", 0n)]);
+
+// ./test/core/float_memory.wast:50
+assert_return(() => invoke($1, `f64.load`, []), [value("f64", 0)]);
+
+// ./test/core/float_memory.wast:51
+invoke($1, `i64.store`, []);
+
+// ./test/core/float_memory.wast:52
+assert_return(() => invoke($1, `i64.load`, []), [value("i64", 9219994337134247936n)]);
+
+// ./test/core/float_memory.wast:53
+assert_return(
+ () => invoke($1, `f64.load`, []),
+ [bytes("f64", [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x7f])],
+);
+
+// ./test/core/float_memory.wast:57
+let $2 = instantiate(`(module
+ (memory (data "\\00\\00\\00\\a0\\7f"))
+
+ (func (export "f32.load") (result f32) (f32.load (i32.const 1)))
+ (func (export "i32.load") (result i32) (i32.load (i32.const 1)))
+ (func (export "f32.store") (f32.store (i32.const 1) (f32.const nan:0x200000)))
+ (func (export "i32.store") (i32.store (i32.const 1) (i32.const 0x7fa00000)))
+ (func (export "reset") (i32.store (i32.const 1) (i32.const 0)))
+)`);
+
+// ./test/core/float_memory.wast:67
+assert_return(() => invoke($2, `i32.load`, []), [value("i32", 2141192192)]);
+
+// ./test/core/float_memory.wast:68
+assert_return(() => invoke($2, `f32.load`, []), [bytes("f32", [0x0, 0x0, 0xa0, 0x7f])]);
+
+// ./test/core/float_memory.wast:69
+invoke($2, `reset`, []);
+
+// ./test/core/float_memory.wast:70
+assert_return(() => invoke($2, `i32.load`, []), [value("i32", 0)]);
+
+// ./test/core/float_memory.wast:71
+assert_return(() => invoke($2, `f32.load`, []), [value("f32", 0)]);
+
+// ./test/core/float_memory.wast:72
+invoke($2, `f32.store`, []);
+
+// ./test/core/float_memory.wast:73
+assert_return(() => invoke($2, `i32.load`, []), [value("i32", 2141192192)]);
+
+// ./test/core/float_memory.wast:74
+assert_return(() => invoke($2, `f32.load`, []), [bytes("f32", [0x0, 0x0, 0xa0, 0x7f])]);
+
+// ./test/core/float_memory.wast:75
+invoke($2, `reset`, []);
+
+// ./test/core/float_memory.wast:76
+assert_return(() => invoke($2, `i32.load`, []), [value("i32", 0)]);
+
+// ./test/core/float_memory.wast:77
+assert_return(() => invoke($2, `f32.load`, []), [value("f32", 0)]);
+
+// ./test/core/float_memory.wast:78
+invoke($2, `i32.store`, []);
+
+// ./test/core/float_memory.wast:79
+assert_return(() => invoke($2, `i32.load`, []), [value("i32", 2141192192)]);
+
+// ./test/core/float_memory.wast:80
+assert_return(() => invoke($2, `f32.load`, []), [bytes("f32", [0x0, 0x0, 0xa0, 0x7f])]);
+
+// ./test/core/float_memory.wast:82
+let $3 = instantiate(`(module
+ (memory (data "\\00\\00\\00\\00\\00\\00\\00\\f4\\7f"))
+
+ (func (export "f64.load") (result f64) (f64.load (i32.const 1)))
+ (func (export "i64.load") (result i64) (i64.load (i32.const 1)))
+ (func (export "f64.store") (f64.store (i32.const 1) (f64.const nan:0x4000000000000)))
+ (func (export "i64.store") (i64.store (i32.const 1) (i64.const 0x7ff4000000000000)))
+ (func (export "reset") (i64.store (i32.const 1) (i64.const 0)))
+)`);
+
+// ./test/core/float_memory.wast:92
+assert_return(() => invoke($3, `i64.load`, []), [value("i64", 9219994337134247936n)]);
+
+// ./test/core/float_memory.wast:93
+assert_return(
+ () => invoke($3, `f64.load`, []),
+ [bytes("f64", [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x7f])],
+);
+
+// ./test/core/float_memory.wast:94
+invoke($3, `reset`, []);
+
+// ./test/core/float_memory.wast:95
+assert_return(() => invoke($3, `i64.load`, []), [value("i64", 0n)]);
+
+// ./test/core/float_memory.wast:96
+assert_return(() => invoke($3, `f64.load`, []), [value("f64", 0)]);
+
+// ./test/core/float_memory.wast:97
+invoke($3, `f64.store`, []);
+
+// ./test/core/float_memory.wast:98
+assert_return(() => invoke($3, `i64.load`, []), [value("i64", 9219994337134247936n)]);
+
+// ./test/core/float_memory.wast:99
+assert_return(
+ () => invoke($3, `f64.load`, []),
+ [bytes("f64", [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x7f])],
+);
+
+// ./test/core/float_memory.wast:100
+invoke($3, `reset`, []);
+
+// ./test/core/float_memory.wast:101
+assert_return(() => invoke($3, `i64.load`, []), [value("i64", 0n)]);
+
+// ./test/core/float_memory.wast:102
+assert_return(() => invoke($3, `f64.load`, []), [value("f64", 0)]);
+
+// ./test/core/float_memory.wast:103
+invoke($3, `i64.store`, []);
+
+// ./test/core/float_memory.wast:104
+assert_return(() => invoke($3, `i64.load`, []), [value("i64", 9219994337134247936n)]);
+
+// ./test/core/float_memory.wast:105
+assert_return(
+ () => invoke($3, `f64.load`, []),
+ [bytes("f64", [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x7f])],
+);
+
+// ./test/core/float_memory.wast:109
+let $4 = instantiate(`(module
+ (memory (data "\\01\\00\\d0\\7f"))
+
+ (func (export "f32.load") (result f32) (f32.load (i32.const 0)))
+ (func (export "i32.load") (result i32) (i32.load (i32.const 0)))
+ (func (export "f32.store") (f32.store (i32.const 0) (f32.const nan:0x500001)))
+ (func (export "i32.store") (i32.store (i32.const 0) (i32.const 0x7fd00001)))
+ (func (export "reset") (i32.store (i32.const 0) (i32.const 0)))
+)`);
+
+// ./test/core/float_memory.wast:119
+assert_return(() => invoke($4, `i32.load`, []), [value("i32", 2144337921)]);
+
+// ./test/core/float_memory.wast:120
+assert_return(() => invoke($4, `f32.load`, []), [bytes("f32", [0x1, 0x0, 0xd0, 0x7f])]);
+
+// ./test/core/float_memory.wast:121
+invoke($4, `reset`, []);
+
+// ./test/core/float_memory.wast:122
+assert_return(() => invoke($4, `i32.load`, []), [value("i32", 0)]);
+
+// ./test/core/float_memory.wast:123
+assert_return(() => invoke($4, `f32.load`, []), [value("f32", 0)]);
+
+// ./test/core/float_memory.wast:124
+invoke($4, `f32.store`, []);
+
+// ./test/core/float_memory.wast:125
+assert_return(() => invoke($4, `i32.load`, []), [value("i32", 2144337921)]);
+
+// ./test/core/float_memory.wast:126
+assert_return(() => invoke($4, `f32.load`, []), [bytes("f32", [0x1, 0x0, 0xd0, 0x7f])]);
+
+// ./test/core/float_memory.wast:127
+invoke($4, `reset`, []);
+
+// ./test/core/float_memory.wast:128
+assert_return(() => invoke($4, `i32.load`, []), [value("i32", 0)]);
+
+// ./test/core/float_memory.wast:129
+assert_return(() => invoke($4, `f32.load`, []), [value("f32", 0)]);
+
+// ./test/core/float_memory.wast:130
+invoke($4, `i32.store`, []);
+
+// ./test/core/float_memory.wast:131
+assert_return(() => invoke($4, `i32.load`, []), [value("i32", 2144337921)]);
+
+// ./test/core/float_memory.wast:132
+assert_return(() => invoke($4, `f32.load`, []), [bytes("f32", [0x1, 0x0, 0xd0, 0x7f])]);
+
+// ./test/core/float_memory.wast:134
+let $5 = instantiate(`(module
+ (memory (data "\\01\\00\\00\\00\\00\\00\\fc\\7f"))
+
+ (func (export "f64.load") (result f64) (f64.load (i32.const 0)))
+ (func (export "i64.load") (result i64) (i64.load (i32.const 0)))
+ (func (export "f64.store") (f64.store (i32.const 0) (f64.const nan:0xc000000000001)))
+ (func (export "i64.store") (i64.store (i32.const 0) (i64.const 0x7ffc000000000001)))
+ (func (export "reset") (i64.store (i32.const 0) (i64.const 0)))
+)`);
+
+// ./test/core/float_memory.wast:144
+assert_return(() => invoke($5, `i64.load`, []), [value("i64", 9222246136947933185n)]);
+
+// ./test/core/float_memory.wast:145
+assert_return(
+ () => invoke($5, `f64.load`, []),
+ [bytes("f64", [0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfc, 0x7f])],
+);
+
+// ./test/core/float_memory.wast:146
+invoke($5, `reset`, []);
+
+// ./test/core/float_memory.wast:147
+assert_return(() => invoke($5, `i64.load`, []), [value("i64", 0n)]);
+
+// ./test/core/float_memory.wast:148
+assert_return(() => invoke($5, `f64.load`, []), [value("f64", 0)]);
+
+// ./test/core/float_memory.wast:149
+invoke($5, `f64.store`, []);
+
+// ./test/core/float_memory.wast:150
+assert_return(() => invoke($5, `i64.load`, []), [value("i64", 9222246136947933185n)]);
+
+// ./test/core/float_memory.wast:151
+assert_return(
+ () => invoke($5, `f64.load`, []),
+ [bytes("f64", [0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfc, 0x7f])],
+);
+
+// ./test/core/float_memory.wast:152
+invoke($5, `reset`, []);
+
+// ./test/core/float_memory.wast:153
+assert_return(() => invoke($5, `i64.load`, []), [value("i64", 0n)]);
+
+// ./test/core/float_memory.wast:154
+assert_return(() => invoke($5, `f64.load`, []), [value("f64", 0)]);
+
+// ./test/core/float_memory.wast:155
+invoke($5, `i64.store`, []);
+
+// ./test/core/float_memory.wast:156
+assert_return(() => invoke($5, `i64.load`, []), [value("i64", 9222246136947933185n)]);
+
+// ./test/core/float_memory.wast:157
+assert_return(
+ () => invoke($5, `f64.load`, []),
+ [bytes("f64", [0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfc, 0x7f])],
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/float_memory0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/float_memory0.wast.js
new file mode 100644
index 0000000000..3647fc1164
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/float_memory0.wast.js
@@ -0,0 +1,137 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/float_memory0.wast
+
+// ./test/core/multi-memory/float_memory0.wast:5
+let $0 = instantiate(`(module
+ (memory 0 0)
+ (memory 0 0)
+ (memory 0 0)
+ (memory $$m (data "\\00\\00\\a0\\7f"))
+ (memory 0 0)
+ (memory 0 0)
+
+ (func (export "f32.load") (result f32) (f32.load $$m (i32.const 0)))
+ (func (export "i32.load") (result i32) (i32.load $$m (i32.const 0)))
+ (func (export "f32.store") (f32.store $$m (i32.const 0) (f32.const nan:0x200000)))
+ (func (export "i32.store") (i32.store $$m (i32.const 0) (i32.const 0x7fa00000)))
+ (func (export "reset") (i32.store $$m (i32.const 0) (i32.const 0)))
+)`);
+
+// ./test/core/multi-memory/float_memory0.wast:20
+assert_return(() => invoke($0, `i32.load`, []), [value("i32", 2141192192)]);
+
+// ./test/core/multi-memory/float_memory0.wast:21
+assert_return(() => invoke($0, `f32.load`, []), [bytes("f32", [0x0, 0x0, 0xa0, 0x7f])]);
+
+// ./test/core/multi-memory/float_memory0.wast:22
+invoke($0, `reset`, []);
+
+// ./test/core/multi-memory/float_memory0.wast:23
+assert_return(() => invoke($0, `i32.load`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/float_memory0.wast:24
+assert_return(() => invoke($0, `f32.load`, []), [value("f32", 0)]);
+
+// ./test/core/multi-memory/float_memory0.wast:25
+invoke($0, `f32.store`, []);
+
+// ./test/core/multi-memory/float_memory0.wast:26
+assert_return(() => invoke($0, `i32.load`, []), [value("i32", 2141192192)]);
+
+// ./test/core/multi-memory/float_memory0.wast:27
+assert_return(() => invoke($0, `f32.load`, []), [bytes("f32", [0x0, 0x0, 0xa0, 0x7f])]);
+
+// ./test/core/multi-memory/float_memory0.wast:28
+invoke($0, `reset`, []);
+
+// ./test/core/multi-memory/float_memory0.wast:29
+assert_return(() => invoke($0, `i32.load`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/float_memory0.wast:30
+assert_return(() => invoke($0, `f32.load`, []), [value("f32", 0)]);
+
+// ./test/core/multi-memory/float_memory0.wast:31
+invoke($0, `i32.store`, []);
+
+// ./test/core/multi-memory/float_memory0.wast:32
+assert_return(() => invoke($0, `i32.load`, []), [value("i32", 2141192192)]);
+
+// ./test/core/multi-memory/float_memory0.wast:33
+assert_return(() => invoke($0, `f32.load`, []), [bytes("f32", [0x0, 0x0, 0xa0, 0x7f])]);
+
+// ./test/core/multi-memory/float_memory0.wast:35
+let $1 = instantiate(`(module
+ (memory 0 0)
+ (memory $$m (data "\\00\\00\\00\\00\\00\\00\\f4\\7f"))
+
+ (func (export "f64.load") (result f64) (f64.load $$m (i32.const 0)))
+ (func (export "i64.load") (result i64) (i64.load $$m (i32.const 0)))
+ (func (export "f64.store") (f64.store $$m (i32.const 0) (f64.const nan:0x4000000000000)))
+ (func (export "i64.store") (i64.store $$m (i32.const 0) (i64.const 0x7ff4000000000000)))
+ (func (export "reset") (i64.store $$m (i32.const 0) (i64.const 0)))
+)`);
+
+// ./test/core/multi-memory/float_memory0.wast:46
+assert_return(() => invoke($1, `i64.load`, []), [value("i64", 9219994337134247936n)]);
+
+// ./test/core/multi-memory/float_memory0.wast:47
+assert_return(
+ () => invoke($1, `f64.load`, []),
+ [bytes("f64", [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x7f])],
+);
+
+// ./test/core/multi-memory/float_memory0.wast:48
+invoke($1, `reset`, []);
+
+// ./test/core/multi-memory/float_memory0.wast:49
+assert_return(() => invoke($1, `i64.load`, []), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/float_memory0.wast:50
+assert_return(() => invoke($1, `f64.load`, []), [value("f64", 0)]);
+
+// ./test/core/multi-memory/float_memory0.wast:51
+invoke($1, `f64.store`, []);
+
+// ./test/core/multi-memory/float_memory0.wast:52
+assert_return(() => invoke($1, `i64.load`, []), [value("i64", 9219994337134247936n)]);
+
+// ./test/core/multi-memory/float_memory0.wast:53
+assert_return(
+ () => invoke($1, `f64.load`, []),
+ [bytes("f64", [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x7f])],
+);
+
+// ./test/core/multi-memory/float_memory0.wast:54
+invoke($1, `reset`, []);
+
+// ./test/core/multi-memory/float_memory0.wast:55
+assert_return(() => invoke($1, `i64.load`, []), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/float_memory0.wast:56
+assert_return(() => invoke($1, `f64.load`, []), [value("f64", 0)]);
+
+// ./test/core/multi-memory/float_memory0.wast:57
+invoke($1, `i64.store`, []);
+
+// ./test/core/multi-memory/float_memory0.wast:58
+assert_return(() => invoke($1, `i64.load`, []), [value("i64", 9219994337134247936n)]);
+
+// ./test/core/multi-memory/float_memory0.wast:59
+assert_return(
+ () => invoke($1, `f64.load`, []),
+ [bytes("f64", [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x7f])],
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/harness/directives.txt b/js/src/jit-test/tests/wasm/spec/multi-memory/harness/directives.txt
new file mode 100644
index 0000000000..d41243abbb
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/harness/directives.txt
@@ -0,0 +1 @@
+|jit-test| skip-if: true \ No newline at end of file
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/harness/harness.js b/js/src/jit-test/tests/wasm/spec/multi-memory/harness/harness.js
new file mode 100644
index 0000000000..a96781e8ed
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/harness/harness.js
@@ -0,0 +1,448 @@
+"use strict";
+
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+if (!wasmIsSupported()) {
+ quit();
+}
+
+function bytes(type, bytes) {
+ var typedBuffer = new Uint8Array(bytes);
+ return wasmGlobalFromArrayBuffer(type, typedBuffer.buffer);
+}
+function value(type, value) {
+ return new WebAssembly.Global({
+ value: type,
+ mutable: false,
+ }, value);
+}
+
+function i8x16(elements) {
+ let typedBuffer = new Uint8Array(elements);
+ return wasmGlobalFromArrayBuffer("v128", typedBuffer.buffer);
+}
+function i16x8(elements) {
+ let typedBuffer = new Uint16Array(elements);
+ return wasmGlobalFromArrayBuffer("v128", typedBuffer.buffer);
+}
+function i32x4(elements) {
+ let typedBuffer = new Uint32Array(elements);
+ return wasmGlobalFromArrayBuffer("v128", typedBuffer.buffer);
+}
+function i64x2(elements) {
+ let typedBuffer = new BigUint64Array(elements);
+ return wasmGlobalFromArrayBuffer("v128", typedBuffer.buffer);
+}
+function f32x4(elements) {
+ let typedBuffer = new Float32Array(elements);
+ return wasmGlobalFromArrayBuffer("v128", typedBuffer.buffer);
+}
+function f64x2(elements) {
+ let typedBuffer = new Float64Array(elements);
+ return wasmGlobalFromArrayBuffer("v128", typedBuffer.buffer);
+}
+
+function either(...arr) {
+ return new EitherVariants(arr);
+}
+
+class F32x4Pattern {
+ constructor(x, y, z, w) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.w = w;
+ }
+}
+
+class F64x2Pattern {
+ constructor(x, y) {
+ this.x = x;
+ this.y = y;
+ }
+}
+
+class RefWithType {
+ constructor(type) {
+ this.type = type;
+ }
+
+ formatExpected() {
+ return `RefWithType(${this.type})`;
+ }
+
+ test(refGlobal) {
+ try {
+ new WebAssembly.Global({value: this.type}, refGlobal.value);
+ return true;
+ } catch (err) {
+ assertEq(err instanceof TypeError, true, `wrong type of error when creating global: ${err}`);
+ assertEq(!!err.message.match(/can only pass/), true, `wrong type of error when creating global: ${err}`);
+ return false;
+ }
+ }
+}
+
+// ref.extern values created by spec tests will be JS objects of the form
+// { [externsym]: <number> }. Other externref values are possible to observe
+// if extern.convert_any is used.
+let externsym = Symbol("externref");
+function externref(s) {
+ return { [externsym]: s };
+}
+function is_externref(x) {
+ return (x !== null && externsym in x) ? 1 : 0;
+}
+function is_funcref(x) {
+ return typeof x === "function" ? 1 : 0;
+}
+function eq_externref(x, y) {
+ return x === y ? 1 : 0;
+}
+function eq_funcref(x, y) {
+ return x === y ? 1 : 0;
+}
+
+class ExternRefResult {
+ constructor(n) {
+ this.n = n;
+ }
+
+ formatExpected() {
+ return `ref.extern ${this.n}`;
+ }
+
+ test(global) {
+ // the global's value can either be an externref or just a plain old JS number
+ let result = global.value;
+ if (typeof global.value === "object" && externsym in global.value) {
+ result = global.value[externsym];
+ }
+ return result === this.n;
+ }
+}
+
+// ref.host values created by spectests will be whatever the JS API does to
+// convert the given value to anyref. It should implicitly be like any.convert_extern.
+function hostref(v) {
+ if (!wasmGcEnabled()) {
+ throw new Error("ref.host only works when wasm GC is enabled");
+ }
+
+ const { internalizeNum } = new WebAssembly.Instance(
+ new WebAssembly.Module(wasmTextToBinary(`(module
+ (func (import "test" "coerce") (param i32) (result anyref))
+ (func (export "internalizeNum") (param i32) (result anyref)
+ (call 0 (local.get 0))
+ )
+ )`)),
+ { "test": { "coerce": x => x } },
+ ).exports;
+ return internalizeNum(v);
+}
+
+class HostRefResult {
+ constructor(n) {
+ this.n = n;
+ }
+
+ formatExpected() {
+ return `ref.host ${this.n}`;
+ }
+
+ test(externrefGlobal) {
+ assertEq(externsym in externrefGlobal.value, true, `HostRefResult only works with externref inputs`);
+ return externrefGlobal.value[externsym] === this.n;
+ }
+}
+
+let spectest = {
+ externref: externref,
+ is_externref: is_externref,
+ is_funcref: is_funcref,
+ eq_externref: eq_externref,
+ eq_funcref: eq_funcref,
+ print: console.log.bind(console),
+ print_i32: console.log.bind(console),
+ print_i32_f32: console.log.bind(console),
+ print_f64_f64: console.log.bind(console),
+ print_f32: console.log.bind(console),
+ print_f64: console.log.bind(console),
+ global_i32: 666,
+ global_i64: 666n,
+ global_f32: 666,
+ global_f64: 666,
+ table: new WebAssembly.Table({
+ initial: 10,
+ maximum: 20,
+ element: "anyfunc",
+ }),
+ memory: new WebAssembly.Memory({ initial: 1, maximum: 2 }),
+};
+
+let linkage = {
+ spectest,
+};
+
+function getInstance(instanceish) {
+ if (typeof instanceish === "string") {
+ assertEq(
+ instanceish in linkage,
+ true,
+ `'${instanceish}'' must be registered`,
+ );
+ return linkage[instanceish];
+ }
+ return instanceish;
+}
+
+function instantiate(source) {
+ let bytecode = wasmTextToBinary(source);
+ let module = new WebAssembly.Module(bytecode);
+ let instance = new WebAssembly.Instance(module, linkage);
+ return instance.exports;
+}
+
+function register(instanceish, name) {
+ linkage[name] = getInstance(instanceish);
+}
+
+function invoke(instanceish, field, params) {
+ let func = getInstance(instanceish)[field];
+ assertEq(func instanceof Function, true, "expected a function");
+ return wasmLosslessInvoke(func, ...params);
+}
+
+function get(instanceish, field) {
+ let global = getInstance(instanceish)[field];
+ assertEq(
+ global instanceof WebAssembly.Global,
+ true,
+ "expected a WebAssembly.Global",
+ );
+ return global;
+}
+
+function assert_trap(thunk, message) {
+ try {
+ thunk();
+ throw new Error("expected trap");
+ } catch (err) {
+ if (err instanceof WebAssembly.RuntimeError) {
+ return;
+ }
+ throw err;
+ }
+}
+
+let StackOverflow;
+try {
+ (function f() {
+ 1 + f();
+ })();
+} catch (e) {
+ StackOverflow = e.constructor;
+}
+function assert_exhaustion(thunk, message) {
+ try {
+ thunk();
+ assertEq("normal return", "exhaustion");
+ } catch (err) {
+ assertEq(
+ err instanceof StackOverflow,
+ true,
+ "expected exhaustion",
+ );
+ }
+}
+
+function assert_invalid(thunk, message) {
+ try {
+ thunk();
+ assertEq("valid module", "invalid module");
+ } catch (err) {
+ assertEq(
+ err instanceof WebAssembly.LinkError ||
+ err instanceof WebAssembly.CompileError,
+ true,
+ "expected an invalid module",
+ );
+ }
+}
+
+function assert_unlinkable(thunk, message) {
+ try {
+ thunk();
+ assertEq(true, false, "expected an unlinkable module");
+ } catch (err) {
+ assertEq(
+ err instanceof WebAssembly.LinkError ||
+ err instanceof WebAssembly.CompileError,
+ true,
+ "expected an unlinkable module",
+ );
+ }
+}
+
+function assert_malformed(thunk, message) {
+ try {
+ thunk();
+ assertEq("valid module", "malformed module");
+ } catch (err) {
+ assertEq(
+ err instanceof TypeError ||
+ err instanceof SyntaxError ||
+ err instanceof WebAssembly.CompileError ||
+ err instanceof WebAssembly.LinkError,
+ true,
+ `expected a malformed module`,
+ );
+ }
+}
+
+function assert_exception(thunk) {
+ let thrown = false;
+ try {
+ thunk();
+ } catch (err) {
+ thrown = true;
+ }
+ assertEq(thrown, true, "expected an exception to be thrown");
+}
+
+function assert_return(thunk, expected) {
+ let results = thunk();
+
+ if (results === undefined) {
+ results = [];
+ } else if (!Array.isArray(results)) {
+ results = [results];
+ }
+ if (!Array.isArray(expected)) {
+ expected = [expected];
+ }
+
+ if (!compareResults(results, expected)) {
+ let got = results.map((x) => formatResult(x)).join(", ");
+ let wanted = expected.map((x) => formatExpected(x)).join(", ");
+ assertEq(
+ `[${got}]`,
+ `[${wanted}]`,
+ );
+ assertEq(true, false, `${got} !== ${wanted}`);
+ }
+}
+
+function formatResult(result) {
+ if (typeof (result) === "object") {
+ return wasmGlobalToString(result);
+ } else {
+ return `${result}`;
+ }
+}
+
+function formatExpected(expected) {
+ if (
+ expected === `f32_canonical_nan` ||
+ expected === `f32_arithmetic_nan` ||
+ expected === `f64_canonical_nan` ||
+ expected === `f64_arithmetic_nan`
+ ) {
+ return expected;
+ } else if (expected instanceof F32x4Pattern) {
+ return `f32x4(${formatExpected(expected.x)}, ${
+ formatExpected(expected.y)
+ }, ${formatExpected(expected.z)}, ${formatExpected(expected.w)})`;
+ } else if (expected instanceof F64x2Pattern) {
+ return `f64x2(${formatExpected(expected.x)}, ${
+ formatExpected(expected.y)
+ })`;
+ } else if (expected instanceof EitherVariants) {
+ return expected.formatExpected();
+ } else if (expected instanceof RefWithType) {
+ return expected.formatExpected();
+ } else if (expected instanceof ExternRefResult) {
+ return expected.formatExpected();
+ } else if (expected instanceof HostRefResult) {
+ return expected.formatExpected();
+ } else if (typeof (expected) === "object") {
+ return wasmGlobalToString(expected);
+ } else {
+ throw new Error("unknown expected result");
+ }
+}
+
+class EitherVariants {
+ constructor(arr) {
+ this.arr = arr;
+ }
+ matches(v) {
+ return this.arr.some((e) => compareResult(v, e));
+ }
+ formatExpected() {
+ return `either(${this.arr.map(formatExpected).join(", ")})`;
+ }
+}
+
+function compareResults(results, expected) {
+ if (results.length !== expected.length) {
+ return false;
+ }
+ for (let i in results) {
+ if (expected[i] instanceof EitherVariants) {
+ return expected[i].matches(results[i]);
+ }
+ if (!compareResult(results[i], expected[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+function compareResult(result, expected) {
+ if (
+ expected === `canonical_nan` ||
+ expected === `arithmetic_nan`
+ ) {
+ return wasmGlobalIsNaN(result, expected);
+ } else if (expected === null) {
+ return result.value === null;
+ } else if (expected instanceof F32x4Pattern) {
+ return compareResult(
+ wasmGlobalExtractLane(result, "f32x4", 0),
+ expected.x,
+ ) &&
+ compareResult(wasmGlobalExtractLane(result, "f32x4", 1), expected.y) &&
+ compareResult(wasmGlobalExtractLane(result, "f32x4", 2), expected.z) &&
+ compareResult(wasmGlobalExtractLane(result, "f32x4", 3), expected.w);
+ } else if (expected instanceof F64x2Pattern) {
+ return compareResult(
+ wasmGlobalExtractLane(result, "f64x2", 0),
+ expected.x,
+ ) &&
+ compareResult(wasmGlobalExtractLane(result, "f64x2", 1), expected.y);
+ } else if (expected instanceof RefWithType) {
+ return expected.test(result);
+ } else if (expected instanceof ExternRefResult) {
+ return expected.test(result);
+ } else if (expected instanceof HostRefResult) {
+ return expected.test(result);
+ } else if (typeof (expected) === "object") {
+ return wasmGlobalsEqual(result, expected);
+ } else {
+ throw new Error("unknown expected result");
+ }
+}
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/imports0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/imports0.wast.js
new file mode 100644
index 0000000000..140457d1d9
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/imports0.wast.js
@@ -0,0 +1,73 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/imports0.wast
+
+// ./test/core/multi-memory/imports0.wast:1
+let $0 = instantiate(`(module
+ (func (export "func"))
+ (func (export "func-i32") (param i32))
+ (func (export "func-f32") (param f32))
+ (func (export "func->i32") (result i32) (i32.const 22))
+ (func (export "func->f32") (result f32) (f32.const 11))
+ (func (export "func-i32->i32") (param i32) (result i32) (local.get 0))
+ (func (export "func-i64->i64") (param i64) (result i64) (local.get 0))
+ (global (export "global-i32") i32 (i32.const 55))
+ (global (export "global-f32") f32 (f32.const 44))
+ (global (export "global-mut-i64") (mut i64) (i64.const 66))
+ (table (export "table-10-inf") 10 funcref)
+ (table (export "table-10-20") 10 20 funcref)
+ (memory (export "memory-2-inf") 2)
+ (memory (export "memory-2-4") 2 4)
+)`);
+
+// ./test/core/multi-memory/imports0.wast:18
+register($0, `test`);
+
+// ./test/core/multi-memory/imports0.wast:20
+assert_unlinkable(
+ () => instantiate(`(module (import "test" "memory-2-inf" (func)))`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports0.wast:24
+assert_unlinkable(
+ () => instantiate(`(module (import "test" "memory-2-4" (func)))`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports0.wast:29
+assert_unlinkable(
+ () => instantiate(`(module (import "test" "memory-2-inf" (global i32)))`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports0.wast:33
+assert_unlinkable(
+ () => instantiate(`(module (import "test" "memory-2-4" (global i32)))`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports0.wast:38
+assert_unlinkable(
+ () => instantiate(`(module (import "test" "memory-2-inf" (table 10 funcref)))`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports0.wast:42
+assert_unlinkable(
+ () => instantiate(`(module (import "test" "memory-2-4" (table 10 funcref)))`),
+ `incompatible import type`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/imports1.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/imports1.wast.js
new file mode 100644
index 0000000000..db3cc392dd
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/imports1.wast.js
@@ -0,0 +1,40 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/imports1.wast
+
+// ./test/core/multi-memory/imports1.wast:1
+let $0 = instantiate(`(module
+ (import "spectest" "memory" (memory 1 2))
+ (import "spectest" "memory" (memory 1 2))
+ (memory $$m (import "spectest" "memory") 1 2)
+ (import "spectest" "memory" (memory 1 2))
+
+ (data (memory 2) (i32.const 10) "\\10")
+
+ (func (export "load") (param i32) (result i32) (i32.load $$m (local.get 0)))
+)`);
+
+// ./test/core/multi-memory/imports1.wast:12
+assert_return(() => invoke($0, `load`, [0]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/imports1.wast:13
+assert_return(() => invoke($0, `load`, [10]), [value("i32", 16)]);
+
+// ./test/core/multi-memory/imports1.wast:14
+assert_return(() => invoke($0, `load`, [8]), [value("i32", 1048576)]);
+
+// ./test/core/multi-memory/imports1.wast:15
+assert_trap(() => invoke($0, `load`, [1000000]), `out of bounds memory access`);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/imports2.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/imports2.wast.js
new file mode 100644
index 0000000000..aa2bec179a
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/imports2.wast.js
@@ -0,0 +1,120 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/imports2.wast
+
+// ./test/core/multi-memory/imports2.wast:1
+let $0 = instantiate(`(module
+ (memory (export "z") 0 0)
+ (memory (export "memory-2-inf") 2)
+ (memory (export "memory-2-4") 2 4)
+)`);
+
+// ./test/core/multi-memory/imports2.wast:7
+register($0, `test`);
+
+// ./test/core/multi-memory/imports2.wast:9
+let $1 = instantiate(`(module
+ (import "test" "z" (memory 0))
+ (memory $$m (import "spectest" "memory") 1 2)
+ (data (memory 1) (i32.const 10) "\\10")
+
+ (func (export "load") (param i32) (result i32) (i32.load $$m (local.get 0)))
+)`);
+
+// ./test/core/multi-memory/imports2.wast:17
+assert_return(() => invoke($1, `load`, [0]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/imports2.wast:18
+assert_return(() => invoke($1, `load`, [10]), [value("i32", 16)]);
+
+// ./test/core/multi-memory/imports2.wast:19
+assert_return(() => invoke($1, `load`, [8]), [value("i32", 1048576)]);
+
+// ./test/core/multi-memory/imports2.wast:20
+assert_trap(() => invoke($1, `load`, [1000000]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/imports2.wast:22
+let $2 = instantiate(`(module
+ (memory (import "spectest" "memory") 1 2)
+ (data (memory 0) (i32.const 10) "\\10")
+
+ (func (export "load") (param i32) (result i32) (i32.load (local.get 0)))
+)`);
+
+// ./test/core/multi-memory/imports2.wast:28
+assert_return(() => invoke($2, `load`, [0]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/imports2.wast:29
+assert_return(() => invoke($2, `load`, [10]), [value("i32", 16)]);
+
+// ./test/core/multi-memory/imports2.wast:30
+assert_return(() => invoke($2, `load`, [8]), [value("i32", 1048576)]);
+
+// ./test/core/multi-memory/imports2.wast:31
+assert_trap(() => invoke($2, `load`, [1000000]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/imports2.wast:33
+let $3 = instantiate(`(module
+ (import "test" "memory-2-inf" (memory 2))
+ (import "test" "memory-2-inf" (memory 1))
+ (import "test" "memory-2-inf" (memory 0))
+)`);
+
+// ./test/core/multi-memory/imports2.wast:39
+let $4 = instantiate(`(module
+ (import "spectest" "memory" (memory 1))
+ (import "spectest" "memory" (memory 0))
+ (import "spectest" "memory" (memory 1 2))
+ (import "spectest" "memory" (memory 0 2))
+ (import "spectest" "memory" (memory 1 3))
+ (import "spectest" "memory" (memory 0 3))
+)`);
+
+// ./test/core/multi-memory/imports2.wast:48
+assert_unlinkable(
+ () => instantiate(`(module (import "test" "unknown" (memory 1)))`),
+ `unknown import`,
+);
+
+// ./test/core/multi-memory/imports2.wast:52
+assert_unlinkable(
+ () => instantiate(`(module (import "spectest" "unknown" (memory 1)))`),
+ `unknown import`,
+);
+
+// ./test/core/multi-memory/imports2.wast:57
+assert_unlinkable(
+ () => instantiate(`(module (import "test" "memory-2-inf" (memory 3)))`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports2.wast:61
+assert_unlinkable(
+ () => instantiate(`(module (import "test" "memory-2-inf" (memory 2 3)))`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports2.wast:65
+assert_unlinkable(
+ () => instantiate(`(module (import "spectest" "memory" (memory 2)))`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports2.wast:69
+assert_unlinkable(
+ () => instantiate(`(module (import "spectest" "memory" (memory 1 1)))`),
+ `incompatible import type`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/imports3.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/imports3.wast.js
new file mode 100644
index 0000000000..9669f1dea0
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/imports3.wast.js
@@ -0,0 +1,109 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/imports3.wast
+
+// ./test/core/multi-memory/imports3.wast:1
+let $0 = instantiate(`(module
+ (func (export "func"))
+ (func (export "func-i32") (param i32))
+ (func (export "func-f32") (param f32))
+ (func (export "func->i32") (result i32) (i32.const 22))
+ (func (export "func->f32") (result f32) (f32.const 11))
+ (func (export "func-i32->i32") (param i32) (result i32) (local.get 0))
+ (func (export "func-i64->i64") (param i64) (result i64) (local.get 0))
+ (global (export "global-i32") i32 (i32.const 55))
+ (global (export "global-f32") f32 (f32.const 44))
+ (global (export "global-mut-i64") (mut i64) (i64.const 66))
+ (table (export "table-10-inf") 10 funcref)
+ (table (export "table-10-20") 10 20 funcref)
+ (memory (export "memory-2-inf") 2)
+ (memory (export "memory-2-4") 2 4)
+)`);
+
+// ./test/core/multi-memory/imports3.wast:18
+register($0, `test`);
+
+// ./test/core/multi-memory/imports3.wast:19
+assert_unlinkable(
+ () => instantiate(`(module
+ (import "test" "memory-2-4" (memory 1))
+ (import "test" "func-i32" (memory 1))
+ )`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports3.wast:26
+assert_unlinkable(
+ () => instantiate(`(module
+ (import "test" "memory-2-4" (memory 1))
+ (import "test" "global-i32" (memory 1))
+ )`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports3.wast:33
+assert_unlinkable(
+ () => instantiate(`(module
+ (import "test" "memory-2-4" (memory 1))
+ (import "test" "table-10-inf" (memory 1))
+ )`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports3.wast:40
+assert_unlinkable(
+ () => instantiate(`(module
+ (import "test" "memory-2-4" (memory 1))
+ (import "spectest" "print_i32" (memory 1))
+ )`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports3.wast:47
+assert_unlinkable(
+ () => instantiate(`(module
+ (import "test" "memory-2-4" (memory 1))
+ (import "spectest" "global_i32" (memory 1))
+ )`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports3.wast:54
+assert_unlinkable(
+ () => instantiate(`(module
+ (import "test" "memory-2-4" (memory 1))
+ (import "spectest" "table" (memory 1))
+ )`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports3.wast:62
+assert_unlinkable(
+ () => instantiate(`(module
+ (import "test" "memory-2-4" (memory 1))
+ (import "spectest" "memory" (memory 2))
+ )`),
+ `incompatible import type`,
+);
+
+// ./test/core/multi-memory/imports3.wast:69
+assert_unlinkable(
+ () => instantiate(`(module
+ (import "test" "memory-2-4" (memory 1))
+ (import "spectest" "memory" (memory 1 1))
+ )`),
+ `incompatible import type`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/imports4.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/imports4.wast.js
new file mode 100644
index 0000000000..86320fe685
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/imports4.wast.js
@@ -0,0 +1,93 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/imports4.wast
+
+// ./test/core/multi-memory/imports4.wast:1
+let $0 = instantiate(`(module
+ (memory (export "memory-2-inf") 2)
+ (memory (export "memory-2-4") 2 4)
+)`);
+
+// ./test/core/multi-memory/imports4.wast:6
+register($0, `test`);
+
+// ./test/core/multi-memory/imports4.wast:8
+let $1 = instantiate(`(module
+ (import "test" "memory-2-4" (memory 1))
+ (memory $$m (import "spectest" "memory") 0 3) ;; actual has max size 2
+ (func (export "grow") (param i32) (result i32) (memory.grow $$m (local.get 0)))
+)`);
+
+// ./test/core/multi-memory/imports4.wast:13
+assert_return(() => invoke($1, `grow`, [0]), [value("i32", 1)]);
+
+// ./test/core/multi-memory/imports4.wast:14
+assert_return(() => invoke($1, `grow`, [1]), [value("i32", 1)]);
+
+// ./test/core/multi-memory/imports4.wast:15
+assert_return(() => invoke($1, `grow`, [0]), [value("i32", 2)]);
+
+// ./test/core/multi-memory/imports4.wast:16
+assert_return(() => invoke($1, `grow`, [1]), [value("i32", -1)]);
+
+// ./test/core/multi-memory/imports4.wast:17
+assert_return(() => invoke($1, `grow`, [0]), [value("i32", 2)]);
+
+// ./test/core/multi-memory/imports4.wast:19
+let $2 = instantiate(`(module $$Mgm
+ (memory 0)
+ (memory 0)
+ (memory $$m (export "memory") 1) ;; initial size is 1
+ (func (export "grow") (result i32) (memory.grow $$m (i32.const 1)))
+)`);
+register($2, `Mgm`);
+
+// ./test/core/multi-memory/imports4.wast:25
+register(`Mgm`, `grown-memory`);
+
+// ./test/core/multi-memory/imports4.wast:26
+assert_return(() => invoke(`Mgm`, `grow`, []), [value("i32", 1)]);
+
+// ./test/core/multi-memory/imports4.wast:28
+let $3 = instantiate(`(module $$Mgim1
+ ;; imported memory limits should match, because external memory size is 2 now
+ (import "test" "memory-2-4" (memory 1))
+ (memory $$m (export "memory") (import "grown-memory" "memory") 2)
+ (memory 0)
+ (memory 0)
+ (func (export "grow") (result i32) (memory.grow $$m (i32.const 1)))
+)`);
+register($3, `Mgim1`);
+
+// ./test/core/multi-memory/imports4.wast:36
+register(`Mgim1`, `grown-imported-memory`);
+
+// ./test/core/multi-memory/imports4.wast:37
+assert_return(() => invoke(`Mgim1`, `grow`, []), [value("i32", 2)]);
+
+// ./test/core/multi-memory/imports4.wast:39
+let $4 = instantiate(`(module $$Mgim2
+ ;; imported memory limits should match, because external memory size is 3 now
+ (import "test" "memory-2-4" (memory 1))
+ (memory $$m (import "grown-imported-memory" "memory") 3)
+ (memory 0)
+ (memory 0)
+ (func (export "size") (result i32) (memory.size $$m))
+)`);
+register($4, `Mgim2`);
+
+// ./test/core/multi-memory/imports4.wast:47
+assert_return(() => invoke(`Mgim2`, `size`, []), [value("i32", 3)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/linking0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/linking0.wast.js
new file mode 100644
index 0000000000..64c4680a48
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/linking0.wast.js
@@ -0,0 +1,68 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/linking0.wast
+
+// ./test/core/multi-memory/linking0.wast:1
+let $0 = instantiate(`(module $$Mt
+ (type (func (result i32)))
+ (type (func))
+
+ (table (export "tab") 10 funcref)
+ (elem (i32.const 2) $$g $$g $$g $$g)
+ (func $$g (result i32) (i32.const 4))
+ (func (export "h") (result i32) (i32.const -4))
+
+ (func (export "call") (param i32) (result i32)
+ (call_indirect (type 0) (local.get 0))
+ )
+)`);
+register($0, `Mt`);
+
+// ./test/core/multi-memory/linking0.wast:14
+register(`Mt`, `Mt`);
+
+// ./test/core/multi-memory/linking0.wast:16
+assert_unlinkable(
+ () => instantiate(`(module
+ (table (import "Mt" "tab") 10 funcref)
+ (memory (import "spectest" "memory") 1)
+ (memory (import "Mt" "mem") 1) ;; does not exist
+ (func $$f (result i32) (i32.const 0))
+ (elem (i32.const 7) $$f)
+ (elem (i32.const 9) $$f)
+ )`),
+ `unknown import`,
+);
+
+// ./test/core/multi-memory/linking0.wast:27
+assert_trap(() => invoke(`Mt`, `call`, [7]), `uninitialized element`);
+
+// ./test/core/multi-memory/linking0.wast:30
+assert_trap(
+ () => instantiate(`(module
+ (table (import "Mt" "tab") 10 funcref)
+ (func $$f (result i32) (i32.const 0))
+ (elem (i32.const 7) $$f)
+ (memory 0)
+ (memory $$m 1)
+ (memory 0)
+ (data $$m (i32.const 0x10000) "d") ;; out of bounds
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/linking0.wast:42
+assert_return(() => invoke(`Mt`, `call`, [7]), [value("i32", 0)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/linking1.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/linking1.wast.js
new file mode 100644
index 0000000000..aacf570e77
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/linking1.wast.js
@@ -0,0 +1,104 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/linking1.wast
+
+// ./test/core/multi-memory/linking1.wast:1
+let $0 = instantiate(`(module $$Mm
+ (memory $$mem0 (export "mem0") 0 0)
+ (memory $$mem1 (export "mem1") 1 5)
+ (memory $$mem2 (export "mem2") 0 0)
+
+ (data (memory 1) (i32.const 10) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09")
+
+ (func (export "load") (param $$a i32) (result i32)
+ (i32.load8_u $$mem1 (local.get 0))
+ )
+)`);
+register($0, `Mm`);
+
+// ./test/core/multi-memory/linking1.wast:12
+register(`Mm`, `Mm`);
+
+// ./test/core/multi-memory/linking1.wast:14
+let $1 = instantiate(`(module $$Nm
+ (func $$loadM (import "Mm" "load") (param i32) (result i32))
+ (memory (import "Mm" "mem0") 0)
+
+ (memory $$m 1)
+ (data (memory 1) (i32.const 10) "\\f0\\f1\\f2\\f3\\f4\\f5")
+
+ (export "Mm.load" (func $$loadM))
+ (func (export "load") (param $$a i32) (result i32)
+ (i32.load8_u $$m (local.get 0))
+ )
+)`);
+register($1, `Nm`);
+
+// ./test/core/multi-memory/linking1.wast:27
+assert_return(() => invoke(`Mm`, `load`, [12]), [value("i32", 2)]);
+
+// ./test/core/multi-memory/linking1.wast:28
+assert_return(() => invoke(`Nm`, `Mm.load`, [12]), [value("i32", 2)]);
+
+// ./test/core/multi-memory/linking1.wast:29
+assert_return(() => invoke(`Nm`, `load`, [12]), [value("i32", 242)]);
+
+// ./test/core/multi-memory/linking1.wast:31
+let $2 = instantiate(`(module $$Om
+ (memory (import "Mm" "mem1") 1)
+ (data (i32.const 5) "\\a0\\a1\\a2\\a3\\a4\\a5\\a6\\a7")
+
+ (func (export "load") (param $$a i32) (result i32)
+ (i32.load8_u (local.get 0))
+ )
+)`);
+register($2, `Om`);
+
+// ./test/core/multi-memory/linking1.wast:40
+assert_return(() => invoke(`Mm`, `load`, [12]), [value("i32", 167)]);
+
+// ./test/core/multi-memory/linking1.wast:41
+assert_return(() => invoke(`Nm`, `Mm.load`, [12]), [value("i32", 167)]);
+
+// ./test/core/multi-memory/linking1.wast:42
+assert_return(() => invoke(`Nm`, `load`, [12]), [value("i32", 242)]);
+
+// ./test/core/multi-memory/linking1.wast:43
+assert_return(() => invoke(`Om`, `load`, [12]), [value("i32", 167)]);
+
+// ./test/core/multi-memory/linking1.wast:45
+let $3 = instantiate(`(module
+ (memory (import "Mm" "mem1") 0)
+ (data (i32.const 0xffff) "a")
+)`);
+
+// ./test/core/multi-memory/linking1.wast:50
+assert_trap(
+ () => instantiate(`(module
+ (memory (import "Mm" "mem0") 0)
+ (data (i32.const 0xffff) "a")
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/linking1.wast:58
+assert_trap(
+ () => instantiate(`(module
+ (memory (import "Mm" "mem1") 0)
+ (data (i32.const 0x10000) "a")
+ )`),
+ `out of bounds memory access`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/linking2.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/linking2.wast.js
new file mode 100644
index 0000000000..8dacb51e9d
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/linking2.wast.js
@@ -0,0 +1,67 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/linking2.wast
+
+// ./test/core/multi-memory/linking2.wast:1
+let $0 = instantiate(`(module $$Mm
+ (memory $$mem0 (export "mem0") 0 0)
+ (memory $$mem1 (export "mem1") 1 5)
+ (memory $$mem2 (export "mem2") 0 0)
+
+ (data (memory 1) (i32.const 10) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09")
+
+ (func (export "load") (param $$a i32) (result i32)
+ (i32.load8_u $$mem1 (local.get 0))
+ )
+)`);
+register($0, `Mm`);
+
+// ./test/core/multi-memory/linking2.wast:12
+register(`Mm`, `Mm`);
+
+// ./test/core/multi-memory/linking2.wast:14
+let $1 = instantiate(`(module $$Pm
+ (memory (import "Mm" "mem1") 1 8)
+
+ (func (export "grow") (param $$a i32) (result i32)
+ (memory.grow (local.get 0))
+ )
+)`);
+register($1, `Pm`);
+
+// ./test/core/multi-memory/linking2.wast:22
+assert_return(() => invoke(`Pm`, `grow`, [0]), [value("i32", 1)]);
+
+// ./test/core/multi-memory/linking2.wast:23
+assert_return(() => invoke(`Pm`, `grow`, [2]), [value("i32", 1)]);
+
+// ./test/core/multi-memory/linking2.wast:24
+assert_return(() => invoke(`Pm`, `grow`, [0]), [value("i32", 3)]);
+
+// ./test/core/multi-memory/linking2.wast:25
+assert_return(() => invoke(`Pm`, `grow`, [1]), [value("i32", 3)]);
+
+// ./test/core/multi-memory/linking2.wast:26
+assert_return(() => invoke(`Pm`, `grow`, [1]), [value("i32", 4)]);
+
+// ./test/core/multi-memory/linking2.wast:27
+assert_return(() => invoke(`Pm`, `grow`, [0]), [value("i32", 5)]);
+
+// ./test/core/multi-memory/linking2.wast:28
+assert_return(() => invoke(`Pm`, `grow`, [1]), [value("i32", -1)]);
+
+// ./test/core/multi-memory/linking2.wast:29
+assert_return(() => invoke(`Pm`, `grow`, [0]), [value("i32", 5)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/linking3.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/linking3.wast.js
new file mode 100644
index 0000000000..0f6d60bacd
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/linking3.wast.js
@@ -0,0 +1,120 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/linking3.wast
+
+// ./test/core/multi-memory/linking3.wast:1
+let $0 = instantiate(`(module $$Mm
+ (memory $$mem0 (export "mem0") 0 0)
+ (memory $$mem1 (export "mem1") 5 5)
+ (memory $$mem2 (export "mem2") 0 0)
+
+ (data (memory 1) (i32.const 10) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09")
+
+ (func (export "load") (param $$a i32) (result i32)
+ (i32.load8_u $$mem1 (local.get 0))
+ )
+)`);
+register($0, `Mm`);
+
+// ./test/core/multi-memory/linking3.wast:12
+register(`Mm`, `Mm`);
+
+// ./test/core/multi-memory/linking3.wast:14
+assert_unlinkable(
+ () => instantiate(`(module
+ (func $$host (import "spectest" "print"))
+ (memory (import "Mm" "mem1") 1)
+ (table (import "Mm" "tab") 0 funcref) ;; does not exist
+ (data (i32.const 0) "abc")
+ )`),
+ `unknown import`,
+);
+
+// ./test/core/multi-memory/linking3.wast:23
+assert_return(() => invoke(`Mm`, `load`, [0]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/linking3.wast:27
+assert_trap(
+ () => instantiate(`(module
+ ;; Note: the memory is 5 pages large by the time we get here.
+ (memory (import "Mm" "mem1") 1)
+ (data (i32.const 0) "abc")
+ (data (i32.const 327670) "zzzzzzzzzzzzzzzzzz") ;; (partially) out of bounds
+ )`),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/linking3.wast:36
+assert_return(() => invoke(`Mm`, `load`, [0]), [value("i32", 97)]);
+
+// ./test/core/multi-memory/linking3.wast:37
+assert_return(() => invoke(`Mm`, `load`, [327670]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/linking3.wast:39
+assert_trap(
+ () => instantiate(`(module
+ (memory (import "Mm" "mem1") 1)
+ (data (i32.const 0) "abc")
+ (table 0 funcref)
+ (func)
+ (elem (i32.const 0) 0) ;; out of bounds
+ )`),
+ `out of bounds table access`,
+);
+
+// ./test/core/multi-memory/linking3.wast:49
+assert_return(() => invoke(`Mm`, `load`, [0]), [value("i32", 97)]);
+
+// ./test/core/multi-memory/linking3.wast:52
+let $1 = instantiate(`(module $$Ms
+ (type $$t (func (result i32)))
+ (memory (export "memory") 1)
+ (table (export "table") 1 funcref)
+ (func (export "get memory[0]") (type $$t)
+ (i32.load8_u (i32.const 0))
+ )
+ (func (export "get table[0]") (type $$t)
+ (call_indirect (type $$t) (i32.const 0))
+ )
+)`);
+register($1, `Ms`);
+
+// ./test/core/multi-memory/linking3.wast:63
+register(`Ms`, `Ms`);
+
+// ./test/core/multi-memory/linking3.wast:65
+assert_trap(
+ () => instantiate(`(module
+ (import "Ms" "memory" (memory 1))
+ (import "Ms" "table" (table 1 funcref))
+ (data (i32.const 0) "hello")
+ (elem (i32.const 0) $$f)
+ (func $$f (result i32)
+ (i32.const 0xdead)
+ )
+ (func $$main
+ (unreachable)
+ )
+ (start $$main)
+ )`),
+ `unreachable`,
+);
+
+// ./test/core/multi-memory/linking3.wast:82
+assert_return(() => invoke(`Ms`, `get memory[0]`, []), [value("i32", 104)]);
+
+// ./test/core/multi-memory/linking3.wast:83
+assert_return(() => invoke(`Ms`, `get table[0]`, []), [value("i32", 57005)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/load.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/load.wast.js
new file mode 100644
index 0000000000..79d90437b9
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/load.wast.js
@@ -0,0 +1,845 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/load.wast
+
+// ./test/core/load.wast:3
+let $0 = instantiate(`(module
+ (memory $$mem1 1)
+ (memory $$mem2 1)
+
+ (func (export "load1") (param i32) (result i64)
+ (i64.load $$mem1 (local.get 0))
+ )
+ (func (export "load2") (param i32) (result i64)
+ (i64.load $$mem2 (local.get 0))
+ )
+
+ (data (memory $$mem1) (i32.const 0) "\\01")
+ (data (memory $$mem2) (i32.const 0) "\\02")
+)`);
+
+// ./test/core/load.wast:18
+assert_return(() => invoke($0, `load1`, [0]), [value("i64", 1n)]);
+
+// ./test/core/load.wast:19
+assert_return(() => invoke($0, `load2`, [0]), [value("i64", 2n)]);
+
+// ./test/core/load.wast:22
+let $1 = instantiate(`(module $$M
+ (memory (export "mem") 2)
+
+ (func (export "read") (param i32) (result i32)
+ (i32.load8_u (local.get 0))
+ )
+)`);
+register($1, `M`);
+
+// ./test/core/load.wast:29
+register($1, `M`);
+
+// ./test/core/load.wast:31
+let $2 = instantiate(`(module
+ (memory $$mem1 (import "M" "mem") 2)
+ (memory $$mem2 3)
+
+ (data (memory $$mem1) (i32.const 20) "\\01\\02\\03\\04\\05")
+ (data (memory $$mem2) (i32.const 50) "\\0A\\0B\\0C\\0D\\0E")
+
+ (func (export "read1") (param i32) (result i32)
+ (i32.load8_u $$mem1 (local.get 0))
+ )
+ (func (export "read2") (param i32) (result i32)
+ (i32.load8_u $$mem2 (local.get 0))
+ )
+)`);
+
+// ./test/core/load.wast:46
+assert_return(() => invoke(`M`, `read`, [20]), [value("i32", 1)]);
+
+// ./test/core/load.wast:47
+assert_return(() => invoke(`M`, `read`, [21]), [value("i32", 2)]);
+
+// ./test/core/load.wast:48
+assert_return(() => invoke(`M`, `read`, [22]), [value("i32", 3)]);
+
+// ./test/core/load.wast:49
+assert_return(() => invoke(`M`, `read`, [23]), [value("i32", 4)]);
+
+// ./test/core/load.wast:50
+assert_return(() => invoke(`M`, `read`, [24]), [value("i32", 5)]);
+
+// ./test/core/load.wast:52
+assert_return(() => invoke($2, `read1`, [20]), [value("i32", 1)]);
+
+// ./test/core/load.wast:53
+assert_return(() => invoke($2, `read1`, [21]), [value("i32", 2)]);
+
+// ./test/core/load.wast:54
+assert_return(() => invoke($2, `read1`, [22]), [value("i32", 3)]);
+
+// ./test/core/load.wast:55
+assert_return(() => invoke($2, `read1`, [23]), [value("i32", 4)]);
+
+// ./test/core/load.wast:56
+assert_return(() => invoke($2, `read1`, [24]), [value("i32", 5)]);
+
+// ./test/core/load.wast:58
+assert_return(() => invoke($2, `read2`, [50]), [value("i32", 10)]);
+
+// ./test/core/load.wast:59
+assert_return(() => invoke($2, `read2`, [51]), [value("i32", 11)]);
+
+// ./test/core/load.wast:60
+assert_return(() => invoke($2, `read2`, [52]), [value("i32", 12)]);
+
+// ./test/core/load.wast:61
+assert_return(() => invoke($2, `read2`, [53]), [value("i32", 13)]);
+
+// ./test/core/load.wast:62
+assert_return(() => invoke($2, `read2`, [54]), [value("i32", 14)]);
+
+// ./test/core/load.wast:67
+let $3 = instantiate(`(module
+ (memory 1)
+
+ (func (export "as-br-value") (result i32)
+ (block (result i32) (br 0 (i32.load (i32.const 0))))
+ )
+
+ (func (export "as-br_if-cond")
+ (block (br_if 0 (i32.load (i32.const 0))))
+ )
+ (func (export "as-br_if-value") (result i32)
+ (block (result i32)
+ (drop (br_if 0 (i32.load (i32.const 0)) (i32.const 1))) (i32.const 7)
+ )
+ )
+ (func (export "as-br_if-value-cond") (result i32)
+ (block (result i32)
+ (drop (br_if 0 (i32.const 6) (i32.load (i32.const 0)))) (i32.const 7)
+ )
+ )
+
+ (func (export "as-br_table-index")
+ (block (br_table 0 0 0 (i32.load (i32.const 0))))
+ )
+ (func (export "as-br_table-value") (result i32)
+ (block (result i32)
+ (br_table 0 0 0 (i32.load (i32.const 0)) (i32.const 1)) (i32.const 7)
+ )
+ )
+ (func (export "as-br_table-value-index") (result i32)
+ (block (result i32)
+ (br_table 0 0 (i32.const 6) (i32.load (i32.const 0))) (i32.const 7)
+ )
+ )
+
+ (func (export "as-return-value") (result i32)
+ (return (i32.load (i32.const 0)))
+ )
+
+ (func (export "as-if-cond") (result i32)
+ (if (result i32) (i32.load (i32.const 0))
+ (then (i32.const 0)) (else (i32.const 1))
+ )
+ )
+ (func (export "as-if-then") (result i32)
+ (if (result i32) (i32.const 1)
+ (then (i32.load (i32.const 0))) (else (i32.const 0))
+ )
+ )
+ (func (export "as-if-else") (result i32)
+ (if (result i32) (i32.const 0)
+ (then (i32.const 0)) (else (i32.load (i32.const 0)))
+ )
+ )
+
+ (func (export "as-select-first") (param i32 i32) (result i32)
+ (select (i32.load (i32.const 0)) (local.get 0) (local.get 1))
+ )
+ (func (export "as-select-second") (param i32 i32) (result i32)
+ (select (local.get 0) (i32.load (i32.const 0)) (local.get 1))
+ )
+ (func (export "as-select-cond") (result i32)
+ (select (i32.const 0) (i32.const 1) (i32.load (i32.const 0)))
+ )
+
+ (func $$f (param i32 i32 i32) (result i32) (i32.const -1))
+ (func (export "as-call-first") (result i32)
+ (call $$f (i32.load (i32.const 0)) (i32.const 2) (i32.const 3))
+ )
+ (func (export "as-call-mid") (result i32)
+ (call $$f (i32.const 1) (i32.load (i32.const 0)) (i32.const 3))
+ )
+ (func (export "as-call-last") (result i32)
+ (call $$f (i32.const 1) (i32.const 2) (i32.load (i32.const 0)))
+ )
+
+ (type $$sig (func (param i32 i32 i32) (result i32)))
+ (table funcref (elem $$f))
+ (func (export "as-call_indirect-first") (result i32)
+ (call_indirect (type $$sig)
+ (i32.load (i32.const 0)) (i32.const 2) (i32.const 3) (i32.const 0)
+ )
+ )
+ (func (export "as-call_indirect-mid") (result i32)
+ (call_indirect (type $$sig)
+ (i32.const 1) (i32.load (i32.const 0)) (i32.const 3) (i32.const 0)
+ )
+ )
+ (func (export "as-call_indirect-last") (result i32)
+ (call_indirect (type $$sig)
+ (i32.const 1) (i32.const 2) (i32.load (i32.const 0)) (i32.const 0)
+ )
+ )
+ (func (export "as-call_indirect-index") (result i32)
+ (call_indirect (type $$sig)
+ (i32.const 1) (i32.const 2) (i32.const 3) (i32.load (i32.const 0))
+ )
+ )
+
+ (func (export "as-local.set-value") (local i32)
+ (local.set 0 (i32.load (i32.const 0)))
+ )
+ (func (export "as-local.tee-value") (result i32) (local i32)
+ (local.tee 0 (i32.load (i32.const 0)))
+ )
+ (global $$g (mut i32) (i32.const 0))
+ (func (export "as-global.set-value") (local i32)
+ (global.set $$g (i32.load (i32.const 0)))
+ )
+
+ (func (export "as-load-address") (result i32)
+ (i32.load (i32.load (i32.const 0)))
+ )
+ (func (export "as-loadN-address") (result i32)
+ (i32.load8_s (i32.load (i32.const 0)))
+ )
+
+ (func (export "as-store-address")
+ (i32.store (i32.load (i32.const 0)) (i32.const 7))
+ )
+ (func (export "as-store-value")
+ (i32.store (i32.const 2) (i32.load (i32.const 0)))
+ )
+
+ (func (export "as-storeN-address")
+ (i32.store8 (i32.load8_s (i32.const 0)) (i32.const 7))
+ )
+ (func (export "as-storeN-value")
+ (i32.store16 (i32.const 2) (i32.load (i32.const 0)))
+ )
+
+ (func (export "as-unary-operand") (result i32)
+ (i32.clz (i32.load (i32.const 100)))
+ )
+
+ (func (export "as-binary-left") (result i32)
+ (i32.add (i32.load (i32.const 100)) (i32.const 10))
+ )
+ (func (export "as-binary-right") (result i32)
+ (i32.sub (i32.const 10) (i32.load (i32.const 100)))
+ )
+
+ (func (export "as-test-operand") (result i32)
+ (i32.eqz (i32.load (i32.const 100)))
+ )
+
+ (func (export "as-compare-left") (result i32)
+ (i32.le_s (i32.load (i32.const 100)) (i32.const 10))
+ )
+ (func (export "as-compare-right") (result i32)
+ (i32.ne (i32.const 10) (i32.load (i32.const 100)))
+ )
+
+ (func (export "as-memory.grow-size") (result i32)
+ (memory.grow (i32.load (i32.const 100)))
+ )
+)`);
+
+// ./test/core/load.wast:225
+assert_return(() => invoke($3, `as-br-value`, []), [value("i32", 0)]);
+
+// ./test/core/load.wast:227
+assert_return(() => invoke($3, `as-br_if-cond`, []), []);
+
+// ./test/core/load.wast:228
+assert_return(() => invoke($3, `as-br_if-value`, []), [value("i32", 0)]);
+
+// ./test/core/load.wast:229
+assert_return(() => invoke($3, `as-br_if-value-cond`, []), [value("i32", 7)]);
+
+// ./test/core/load.wast:231
+assert_return(() => invoke($3, `as-br_table-index`, []), []);
+
+// ./test/core/load.wast:232
+assert_return(() => invoke($3, `as-br_table-value`, []), [value("i32", 0)]);
+
+// ./test/core/load.wast:233
+assert_return(() => invoke($3, `as-br_table-value-index`, []), [value("i32", 6)]);
+
+// ./test/core/load.wast:235
+assert_return(() => invoke($3, `as-return-value`, []), [value("i32", 0)]);
+
+// ./test/core/load.wast:237
+assert_return(() => invoke($3, `as-if-cond`, []), [value("i32", 1)]);
+
+// ./test/core/load.wast:238
+assert_return(() => invoke($3, `as-if-then`, []), [value("i32", 0)]);
+
+// ./test/core/load.wast:239
+assert_return(() => invoke($3, `as-if-else`, []), [value("i32", 0)]);
+
+// ./test/core/load.wast:241
+assert_return(() => invoke($3, `as-select-first`, [0, 1]), [value("i32", 0)]);
+
+// ./test/core/load.wast:242
+assert_return(() => invoke($3, `as-select-second`, [0, 0]), [value("i32", 0)]);
+
+// ./test/core/load.wast:243
+assert_return(() => invoke($3, `as-select-cond`, []), [value("i32", 1)]);
+
+// ./test/core/load.wast:245
+assert_return(() => invoke($3, `as-call-first`, []), [value("i32", -1)]);
+
+// ./test/core/load.wast:246
+assert_return(() => invoke($3, `as-call-mid`, []), [value("i32", -1)]);
+
+// ./test/core/load.wast:247
+assert_return(() => invoke($3, `as-call-last`, []), [value("i32", -1)]);
+
+// ./test/core/load.wast:249
+assert_return(() => invoke($3, `as-call_indirect-first`, []), [value("i32", -1)]);
+
+// ./test/core/load.wast:250
+assert_return(() => invoke($3, `as-call_indirect-mid`, []), [value("i32", -1)]);
+
+// ./test/core/load.wast:251
+assert_return(() => invoke($3, `as-call_indirect-last`, []), [value("i32", -1)]);
+
+// ./test/core/load.wast:252
+assert_return(() => invoke($3, `as-call_indirect-index`, []), [value("i32", -1)]);
+
+// ./test/core/load.wast:254
+assert_return(() => invoke($3, `as-local.set-value`, []), []);
+
+// ./test/core/load.wast:255
+assert_return(() => invoke($3, `as-local.tee-value`, []), [value("i32", 0)]);
+
+// ./test/core/load.wast:256
+assert_return(() => invoke($3, `as-global.set-value`, []), []);
+
+// ./test/core/load.wast:258
+assert_return(() => invoke($3, `as-load-address`, []), [value("i32", 0)]);
+
+// ./test/core/load.wast:259
+assert_return(() => invoke($3, `as-loadN-address`, []), [value("i32", 0)]);
+
+// ./test/core/load.wast:260
+assert_return(() => invoke($3, `as-store-address`, []), []);
+
+// ./test/core/load.wast:261
+assert_return(() => invoke($3, `as-store-value`, []), []);
+
+// ./test/core/load.wast:262
+assert_return(() => invoke($3, `as-storeN-address`, []), []);
+
+// ./test/core/load.wast:263
+assert_return(() => invoke($3, `as-storeN-value`, []), []);
+
+// ./test/core/load.wast:265
+assert_return(() => invoke($3, `as-unary-operand`, []), [value("i32", 32)]);
+
+// ./test/core/load.wast:267
+assert_return(() => invoke($3, `as-binary-left`, []), [value("i32", 10)]);
+
+// ./test/core/load.wast:268
+assert_return(() => invoke($3, `as-binary-right`, []), [value("i32", 10)]);
+
+// ./test/core/load.wast:270
+assert_return(() => invoke($3, `as-test-operand`, []), [value("i32", 1)]);
+
+// ./test/core/load.wast:272
+assert_return(() => invoke($3, `as-compare-left`, []), [value("i32", 1)]);
+
+// ./test/core/load.wast:273
+assert_return(() => invoke($3, `as-compare-right`, []), [value("i32", 1)]);
+
+// ./test/core/load.wast:275
+assert_return(() => invoke($3, `as-memory.grow-size`, []), [value("i32", 1)]);
+
+// ./test/core/load.wast:277
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (result i32) (i32.load32 (local.get 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/load.wast:284
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (result i32) (i32.load32_u (local.get 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/load.wast:291
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (result i32) (i32.load32_s (local.get 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/load.wast:298
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (result i32) (i32.load64 (local.get 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/load.wast:305
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (result i32) (i32.load64_u (local.get 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/load.wast:312
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (result i32) (i32.load64_s (local.get 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/load.wast:320
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (result i64) (i64.load64 (local.get 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/load.wast:327
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (result i64) (i64.load64_u (local.get 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/load.wast:334
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (result i64) (i64.load64_s (local.get 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/load.wast:342
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (result f32) (f32.load32 (local.get 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/load.wast:349
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (result f32) (f32.load64 (local.get 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/load.wast:357
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (result f64) (f64.load32 (local.get 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/load.wast:364
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (result f64) (f64.load64 (local.get 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/load.wast:375
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load_i32 (i32.load (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:379
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load8_s_i32 (i32.load8_s (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:383
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load8_u_i32 (i32.load8_u (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:387
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load16_s_i32 (i32.load16_s (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:391
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load16_u_i32 (i32.load16_u (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:395
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load_i64 (i64.load (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:399
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load8_s_i64 (i64.load8_s (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:403
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load8_u_i64 (i64.load8_u (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:407
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load16_s_i64 (i64.load16_s (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:411
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load16_u_i64 (i64.load16_u (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:415
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load32_s_i64 (i64.load32_s (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:419
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load32_u_i64 (i64.load32_u (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:423
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load_f32 (f32.load (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:427
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func $$load_f64 (f64.load (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:435
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result i32) (i32.load (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:436
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result i32) (i32.load8_s (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:437
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result i32) (i32.load8_u (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:438
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result i32) (i32.load16_s (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:439
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result i32) (i32.load16_u (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:440
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result i64) (i64.load (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:441
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result i64) (i64.load8_s (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:442
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result i64) (i64.load8_u (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:443
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result i64) (i64.load16_s (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:444
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result i64) (i64.load16_u (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:445
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result i64) (i64.load32_s (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:446
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result i64) (i64.load32_u (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:447
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result f32) (f32.load (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:448
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result f64) (f64.load (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:451
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty
+ (i32.load) (drop)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:460
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-block
+ (i32.const 0)
+ (block (i32.load) (drop))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:470
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-loop
+ (i32.const 0)
+ (loop (i32.load) (drop))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:480
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-then
+ (i32.const 0) (i32.const 0)
+ (if (then (i32.load) (drop)))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:490
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-else
+ (i32.const 0) (i32.const 0)
+ (if (result i32) (then (i32.const 0)) (else (i32.load))) (drop)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:500
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-br
+ (i32.const 0)
+ (block (br 0 (i32.load)) (drop))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:510
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-br_if
+ (i32.const 0)
+ (block (br_if 0 (i32.load) (i32.const 1)) (drop))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:520
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-br_table
+ (i32.const 0)
+ (block (br_table 0 (i32.load)) (drop))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:530
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-return
+ (return (i32.load)) (drop)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:539
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-select
+ (select (i32.load) (i32.const 1) (i32.const 2)) (drop)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:548
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-call
+ (call 1 (i32.load)) (drop)
+ )
+ (func (param i32) (result i32) (local.get 0))
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:558
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$f (param i32) (result i32) (local.get 0))
+ (type $$sig (func (param i32) (result i32)))
+ (table funcref (elem $$f))
+ (func $$type-address-empty-in-call_indirect
+ (block (result i32)
+ (call_indirect (type $$sig)
+ (i32.load) (i32.const 0)
+ )
+ (drop)
+ )
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:575
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-local.set
+ (local i32)
+ (local.set 0 (i32.load)) (local.get 0) (drop)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:585
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-local.tee
+ (local i32)
+ (local.tee 0 (i32.load)) (drop)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:595
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (global $$x (mut i32) (i32.const 0))
+ (func $$type-address-empty-in-global.set
+ (global.set $$x (i32.load)) (global.get $$x) (drop)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:605
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-memory.grow
+ (memory.grow (i32.load)) (drop)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:614
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-address-empty-in-load
+ (i32.load (i32.load)) (drop)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/load.wast:623
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-address-empty-in-store
+ (i32.store (i32.load) (i32.const 1))
+ )
+ )`),
+ `type mismatch`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/load0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/load0.wast.js
new file mode 100644
index 0000000000..67638b1111
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/load0.wast.js
@@ -0,0 +1,38 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/load0.wast
+
+// ./test/core/multi-memory/load0.wast:3
+let $0 = instantiate(`(module
+ (memory $$mem1 1)
+ (memory $$mem2 1)
+
+ (func (export "load1") (param i32) (result i64)
+ (i64.load $$mem1 (local.get 0))
+ )
+ (func (export "load2") (param i32) (result i64)
+ (i64.load $$mem2 (local.get 0))
+ )
+
+ (data (memory $$mem1) (i32.const 0) "\\01")
+ (data (memory $$mem2) (i32.const 0) "\\02")
+)`);
+
+// ./test/core/multi-memory/load0.wast:18
+assert_return(() => invoke($0, `load1`, [0]), [value("i64", 1n)]);
+
+// ./test/core/multi-memory/load0.wast:19
+assert_return(() => invoke($0, `load2`, [0]), [value("i64", 2n)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/load1.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/load1.wast.js
new file mode 100644
index 0000000000..6ba5204bc7
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/load1.wast.js
@@ -0,0 +1,90 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/load1.wast
+
+// ./test/core/multi-memory/load1.wast:1
+let $0 = instantiate(`(module $$M
+ (memory (export "mem") 2)
+
+ (func (export "read") (param i32) (result i32)
+ (i32.load8_u (local.get 0))
+ )
+)`);
+register($0, `M`);
+
+// ./test/core/multi-memory/load1.wast:8
+register($0, `M`);
+
+// ./test/core/multi-memory/load1.wast:10
+let $1 = instantiate(`(module
+ (memory $$mem1 (import "M" "mem") 2)
+ (memory $$mem2 3)
+
+ (data (memory $$mem1) (i32.const 20) "\\01\\02\\03\\04\\05")
+ (data (memory $$mem2) (i32.const 50) "\\0A\\0B\\0C\\0D\\0E")
+
+ (func (export "read1") (param i32) (result i32)
+ (i32.load8_u $$mem1 (local.get 0))
+ )
+ (func (export "read2") (param i32) (result i32)
+ (i32.load8_u $$mem2 (local.get 0))
+ )
+)`);
+
+// ./test/core/multi-memory/load1.wast:25
+assert_return(() => invoke(`M`, `read`, [20]), [value("i32", 1)]);
+
+// ./test/core/multi-memory/load1.wast:26
+assert_return(() => invoke(`M`, `read`, [21]), [value("i32", 2)]);
+
+// ./test/core/multi-memory/load1.wast:27
+assert_return(() => invoke(`M`, `read`, [22]), [value("i32", 3)]);
+
+// ./test/core/multi-memory/load1.wast:28
+assert_return(() => invoke(`M`, `read`, [23]), [value("i32", 4)]);
+
+// ./test/core/multi-memory/load1.wast:29
+assert_return(() => invoke(`M`, `read`, [24]), [value("i32", 5)]);
+
+// ./test/core/multi-memory/load1.wast:31
+assert_return(() => invoke($1, `read1`, [20]), [value("i32", 1)]);
+
+// ./test/core/multi-memory/load1.wast:32
+assert_return(() => invoke($1, `read1`, [21]), [value("i32", 2)]);
+
+// ./test/core/multi-memory/load1.wast:33
+assert_return(() => invoke($1, `read1`, [22]), [value("i32", 3)]);
+
+// ./test/core/multi-memory/load1.wast:34
+assert_return(() => invoke($1, `read1`, [23]), [value("i32", 4)]);
+
+// ./test/core/multi-memory/load1.wast:35
+assert_return(() => invoke($1, `read1`, [24]), [value("i32", 5)]);
+
+// ./test/core/multi-memory/load1.wast:37
+assert_return(() => invoke($1, `read2`, [50]), [value("i32", 10)]);
+
+// ./test/core/multi-memory/load1.wast:38
+assert_return(() => invoke($1, `read2`, [51]), [value("i32", 11)]);
+
+// ./test/core/multi-memory/load1.wast:39
+assert_return(() => invoke($1, `read2`, [52]), [value("i32", 12)]);
+
+// ./test/core/multi-memory/load1.wast:40
+assert_return(() => invoke($1, `read2`, [53]), [value("i32", 13)]);
+
+// ./test/core/multi-memory/load1.wast:41
+assert_return(() => invoke($1, `read2`, [54]), [value("i32", 14)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/load2.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/load2.wast.js
new file mode 100644
index 0000000000..de549b845f
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/load2.wast.js
@@ -0,0 +1,289 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/load2.wast
+
+// ./test/core/multi-memory/load2.wast:1
+let $0 = instantiate(`(module
+ (memory 0)
+ (memory 0)
+ (memory 0)
+ (memory $$m 1)
+
+ (func (export "as-br-value") (result i32)
+ (block (result i32) (br 0 (i32.load $$m (i32.const 0))))
+ )
+
+ (func (export "as-br_if-cond")
+ (block (br_if 0 (i32.load $$m (i32.const 0))))
+ )
+ (func (export "as-br_if-value") (result i32)
+ (block (result i32)
+ (drop (br_if 0 (i32.load $$m (i32.const 0)) (i32.const 1))) (i32.const 7)
+ )
+ )
+ (func (export "as-br_if-value-cond") (result i32)
+ (block (result i32)
+ (drop (br_if 0 (i32.const 6) (i32.load $$m (i32.const 0)))) (i32.const 7)
+ )
+ )
+
+ (func (export "as-br_table-index")
+ (block (br_table 0 0 0 (i32.load $$m (i32.const 0))))
+ )
+ (func (export "as-br_table-value") (result i32)
+ (block (result i32)
+ (br_table 0 0 0 (i32.load $$m (i32.const 0)) (i32.const 1)) (i32.const 7)
+ )
+ )
+ (func (export "as-br_table-value-index") (result i32)
+ (block (result i32)
+ (br_table 0 0 (i32.const 6) (i32.load $$m (i32.const 0))) (i32.const 7)
+ )
+ )
+
+ (func (export "as-return-value") (result i32)
+ (return (i32.load $$m (i32.const 0)))
+ )
+
+ (func (export "as-if-cond") (result i32)
+ (if (result i32) (i32.load $$m (i32.const 0))
+ (then (i32.const 0)) (else (i32.const 1))
+ )
+ )
+ (func (export "as-if-then") (result i32)
+ (if (result i32) (i32.const 1)
+ (then (i32.load $$m (i32.const 0))) (else (i32.const 0))
+ )
+ )
+ (func (export "as-if-else") (result i32)
+ (if (result i32) (i32.const 0)
+ (then (i32.const 0)) (else (i32.load $$m (i32.const 0)))
+ )
+ )
+
+ (func (export "as-select-first") (param i32 i32) (result i32)
+ (select (i32.load $$m (i32.const 0)) (local.get 0) (local.get 1))
+ )
+ (func (export "as-select-second") (param i32 i32) (result i32)
+ (select (local.get 0) (i32.load $$m (i32.const 0)) (local.get 1))
+ )
+ (func (export "as-select-cond") (result i32)
+ (select (i32.const 0) (i32.const 1) (i32.load $$m (i32.const 0)))
+ )
+
+ (func $$f (param i32 i32 i32) (result i32) (i32.const -1))
+ (func (export "as-call-first") (result i32)
+ (call $$f (i32.load $$m (i32.const 0)) (i32.const 2) (i32.const 3))
+ )
+ (func (export "as-call-mid") (result i32)
+ (call $$f (i32.const 1) (i32.load $$m (i32.const 0)) (i32.const 3))
+ )
+ (func (export "as-call-last") (result i32)
+ (call $$f (i32.const 1) (i32.const 2) (i32.load $$m (i32.const 0)))
+ )
+
+ (type $$sig (func (param i32 i32 i32) (result i32)))
+ (table funcref (elem $$f))
+ (func (export "as-call_indirect-first") (result i32)
+ (call_indirect (type $$sig)
+ (i32.load $$m (i32.const 0)) (i32.const 2) (i32.const 3) (i32.const 0)
+ )
+ )
+ (func (export "as-call_indirect-mid") (result i32)
+ (call_indirect (type $$sig)
+ (i32.const 1) (i32.load $$m (i32.const 0)) (i32.const 3) (i32.const 0)
+ )
+ )
+ (func (export "as-call_indirect-last") (result i32)
+ (call_indirect (type $$sig)
+ (i32.const 1) (i32.const 2) (i32.load $$m (i32.const 0)) (i32.const 0)
+ )
+ )
+ (func (export "as-call_indirect-index") (result i32)
+ (call_indirect (type $$sig)
+ (i32.const 1) (i32.const 2) (i32.const 3) (i32.load $$m (i32.const 0))
+ )
+ )
+
+ (func (export "as-local.set-value") (local i32)
+ (local.set 0 (i32.load $$m (i32.const 0)))
+ )
+ (func (export "as-local.tee-value") (result i32) (local i32)
+ (local.tee 0 (i32.load $$m (i32.const 0)))
+ )
+ (global $$g (mut i32) (i32.const 0))
+ (func (export "as-global.set-value") (local i32)
+ (global.set $$g (i32.load $$m (i32.const 0)))
+ )
+
+ (func (export "as-load-address") (result i32)
+ (i32.load $$m (i32.load $$m (i32.const 0)))
+ )
+ (func (export "as-loadN-address") (result i32)
+ (i32.load8_s $$m (i32.load $$m (i32.const 0)))
+ )
+
+ (func (export "as-store-address")
+ (i32.store $$m (i32.load $$m (i32.const 0)) (i32.const 7))
+ )
+ (func (export "as-store-value")
+ (i32.store $$m (i32.const 2) (i32.load $$m (i32.const 0)))
+ )
+
+ (func (export "as-storeN-address")
+ (i32.store8 $$m (i32.load8_s $$m (i32.const 0)) (i32.const 7))
+ )
+ (func (export "as-storeN-value")
+ (i32.store16 $$m (i32.const 2) (i32.load $$m (i32.const 0)))
+ )
+
+ (func (export "as-unary-operand") (result i32)
+ (i32.clz (i32.load $$m (i32.const 100)))
+ )
+
+ (func (export "as-binary-left") (result i32)
+ (i32.add (i32.load $$m (i32.const 100)) (i32.const 10))
+ )
+ (func (export "as-binary-right") (result i32)
+ (i32.sub (i32.const 10) (i32.load $$m (i32.const 100)))
+ )
+
+ (func (export "as-test-operand") (result i32)
+ (i32.eqz (i32.load $$m (i32.const 100)))
+ )
+
+ (func (export "as-compare-left") (result i32)
+ (i32.le_s (i32.load $$m (i32.const 100)) (i32.const 10))
+ )
+ (func (export "as-compare-right") (result i32)
+ (i32.ne (i32.const 10) (i32.load $$m (i32.const 100)))
+ )
+
+ (func (export "as-memory.grow-size") (result i32)
+ (memory.grow $$m (i32.load $$m (i32.const 100)))
+ )
+)`);
+
+// ./test/core/multi-memory/load2.wast:162
+assert_return(() => invoke($0, `as-br-value`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/load2.wast:164
+assert_return(() => invoke($0, `as-br_if-cond`, []), []);
+
+// ./test/core/multi-memory/load2.wast:165
+assert_return(() => invoke($0, `as-br_if-value`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/load2.wast:166
+assert_return(() => invoke($0, `as-br_if-value-cond`, []), [value("i32", 7)]);
+
+// ./test/core/multi-memory/load2.wast:168
+assert_return(() => invoke($0, `as-br_table-index`, []), []);
+
+// ./test/core/multi-memory/load2.wast:169
+assert_return(() => invoke($0, `as-br_table-value`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/load2.wast:170
+assert_return(() => invoke($0, `as-br_table-value-index`, []), [value("i32", 6)]);
+
+// ./test/core/multi-memory/load2.wast:172
+assert_return(() => invoke($0, `as-return-value`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/load2.wast:174
+assert_return(() => invoke($0, `as-if-cond`, []), [value("i32", 1)]);
+
+// ./test/core/multi-memory/load2.wast:175
+assert_return(() => invoke($0, `as-if-then`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/load2.wast:176
+assert_return(() => invoke($0, `as-if-else`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/load2.wast:178
+assert_return(() => invoke($0, `as-select-first`, [0, 1]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/load2.wast:179
+assert_return(() => invoke($0, `as-select-second`, [0, 0]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/load2.wast:180
+assert_return(() => invoke($0, `as-select-cond`, []), [value("i32", 1)]);
+
+// ./test/core/multi-memory/load2.wast:182
+assert_return(() => invoke($0, `as-call-first`, []), [value("i32", -1)]);
+
+// ./test/core/multi-memory/load2.wast:183
+assert_return(() => invoke($0, `as-call-mid`, []), [value("i32", -1)]);
+
+// ./test/core/multi-memory/load2.wast:184
+assert_return(() => invoke($0, `as-call-last`, []), [value("i32", -1)]);
+
+// ./test/core/multi-memory/load2.wast:186
+assert_return(() => invoke($0, `as-call_indirect-first`, []), [value("i32", -1)]);
+
+// ./test/core/multi-memory/load2.wast:187
+assert_return(() => invoke($0, `as-call_indirect-mid`, []), [value("i32", -1)]);
+
+// ./test/core/multi-memory/load2.wast:188
+assert_return(() => invoke($0, `as-call_indirect-last`, []), [value("i32", -1)]);
+
+// ./test/core/multi-memory/load2.wast:189
+assert_return(() => invoke($0, `as-call_indirect-index`, []), [value("i32", -1)]);
+
+// ./test/core/multi-memory/load2.wast:191
+assert_return(() => invoke($0, `as-local.set-value`, []), []);
+
+// ./test/core/multi-memory/load2.wast:192
+assert_return(() => invoke($0, `as-local.tee-value`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/load2.wast:193
+assert_return(() => invoke($0, `as-global.set-value`, []), []);
+
+// ./test/core/multi-memory/load2.wast:195
+assert_return(() => invoke($0, `as-load-address`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/load2.wast:196
+assert_return(() => invoke($0, `as-loadN-address`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/load2.wast:197
+assert_return(() => invoke($0, `as-store-address`, []), []);
+
+// ./test/core/multi-memory/load2.wast:198
+assert_return(() => invoke($0, `as-store-value`, []), []);
+
+// ./test/core/multi-memory/load2.wast:199
+assert_return(() => invoke($0, `as-storeN-address`, []), []);
+
+// ./test/core/multi-memory/load2.wast:200
+assert_return(() => invoke($0, `as-storeN-value`, []), []);
+
+// ./test/core/multi-memory/load2.wast:202
+assert_return(() => invoke($0, `as-unary-operand`, []), [value("i32", 32)]);
+
+// ./test/core/multi-memory/load2.wast:204
+assert_return(() => invoke($0, `as-binary-left`, []), [value("i32", 10)]);
+
+// ./test/core/multi-memory/load2.wast:205
+assert_return(() => invoke($0, `as-binary-right`, []), [value("i32", 10)]);
+
+// ./test/core/multi-memory/load2.wast:207
+assert_return(() => invoke($0, `as-test-operand`, []), [value("i32", 1)]);
+
+// ./test/core/multi-memory/load2.wast:209
+assert_return(() => invoke($0, `as-compare-left`, []), [value("i32", 1)]);
+
+// ./test/core/multi-memory/load2.wast:210
+assert_return(() => invoke($0, `as-compare-right`, []), [value("i32", 1)]);
+
+// ./test/core/multi-memory/load2.wast:212
+assert_return(() => invoke($0, `as-memory.grow-size`, []), [value("i32", 1)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/memory-multi.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/memory-multi.wast.js
new file mode 100644
index 0000000000..8d9503ee59
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/memory-multi.wast.js
@@ -0,0 +1,62 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/memory-multi.wast
+
+// ./test/core/memory-multi.wast:5
+let $0 = instantiate(`(module
+ (memory $$mem1 1)
+ (memory $$mem2 1)
+
+ (func (export "init1") (result i32)
+ (memory.init $$mem1 $$d (i32.const 1) (i32.const 0) (i32.const 4))
+ (i32.load $$mem1 (i32.const 1))
+ )
+
+ (func (export "init2") (result i32)
+ (memory.init $$mem2 $$d (i32.const 1) (i32.const 4) (i32.const 4))
+ (i32.load $$mem2 (i32.const 1))
+ )
+
+ (data $$d "\\01\\00\\00\\00" "\\02\\00\\00\\00")
+)`);
+
+// ./test/core/memory-multi.wast:22
+assert_return(() => invoke($0, `init1`, []), [value("i32", 1)]);
+
+// ./test/core/memory-multi.wast:23
+assert_return(() => invoke($0, `init2`, []), [value("i32", 2)]);
+
+// ./test/core/memory-multi.wast:26
+let $1 = instantiate(`(module
+ (memory $$mem1 1)
+ (memory $$mem2 1)
+
+ (func (export "fill1") (result i32)
+ (memory.fill $$mem1 (i32.const 1) (i32.const 0x01) (i32.const 4))
+ (i32.load $$mem1 (i32.const 1))
+ )
+
+ (func (export "fill2") (result i32)
+ (memory.fill $$mem2 (i32.const 1) (i32.const 0x02) (i32.const 2))
+ (i32.load $$mem2 (i32.const 1))
+ )
+)`);
+
+// ./test/core/memory-multi.wast:41
+assert_return(() => invoke($1, `fill1`, []), [value("i32", 16843009)]);
+
+// ./test/core/memory-multi.wast:42
+assert_return(() => invoke($1, `fill2`, []), [value("i32", 514)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/memory.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/memory.wast.js
new file mode 100644
index 0000000000..170b4f860f
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/memory.wast.js
@@ -0,0 +1,390 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/memory.wast
+
+// ./test/core/memory.wast:3
+let $0 = instantiate(`(module (memory 0))`);
+
+// ./test/core/memory.wast:4
+let $1 = instantiate(`(module (memory 1))`);
+
+// ./test/core/memory.wast:5
+let $2 = instantiate(`(module (memory 0 0))`);
+
+// ./test/core/memory.wast:6
+let $3 = instantiate(`(module (memory 0 1))`);
+
+// ./test/core/memory.wast:7
+let $4 = instantiate(`(module (memory 1 256))`);
+
+// ./test/core/memory.wast:8
+let $5 = instantiate(`(module (memory 0 65536))`);
+
+// ./test/core/memory.wast:10
+let $6 = instantiate(`(module (memory (data)) (func (export "memsize") (result i32) (memory.size)))`);
+
+// ./test/core/memory.wast:11
+assert_return(() => invoke($6, `memsize`, []), [value("i32", 0)]);
+
+// ./test/core/memory.wast:12
+let $7 = instantiate(`(module (memory (data "")) (func (export "memsize") (result i32) (memory.size)))`);
+
+// ./test/core/memory.wast:13
+assert_return(() => invoke($7, `memsize`, []), [value("i32", 0)]);
+
+// ./test/core/memory.wast:14
+let $8 = instantiate(`(module (memory (data "x")) (func (export "memsize") (result i32) (memory.size)))`);
+
+// ./test/core/memory.wast:15
+assert_return(() => invoke($8, `memsize`, []), [value("i32", 1)]);
+
+// ./test/core/memory.wast:17
+assert_invalid(() => instantiate(`(module (data (i32.const 0)))`), `unknown memory`);
+
+// ./test/core/memory.wast:18
+assert_invalid(() => instantiate(`(module (data (i32.const 0) ""))`), `unknown memory`);
+
+// ./test/core/memory.wast:19
+assert_invalid(() => instantiate(`(module (data (i32.const 0) "x"))`), `unknown memory`);
+
+// ./test/core/memory.wast:21
+assert_invalid(
+ () => instantiate(`(module (func (drop (f32.load (i32.const 0)))))`),
+ `unknown memory`,
+);
+
+// ./test/core/memory.wast:25
+assert_invalid(
+ () => instantiate(`(module (func (f32.store (i32.const 0) (f32.const 0))))`),
+ `unknown memory`,
+);
+
+// ./test/core/memory.wast:29
+assert_invalid(
+ () => instantiate(`(module (func (drop (i32.load8_s (i32.const 0)))))`),
+ `unknown memory`,
+);
+
+// ./test/core/memory.wast:33
+assert_invalid(
+ () => instantiate(`(module (func (i32.store8 (i32.const 0) (i32.const 0))))`),
+ `unknown memory`,
+);
+
+// ./test/core/memory.wast:37
+assert_invalid(
+ () => instantiate(`(module (func (drop (memory.size))))`),
+ `unknown memory`,
+);
+
+// ./test/core/memory.wast:41
+assert_invalid(
+ () => instantiate(`(module (func (drop (memory.grow (i32.const 0)))))`),
+ `unknown memory`,
+);
+
+// ./test/core/memory.wast:47
+assert_invalid(
+ () => instantiate(`(module (memory 1 0))`),
+ `size minimum must not be greater than maximum`,
+);
+
+// ./test/core/memory.wast:51
+assert_invalid(
+ () => instantiate(`(module (memory 65537))`),
+ `memory size must be at most 65536 pages (4GiB)`,
+);
+
+// ./test/core/memory.wast:55
+assert_invalid(
+ () => instantiate(`(module (memory 2147483648))`),
+ `memory size must be at most 65536 pages (4GiB)`,
+);
+
+// ./test/core/memory.wast:59
+assert_invalid(
+ () => instantiate(`(module (memory 4294967295))`),
+ `memory size must be at most 65536 pages (4GiB)`,
+);
+
+// ./test/core/memory.wast:63
+assert_invalid(
+ () => instantiate(`(module (memory 0 65537))`),
+ `memory size must be at most 65536 pages (4GiB)`,
+);
+
+// ./test/core/memory.wast:67
+assert_invalid(
+ () => instantiate(`(module (memory 0 2147483648))`),
+ `memory size must be at most 65536 pages (4GiB)`,
+);
+
+// ./test/core/memory.wast:71
+assert_invalid(
+ () => instantiate(`(module (memory 0 4294967295))`),
+ `memory size must be at most 65536 pages (4GiB)`,
+);
+
+// ./test/core/memory.wast:76
+assert_malformed(
+ () => instantiate(`(memory 0x1_0000_0000) `),
+ `i32 constant out of range`,
+);
+
+// ./test/core/memory.wast:80
+assert_malformed(
+ () => instantiate(`(memory 0x1_0000_0000 0x1_0000_0000) `),
+ `i32 constant out of range`,
+);
+
+// ./test/core/memory.wast:84
+assert_malformed(
+ () => instantiate(`(memory 0 0x1_0000_0000) `),
+ `i32 constant out of range`,
+);
+
+// ./test/core/memory.wast:89
+let $9 = instantiate(`(module
+ (memory 1)
+ (data (i32.const 0) "ABC\\a7D") (data (i32.const 20) "WASM")
+
+ ;; Data section
+ (func (export "data") (result i32)
+ (i32.and
+ (i32.and
+ (i32.and
+ (i32.eq (i32.load8_u (i32.const 0)) (i32.const 65))
+ (i32.eq (i32.load8_u (i32.const 3)) (i32.const 167))
+ )
+ (i32.and
+ (i32.eq (i32.load8_u (i32.const 6)) (i32.const 0))
+ (i32.eq (i32.load8_u (i32.const 19)) (i32.const 0))
+ )
+ )
+ (i32.and
+ (i32.and
+ (i32.eq (i32.load8_u (i32.const 20)) (i32.const 87))
+ (i32.eq (i32.load8_u (i32.const 23)) (i32.const 77))
+ )
+ (i32.and
+ (i32.eq (i32.load8_u (i32.const 24)) (i32.const 0))
+ (i32.eq (i32.load8_u (i32.const 1023)) (i32.const 0))
+ )
+ )
+ )
+ )
+
+ ;; Memory cast
+ (func (export "cast") (result f64)
+ (i64.store (i32.const 8) (i64.const -12345))
+ (if
+ (f64.eq
+ (f64.load (i32.const 8))
+ (f64.reinterpret_i64 (i64.const -12345))
+ )
+ (then (return (f64.const 0)))
+ )
+ (i64.store align=1 (i32.const 9) (i64.const 0))
+ (i32.store16 align=1 (i32.const 15) (i32.const 16453))
+ (f64.load align=1 (i32.const 9))
+ )
+
+ ;; Sign and zero extending memory loads
+ (func (export "i32_load8_s") (param $$i i32) (result i32)
+ (i32.store8 (i32.const 8) (local.get $$i))
+ (i32.load8_s (i32.const 8))
+ )
+ (func (export "i32_load8_u") (param $$i i32) (result i32)
+ (i32.store8 (i32.const 8) (local.get $$i))
+ (i32.load8_u (i32.const 8))
+ )
+ (func (export "i32_load16_s") (param $$i i32) (result i32)
+ (i32.store16 (i32.const 8) (local.get $$i))
+ (i32.load16_s (i32.const 8))
+ )
+ (func (export "i32_load16_u") (param $$i i32) (result i32)
+ (i32.store16 (i32.const 8) (local.get $$i))
+ (i32.load16_u (i32.const 8))
+ )
+ (func (export "i64_load8_s") (param $$i i64) (result i64)
+ (i64.store8 (i32.const 8) (local.get $$i))
+ (i64.load8_s (i32.const 8))
+ )
+ (func (export "i64_load8_u") (param $$i i64) (result i64)
+ (i64.store8 (i32.const 8) (local.get $$i))
+ (i64.load8_u (i32.const 8))
+ )
+ (func (export "i64_load16_s") (param $$i i64) (result i64)
+ (i64.store16 (i32.const 8) (local.get $$i))
+ (i64.load16_s (i32.const 8))
+ )
+ (func (export "i64_load16_u") (param $$i i64) (result i64)
+ (i64.store16 (i32.const 8) (local.get $$i))
+ (i64.load16_u (i32.const 8))
+ )
+ (func (export "i64_load32_s") (param $$i i64) (result i64)
+ (i64.store32 (i32.const 8) (local.get $$i))
+ (i64.load32_s (i32.const 8))
+ )
+ (func (export "i64_load32_u") (param $$i i64) (result i64)
+ (i64.store32 (i32.const 8) (local.get $$i))
+ (i64.load32_u (i32.const 8))
+ )
+)`);
+
+// ./test/core/memory.wast:177
+assert_return(() => invoke($9, `data`, []), [value("i32", 1)]);
+
+// ./test/core/memory.wast:178
+assert_return(() => invoke($9, `cast`, []), [value("f64", 42)]);
+
+// ./test/core/memory.wast:180
+assert_return(() => invoke($9, `i32_load8_s`, [-1]), [value("i32", -1)]);
+
+// ./test/core/memory.wast:181
+assert_return(() => invoke($9, `i32_load8_u`, [-1]), [value("i32", 255)]);
+
+// ./test/core/memory.wast:182
+assert_return(() => invoke($9, `i32_load16_s`, [-1]), [value("i32", -1)]);
+
+// ./test/core/memory.wast:183
+assert_return(() => invoke($9, `i32_load16_u`, [-1]), [value("i32", 65535)]);
+
+// ./test/core/memory.wast:185
+assert_return(() => invoke($9, `i32_load8_s`, [100]), [value("i32", 100)]);
+
+// ./test/core/memory.wast:186
+assert_return(() => invoke($9, `i32_load8_u`, [200]), [value("i32", 200)]);
+
+// ./test/core/memory.wast:187
+assert_return(() => invoke($9, `i32_load16_s`, [20000]), [value("i32", 20000)]);
+
+// ./test/core/memory.wast:188
+assert_return(() => invoke($9, `i32_load16_u`, [40000]), [value("i32", 40000)]);
+
+// ./test/core/memory.wast:190
+assert_return(() => invoke($9, `i32_load8_s`, [-19110589]), [value("i32", 67)]);
+
+// ./test/core/memory.wast:191
+assert_return(() => invoke($9, `i32_load8_s`, [878104047]), [value("i32", -17)]);
+
+// ./test/core/memory.wast:192
+assert_return(() => invoke($9, `i32_load8_u`, [-19110589]), [value("i32", 67)]);
+
+// ./test/core/memory.wast:193
+assert_return(() => invoke($9, `i32_load8_u`, [878104047]), [value("i32", 239)]);
+
+// ./test/core/memory.wast:194
+assert_return(() => invoke($9, `i32_load16_s`, [-19110589]), [value("i32", 25923)]);
+
+// ./test/core/memory.wast:195
+assert_return(() => invoke($9, `i32_load16_s`, [878104047]), [value("i32", -12817)]);
+
+// ./test/core/memory.wast:196
+assert_return(() => invoke($9, `i32_load16_u`, [-19110589]), [value("i32", 25923)]);
+
+// ./test/core/memory.wast:197
+assert_return(() => invoke($9, `i32_load16_u`, [878104047]), [value("i32", 52719)]);
+
+// ./test/core/memory.wast:199
+assert_return(() => invoke($9, `i64_load8_s`, [-1n]), [value("i64", -1n)]);
+
+// ./test/core/memory.wast:200
+assert_return(() => invoke($9, `i64_load8_u`, [-1n]), [value("i64", 255n)]);
+
+// ./test/core/memory.wast:201
+assert_return(() => invoke($9, `i64_load16_s`, [-1n]), [value("i64", -1n)]);
+
+// ./test/core/memory.wast:202
+assert_return(() => invoke($9, `i64_load16_u`, [-1n]), [value("i64", 65535n)]);
+
+// ./test/core/memory.wast:203
+assert_return(() => invoke($9, `i64_load32_s`, [-1n]), [value("i64", -1n)]);
+
+// ./test/core/memory.wast:204
+assert_return(() => invoke($9, `i64_load32_u`, [-1n]), [value("i64", 4294967295n)]);
+
+// ./test/core/memory.wast:206
+assert_return(() => invoke($9, `i64_load8_s`, [100n]), [value("i64", 100n)]);
+
+// ./test/core/memory.wast:207
+assert_return(() => invoke($9, `i64_load8_u`, [200n]), [value("i64", 200n)]);
+
+// ./test/core/memory.wast:208
+assert_return(() => invoke($9, `i64_load16_s`, [20000n]), [value("i64", 20000n)]);
+
+// ./test/core/memory.wast:209
+assert_return(() => invoke($9, `i64_load16_u`, [40000n]), [value("i64", 40000n)]);
+
+// ./test/core/memory.wast:210
+assert_return(() => invoke($9, `i64_load32_s`, [20000n]), [value("i64", 20000n)]);
+
+// ./test/core/memory.wast:211
+assert_return(() => invoke($9, `i64_load32_u`, [40000n]), [value("i64", 40000n)]);
+
+// ./test/core/memory.wast:213
+assert_return(() => invoke($9, `i64_load8_s`, [-81985529755441853n]), [value("i64", 67n)]);
+
+// ./test/core/memory.wast:214
+assert_return(() => invoke($9, `i64_load8_s`, [3771275841602506223n]), [value("i64", -17n)]);
+
+// ./test/core/memory.wast:215
+assert_return(() => invoke($9, `i64_load8_u`, [-81985529755441853n]), [value("i64", 67n)]);
+
+// ./test/core/memory.wast:216
+assert_return(() => invoke($9, `i64_load8_u`, [3771275841602506223n]), [value("i64", 239n)]);
+
+// ./test/core/memory.wast:217
+assert_return(() => invoke($9, `i64_load16_s`, [-81985529755441853n]), [value("i64", 25923n)]);
+
+// ./test/core/memory.wast:218
+assert_return(() => invoke($9, `i64_load16_s`, [3771275841602506223n]), [value("i64", -12817n)]);
+
+// ./test/core/memory.wast:219
+assert_return(() => invoke($9, `i64_load16_u`, [-81985529755441853n]), [value("i64", 25923n)]);
+
+// ./test/core/memory.wast:220
+assert_return(() => invoke($9, `i64_load16_u`, [3771275841602506223n]), [value("i64", 52719n)]);
+
+// ./test/core/memory.wast:221
+assert_return(() => invoke($9, `i64_load32_s`, [-81985529755441853n]), [value("i64", 1446274371n)]);
+
+// ./test/core/memory.wast:222
+assert_return(() => invoke($9, `i64_load32_s`, [3771275841602506223n]), [value("i64", -1732588049n)]);
+
+// ./test/core/memory.wast:223
+assert_return(() => invoke($9, `i64_load32_u`, [-81985529755441853n]), [value("i64", 1446274371n)]);
+
+// ./test/core/memory.wast:224
+assert_return(() => invoke($9, `i64_load32_u`, [3771275841602506223n]), [value("i64", 2562379247n)]);
+
+// ./test/core/memory.wast:228
+assert_malformed(
+ () => instantiate(`(memory $$foo 1) (memory $$foo 1) `),
+ `duplicate memory`,
+);
+
+// ./test/core/memory.wast:232
+assert_malformed(
+ () => instantiate(`(import "" "" (memory $$foo 1)) (memory $$foo 1) `),
+ `duplicate memory`,
+);
+
+// ./test/core/memory.wast:236
+assert_malformed(
+ () => instantiate(`(import "" "" (memory $$foo 1)) (import "" "" (memory $$foo 1)) `),
+ `duplicate memory`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/memory_copy0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_copy0.wast.js
new file mode 100644
index 0000000000..abd99c0597
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_copy0.wast.js
@@ -0,0 +1,117 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/memory_copy0.wast
+
+// ./test/core/multi-memory/memory_copy0.wast:2
+let $0 = instantiate(`(module
+ (memory $$mem0 (data "\\ff\\11\\44\\ee"))
+ (memory $$mem1 (data "\\ee\\22\\55\\ff"))
+ (memory $$mem2 (data "\\dd\\33\\66\\00"))
+ (memory $$mem3 (data "\\aa\\bb\\cc\\dd"))
+
+ (func (export "copy") (param i32 i32 i32)
+ (memory.copy $$mem3 $$mem3
+ (local.get 0)
+ (local.get 1)
+ (local.get 2)))
+
+ (func (export "load8_u") (param i32) (result i32)
+ (i32.load8_u $$mem3 (local.get 0)))
+)`);
+
+// ./test/core/multi-memory/memory_copy0.wast:19
+invoke($0, `copy`, [10, 0, 4]);
+
+// ./test/core/multi-memory/memory_copy0.wast:21
+assert_return(() => invoke($0, `load8_u`, [9]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:22
+assert_return(() => invoke($0, `load8_u`, [10]), [value("i32", 170)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:23
+assert_return(() => invoke($0, `load8_u`, [11]), [value("i32", 187)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:24
+assert_return(() => invoke($0, `load8_u`, [12]), [value("i32", 204)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:25
+assert_return(() => invoke($0, `load8_u`, [13]), [value("i32", 221)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:26
+assert_return(() => invoke($0, `load8_u`, [14]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:29
+invoke($0, `copy`, [8, 10, 4]);
+
+// ./test/core/multi-memory/memory_copy0.wast:30
+assert_return(() => invoke($0, `load8_u`, [8]), [value("i32", 170)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:31
+assert_return(() => invoke($0, `load8_u`, [9]), [value("i32", 187)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:32
+assert_return(() => invoke($0, `load8_u`, [10]), [value("i32", 204)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:33
+assert_return(() => invoke($0, `load8_u`, [11]), [value("i32", 221)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:34
+assert_return(() => invoke($0, `load8_u`, [12]), [value("i32", 204)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:35
+assert_return(() => invoke($0, `load8_u`, [13]), [value("i32", 221)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:38
+invoke($0, `copy`, [10, 7, 6]);
+
+// ./test/core/multi-memory/memory_copy0.wast:39
+assert_return(() => invoke($0, `load8_u`, [10]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:40
+assert_return(() => invoke($0, `load8_u`, [11]), [value("i32", 170)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:41
+assert_return(() => invoke($0, `load8_u`, [12]), [value("i32", 187)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:42
+assert_return(() => invoke($0, `load8_u`, [13]), [value("i32", 204)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:43
+assert_return(() => invoke($0, `load8_u`, [14]), [value("i32", 221)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:44
+assert_return(() => invoke($0, `load8_u`, [15]), [value("i32", 204)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:45
+assert_return(() => invoke($0, `load8_u`, [16]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_copy0.wast:48
+invoke($0, `copy`, [65280, 0, 256]);
+
+// ./test/core/multi-memory/memory_copy0.wast:49
+invoke($0, `copy`, [65024, 65280, 256]);
+
+// ./test/core/multi-memory/memory_copy0.wast:52
+invoke($0, `copy`, [65536, 0, 0]);
+
+// ./test/core/multi-memory/memory_copy0.wast:53
+invoke($0, `copy`, [0, 65536, 0]);
+
+// ./test/core/multi-memory/memory_copy0.wast:56
+assert_trap(() => invoke($0, `copy`, [65537, 0, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_copy0.wast:58
+assert_trap(() => invoke($0, `copy`, [0, 65537, 0]), `out of bounds memory access`);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/memory_fill0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_fill0.wast.js
new file mode 100644
index 0000000000..2bc3eef0c8
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_fill0.wast.js
@@ -0,0 +1,77 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/memory_fill0.wast
+
+// ./test/core/multi-memory/memory_fill0.wast:2
+let $0 = instantiate(`(module
+ (memory $$mem0 0)
+ (memory $$mem1 0)
+ (memory $$mem2 1)
+
+ (func (export "fill") (param i32 i32 i32)
+ (memory.fill $$mem2
+ (local.get 0)
+ (local.get 1)
+ (local.get 2)))
+
+ (func (export "load8_u") (param i32) (result i32)
+ (i32.load8_u $$mem2 (local.get 0)))
+)`);
+
+// ./test/core/multi-memory/memory_fill0.wast:18
+invoke($0, `fill`, [1, 255, 3]);
+
+// ./test/core/multi-memory/memory_fill0.wast:19
+assert_return(() => invoke($0, `load8_u`, [0]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_fill0.wast:20
+assert_return(() => invoke($0, `load8_u`, [1]), [value("i32", 255)]);
+
+// ./test/core/multi-memory/memory_fill0.wast:21
+assert_return(() => invoke($0, `load8_u`, [2]), [value("i32", 255)]);
+
+// ./test/core/multi-memory/memory_fill0.wast:22
+assert_return(() => invoke($0, `load8_u`, [3]), [value("i32", 255)]);
+
+// ./test/core/multi-memory/memory_fill0.wast:23
+assert_return(() => invoke($0, `load8_u`, [4]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_fill0.wast:26
+invoke($0, `fill`, [0, 48042, 2]);
+
+// ./test/core/multi-memory/memory_fill0.wast:27
+assert_return(() => invoke($0, `load8_u`, [0]), [value("i32", 170)]);
+
+// ./test/core/multi-memory/memory_fill0.wast:28
+assert_return(() => invoke($0, `load8_u`, [1]), [value("i32", 170)]);
+
+// ./test/core/multi-memory/memory_fill0.wast:31
+invoke($0, `fill`, [0, 0, 65536]);
+
+// ./test/core/multi-memory/memory_fill0.wast:34
+assert_trap(() => invoke($0, `fill`, [65280, 1, 257]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_fill0.wast:36
+assert_return(() => invoke($0, `load8_u`, [65280]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_fill0.wast:37
+assert_return(() => invoke($0, `load8_u`, [65535]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_fill0.wast:40
+invoke($0, `fill`, [65536, 0, 0]);
+
+// ./test/core/multi-memory/memory_fill0.wast:43
+assert_trap(() => invoke($0, `fill`, [65537, 0, 0]), `out of bounds memory access`);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/memory_grow.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_grow.wast.js
new file mode 100644
index 0000000000..6cef74d6ba
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_grow.wast.js
@@ -0,0 +1,773 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/memory_grow.wast
+
+// ./test/core/memory_grow.wast:1
+let $0 = instantiate(`(module
+ (memory 0)
+ (func (export "grow") (param i32) (result i32) (memory.grow (local.get 0)))
+)`);
+
+// ./test/core/memory_grow.wast:6
+assert_return(() => invoke($0, `grow`, [0]), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:7
+assert_return(() => invoke($0, `grow`, [1]), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:8
+assert_return(() => invoke($0, `grow`, [0]), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:9
+assert_return(() => invoke($0, `grow`, [2]), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:10
+assert_return(() => invoke($0, `grow`, [800]), [value("i32", 3)]);
+
+// ./test/core/memory_grow.wast:11
+assert_return(() => invoke($0, `grow`, [65536]), [value("i32", -1)]);
+
+// ./test/core/memory_grow.wast:12
+assert_return(() => invoke($0, `grow`, [64736]), [value("i32", -1)]);
+
+// ./test/core/memory_grow.wast:13
+assert_return(() => invoke($0, `grow`, [1]), [value("i32", 803)]);
+
+// ./test/core/memory_grow.wast:15
+let $1 = instantiate(`(module
+ (memory 0 10)
+ (func (export "grow") (param i32) (result i32) (memory.grow (local.get 0)))
+)`);
+
+// ./test/core/memory_grow.wast:20
+assert_return(() => invoke($1, `grow`, [0]), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:21
+assert_return(() => invoke($1, `grow`, [1]), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:22
+assert_return(() => invoke($1, `grow`, [1]), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:23
+assert_return(() => invoke($1, `grow`, [2]), [value("i32", 2)]);
+
+// ./test/core/memory_grow.wast:24
+assert_return(() => invoke($1, `grow`, [6]), [value("i32", 4)]);
+
+// ./test/core/memory_grow.wast:25
+assert_return(() => invoke($1, `grow`, [0]), [value("i32", 10)]);
+
+// ./test/core/memory_grow.wast:26
+assert_return(() => invoke($1, `grow`, [1]), [value("i32", -1)]);
+
+// ./test/core/memory_grow.wast:27
+assert_return(() => invoke($1, `grow`, [65536]), [value("i32", -1)]);
+
+// ./test/core/memory_grow.wast:32
+let $2 = instantiate(`(module
+ (memory 1)
+ (func (export "grow") (param i32) (result i32)
+ (memory.grow (local.get 0))
+ )
+ (func (export "check-memory-zero") (param i32 i32) (result i32)
+ (local i32)
+ (local.set 2 (i32.const 1))
+ (block
+ (loop
+ (local.set 2 (i32.load8_u (local.get 0)))
+ (br_if 1 (i32.ne (local.get 2) (i32.const 0)))
+ (br_if 1 (i32.ge_u (local.get 0) (local.get 1)))
+ (local.set 0 (i32.add (local.get 0) (i32.const 1)))
+ (br_if 0 (i32.le_u (local.get 0) (local.get 1)))
+ )
+ )
+ (local.get 2)
+ )
+)`);
+
+// ./test/core/memory_grow.wast:53
+assert_return(() => invoke($2, `check-memory-zero`, [0, 65535]), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:54
+assert_return(() => invoke($2, `grow`, [1]), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:55
+assert_return(() => invoke($2, `check-memory-zero`, [65536, 131071]), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:56
+assert_return(() => invoke($2, `grow`, [1]), [value("i32", 2)]);
+
+// ./test/core/memory_grow.wast:57
+assert_return(() => invoke($2, `check-memory-zero`, [131072, 196607]), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:58
+assert_return(() => invoke($2, `grow`, [1]), [value("i32", 3)]);
+
+// ./test/core/memory_grow.wast:59
+assert_return(() => invoke($2, `check-memory-zero`, [196608, 262143]), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:60
+assert_return(() => invoke($2, `grow`, [1]), [value("i32", 4)]);
+
+// ./test/core/memory_grow.wast:61
+assert_return(() => invoke($2, `check-memory-zero`, [262144, 327679]), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:62
+assert_return(() => invoke($2, `grow`, [1]), [value("i32", 5)]);
+
+// ./test/core/memory_grow.wast:63
+assert_return(() => invoke($2, `check-memory-zero`, [327680, 393215]), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:68
+let $3 = instantiate(`(module
+ (memory 0)
+
+ (func (export "load_at_zero") (result i32) (i32.load (i32.const 0)))
+ (func (export "store_at_zero") (i32.store (i32.const 0) (i32.const 2)))
+
+ (func (export "load_at_page_size") (result i32)
+ (i32.load (i32.const 0x10000))
+ )
+ (func (export "store_at_page_size")
+ (i32.store (i32.const 0x10000) (i32.const 3))
+ )
+
+ (func (export "grow") (param i32) (result i32) (memory.grow (local.get 0)))
+ (func (export "size") (result i32) (memory.size))
+)`);
+
+// ./test/core/memory_grow.wast:85
+assert_return(() => invoke($3, `size`, []), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:86
+assert_trap(() => invoke($3, `store_at_zero`, []), `out of bounds memory access`);
+
+// ./test/core/memory_grow.wast:87
+assert_trap(() => invoke($3, `load_at_zero`, []), `out of bounds memory access`);
+
+// ./test/core/memory_grow.wast:88
+assert_trap(() => invoke($3, `store_at_page_size`, []), `out of bounds memory access`);
+
+// ./test/core/memory_grow.wast:89
+assert_trap(() => invoke($3, `load_at_page_size`, []), `out of bounds memory access`);
+
+// ./test/core/memory_grow.wast:90
+assert_return(() => invoke($3, `grow`, [1]), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:91
+assert_return(() => invoke($3, `size`, []), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:92
+assert_return(() => invoke($3, `load_at_zero`, []), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:93
+assert_return(() => invoke($3, `store_at_zero`, []), []);
+
+// ./test/core/memory_grow.wast:94
+assert_return(() => invoke($3, `load_at_zero`, []), [value("i32", 2)]);
+
+// ./test/core/memory_grow.wast:95
+assert_trap(() => invoke($3, `store_at_page_size`, []), `out of bounds memory access`);
+
+// ./test/core/memory_grow.wast:96
+assert_trap(() => invoke($3, `load_at_page_size`, []), `out of bounds memory access`);
+
+// ./test/core/memory_grow.wast:97
+assert_return(() => invoke($3, `grow`, [4]), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:98
+assert_return(() => invoke($3, `size`, []), [value("i32", 5)]);
+
+// ./test/core/memory_grow.wast:99
+assert_return(() => invoke($3, `load_at_zero`, []), [value("i32", 2)]);
+
+// ./test/core/memory_grow.wast:100
+assert_return(() => invoke($3, `store_at_zero`, []), []);
+
+// ./test/core/memory_grow.wast:101
+assert_return(() => invoke($3, `load_at_zero`, []), [value("i32", 2)]);
+
+// ./test/core/memory_grow.wast:102
+assert_return(() => invoke($3, `load_at_page_size`, []), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:103
+assert_return(() => invoke($3, `store_at_page_size`, []), []);
+
+// ./test/core/memory_grow.wast:104
+assert_return(() => invoke($3, `load_at_page_size`, []), [value("i32", 3)]);
+
+// ./test/core/memory_grow.wast:109
+let $4 = instantiate(`(module
+ (memory (export "mem1") 2 5)
+ (memory (export "mem2") 0)
+)`);
+
+// ./test/core/memory_grow.wast:113
+register($4, `M`);
+
+// ./test/core/memory_grow.wast:115
+let $5 = instantiate(`(module
+ (memory $$mem1 (import "M" "mem1") 1 6)
+ (memory $$mem2 (import "M" "mem2") 0)
+ (memory $$mem3 3)
+ (memory $$mem4 4 5)
+
+ (func (export "size1") (result i32) (memory.size $$mem1))
+ (func (export "size2") (result i32) (memory.size $$mem2))
+ (func (export "size3") (result i32) (memory.size $$mem3))
+ (func (export "size4") (result i32) (memory.size $$mem4))
+
+ (func (export "grow1") (param i32) (result i32)
+ (memory.grow $$mem1 (local.get 0))
+ )
+ (func (export "grow2") (param i32) (result i32)
+ (memory.grow $$mem2 (local.get 0))
+ )
+ (func (export "grow3") (param i32) (result i32)
+ (memory.grow $$mem3 (local.get 0))
+ )
+ (func (export "grow4") (param i32) (result i32)
+ (memory.grow $$mem4 (local.get 0))
+ )
+)`);
+
+// ./test/core/memory_grow.wast:140
+assert_return(() => invoke($5, `size1`, []), [value("i32", 2)]);
+
+// ./test/core/memory_grow.wast:141
+assert_return(() => invoke($5, `size2`, []), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:142
+assert_return(() => invoke($5, `size3`, []), [value("i32", 3)]);
+
+// ./test/core/memory_grow.wast:143
+assert_return(() => invoke($5, `size4`, []), [value("i32", 4)]);
+
+// ./test/core/memory_grow.wast:145
+assert_return(() => invoke($5, `grow1`, [1]), [value("i32", 2)]);
+
+// ./test/core/memory_grow.wast:146
+assert_return(() => invoke($5, `size1`, []), [value("i32", 3)]);
+
+// ./test/core/memory_grow.wast:147
+assert_return(() => invoke($5, `size2`, []), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:148
+assert_return(() => invoke($5, `size3`, []), [value("i32", 3)]);
+
+// ./test/core/memory_grow.wast:149
+assert_return(() => invoke($5, `size4`, []), [value("i32", 4)]);
+
+// ./test/core/memory_grow.wast:151
+assert_return(() => invoke($5, `grow1`, [2]), [value("i32", 3)]);
+
+// ./test/core/memory_grow.wast:152
+assert_return(() => invoke($5, `size1`, []), [value("i32", 5)]);
+
+// ./test/core/memory_grow.wast:153
+assert_return(() => invoke($5, `size2`, []), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:154
+assert_return(() => invoke($5, `size3`, []), [value("i32", 3)]);
+
+// ./test/core/memory_grow.wast:155
+assert_return(() => invoke($5, `size4`, []), [value("i32", 4)]);
+
+// ./test/core/memory_grow.wast:157
+assert_return(() => invoke($5, `grow1`, [1]), [value("i32", -1)]);
+
+// ./test/core/memory_grow.wast:158
+assert_return(() => invoke($5, `size1`, []), [value("i32", 5)]);
+
+// ./test/core/memory_grow.wast:159
+assert_return(() => invoke($5, `size2`, []), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:160
+assert_return(() => invoke($5, `size3`, []), [value("i32", 3)]);
+
+// ./test/core/memory_grow.wast:161
+assert_return(() => invoke($5, `size4`, []), [value("i32", 4)]);
+
+// ./test/core/memory_grow.wast:163
+assert_return(() => invoke($5, `grow2`, [10]), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:164
+assert_return(() => invoke($5, `size1`, []), [value("i32", 5)]);
+
+// ./test/core/memory_grow.wast:165
+assert_return(() => invoke($5, `size2`, []), [value("i32", 10)]);
+
+// ./test/core/memory_grow.wast:166
+assert_return(() => invoke($5, `size3`, []), [value("i32", 3)]);
+
+// ./test/core/memory_grow.wast:167
+assert_return(() => invoke($5, `size4`, []), [value("i32", 4)]);
+
+// ./test/core/memory_grow.wast:169
+assert_return(() => invoke($5, `grow3`, [268435456]), [value("i32", -1)]);
+
+// ./test/core/memory_grow.wast:170
+assert_return(() => invoke($5, `size1`, []), [value("i32", 5)]);
+
+// ./test/core/memory_grow.wast:171
+assert_return(() => invoke($5, `size2`, []), [value("i32", 10)]);
+
+// ./test/core/memory_grow.wast:172
+assert_return(() => invoke($5, `size3`, []), [value("i32", 3)]);
+
+// ./test/core/memory_grow.wast:173
+assert_return(() => invoke($5, `size4`, []), [value("i32", 4)]);
+
+// ./test/core/memory_grow.wast:175
+assert_return(() => invoke($5, `grow3`, [3]), [value("i32", 3)]);
+
+// ./test/core/memory_grow.wast:176
+assert_return(() => invoke($5, `size1`, []), [value("i32", 5)]);
+
+// ./test/core/memory_grow.wast:177
+assert_return(() => invoke($5, `size2`, []), [value("i32", 10)]);
+
+// ./test/core/memory_grow.wast:178
+assert_return(() => invoke($5, `size3`, []), [value("i32", 6)]);
+
+// ./test/core/memory_grow.wast:179
+assert_return(() => invoke($5, `size4`, []), [value("i32", 4)]);
+
+// ./test/core/memory_grow.wast:181
+assert_return(() => invoke($5, `grow4`, [1]), [value("i32", 4)]);
+
+// ./test/core/memory_grow.wast:182
+assert_return(() => invoke($5, `grow4`, [1]), [value("i32", -1)]);
+
+// ./test/core/memory_grow.wast:183
+assert_return(() => invoke($5, `size1`, []), [value("i32", 5)]);
+
+// ./test/core/memory_grow.wast:184
+assert_return(() => invoke($5, `size2`, []), [value("i32", 10)]);
+
+// ./test/core/memory_grow.wast:185
+assert_return(() => invoke($5, `size3`, []), [value("i32", 6)]);
+
+// ./test/core/memory_grow.wast:186
+assert_return(() => invoke($5, `size4`, []), [value("i32", 5)]);
+
+// ./test/core/memory_grow.wast:191
+let $6 = instantiate(`(module
+ (memory 1)
+
+ (func (export "as-br-value") (result i32)
+ (block (result i32) (br 0 (memory.grow (i32.const 0))))
+ )
+
+ (func (export "as-br_if-cond")
+ (block (br_if 0 (memory.grow (i32.const 0))))
+ )
+ (func (export "as-br_if-value") (result i32)
+ (block (result i32)
+ (drop (br_if 0 (memory.grow (i32.const 0)) (i32.const 1))) (i32.const 7)
+ )
+ )
+ (func (export "as-br_if-value-cond") (result i32)
+ (block (result i32)
+ (drop (br_if 0 (i32.const 6) (memory.grow (i32.const 0)))) (i32.const 7)
+ )
+ )
+
+ (func (export "as-br_table-index")
+ (block (br_table 0 0 0 (memory.grow (i32.const 0))))
+ )
+ (func (export "as-br_table-value") (result i32)
+ (block (result i32)
+ (br_table 0 0 0 (memory.grow (i32.const 0)) (i32.const 1)) (i32.const 7)
+ )
+ )
+ (func (export "as-br_table-value-index") (result i32)
+ (block (result i32)
+ (br_table 0 0 (i32.const 6) (memory.grow (i32.const 0))) (i32.const 7)
+ )
+ )
+
+ (func (export "as-return-value") (result i32)
+ (return (memory.grow (i32.const 0)))
+ )
+
+ (func (export "as-if-cond") (result i32)
+ (if (result i32) (memory.grow (i32.const 0))
+ (then (i32.const 0)) (else (i32.const 1))
+ )
+ )
+ (func (export "as-if-then") (result i32)
+ (if (result i32) (i32.const 1)
+ (then (memory.grow (i32.const 0))) (else (i32.const 0))
+ )
+ )
+ (func (export "as-if-else") (result i32)
+ (if (result i32) (i32.const 0)
+ (then (i32.const 0)) (else (memory.grow (i32.const 0)))
+ )
+ )
+
+ (func (export "as-select-first") (param i32 i32) (result i32)
+ (select (memory.grow (i32.const 0)) (local.get 0) (local.get 1))
+ )
+ (func (export "as-select-second") (param i32 i32) (result i32)
+ (select (local.get 0) (memory.grow (i32.const 0)) (local.get 1))
+ )
+ (func (export "as-select-cond") (result i32)
+ (select (i32.const 0) (i32.const 1) (memory.grow (i32.const 0)))
+ )
+
+ (func $$f (param i32 i32 i32) (result i32) (i32.const -1))
+ (func (export "as-call-first") (result i32)
+ (call $$f (memory.grow (i32.const 0)) (i32.const 2) (i32.const 3))
+ )
+ (func (export "as-call-mid") (result i32)
+ (call $$f (i32.const 1) (memory.grow (i32.const 0)) (i32.const 3))
+ )
+ (func (export "as-call-last") (result i32)
+ (call $$f (i32.const 1) (i32.const 2) (memory.grow (i32.const 0)))
+ )
+
+ (type $$sig (func (param i32 i32 i32) (result i32)))
+ (table funcref (elem $$f))
+ (func (export "as-call_indirect-first") (result i32)
+ (call_indirect (type $$sig)
+ (memory.grow (i32.const 0)) (i32.const 2) (i32.const 3) (i32.const 0)
+ )
+ )
+ (func (export "as-call_indirect-mid") (result i32)
+ (call_indirect (type $$sig)
+ (i32.const 1) (memory.grow (i32.const 0)) (i32.const 3) (i32.const 0)
+ )
+ )
+ (func (export "as-call_indirect-last") (result i32)
+ (call_indirect (type $$sig)
+ (i32.const 1) (i32.const 2) (memory.grow (i32.const 0)) (i32.const 0)
+ )
+ )
+ (func (export "as-call_indirect-index") (result i32)
+ (call_indirect (type $$sig)
+ (i32.const 1) (i32.const 2) (i32.const 3) (memory.grow (i32.const 0))
+ )
+ )
+
+ (func (export "as-local.set-value") (local i32)
+ (local.set 0 (memory.grow (i32.const 0)))
+ )
+ (func (export "as-local.tee-value") (result i32) (local i32)
+ (local.tee 0 (memory.grow (i32.const 0)))
+ )
+ (global $$g (mut i32) (i32.const 0))
+ (func (export "as-global.set-value") (local i32)
+ (global.set $$g (memory.grow (i32.const 0)))
+ )
+
+ (func (export "as-load-address") (result i32)
+ (i32.load (memory.grow (i32.const 0)))
+ )
+ (func (export "as-loadN-address") (result i32)
+ (i32.load8_s (memory.grow (i32.const 0)))
+ )
+
+ (func (export "as-store-address")
+ (i32.store (memory.grow (i32.const 0)) (i32.const 7))
+ )
+ (func (export "as-store-value")
+ (i32.store (i32.const 2) (memory.grow (i32.const 0)))
+ )
+
+ (func (export "as-storeN-address")
+ (i32.store8 (memory.grow (i32.const 0)) (i32.const 7))
+ )
+ (func (export "as-storeN-value")
+ (i32.store16 (i32.const 2) (memory.grow (i32.const 0)))
+ )
+
+ (func (export "as-unary-operand") (result i32)
+ (i32.clz (memory.grow (i32.const 0)))
+ )
+
+ (func (export "as-binary-left") (result i32)
+ (i32.add (memory.grow (i32.const 0)) (i32.const 10))
+ )
+ (func (export "as-binary-right") (result i32)
+ (i32.sub (i32.const 10) (memory.grow (i32.const 0)))
+ )
+
+ (func (export "as-test-operand") (result i32)
+ (i32.eqz (memory.grow (i32.const 0)))
+ )
+
+ (func (export "as-compare-left") (result i32)
+ (i32.le_s (memory.grow (i32.const 0)) (i32.const 10))
+ )
+ (func (export "as-compare-right") (result i32)
+ (i32.ne (i32.const 10) (memory.grow (i32.const 0)))
+ )
+
+ (func (export "as-memory.grow-size") (result i32)
+ (memory.grow (memory.grow (i32.const 0)))
+ )
+)`);
+
+// ./test/core/memory_grow.wast:349
+assert_return(() => invoke($6, `as-br-value`, []), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:351
+assert_return(() => invoke($6, `as-br_if-cond`, []), []);
+
+// ./test/core/memory_grow.wast:352
+assert_return(() => invoke($6, `as-br_if-value`, []), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:353
+assert_return(() => invoke($6, `as-br_if-value-cond`, []), [value("i32", 6)]);
+
+// ./test/core/memory_grow.wast:355
+assert_return(() => invoke($6, `as-br_table-index`, []), []);
+
+// ./test/core/memory_grow.wast:356
+assert_return(() => invoke($6, `as-br_table-value`, []), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:357
+assert_return(() => invoke($6, `as-br_table-value-index`, []), [value("i32", 6)]);
+
+// ./test/core/memory_grow.wast:359
+assert_return(() => invoke($6, `as-return-value`, []), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:361
+assert_return(() => invoke($6, `as-if-cond`, []), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:362
+assert_return(() => invoke($6, `as-if-then`, []), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:363
+assert_return(() => invoke($6, `as-if-else`, []), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:365
+assert_return(() => invoke($6, `as-select-first`, [0, 1]), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:366
+assert_return(() => invoke($6, `as-select-second`, [0, 0]), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:367
+assert_return(() => invoke($6, `as-select-cond`, []), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:369
+assert_return(() => invoke($6, `as-call-first`, []), [value("i32", -1)]);
+
+// ./test/core/memory_grow.wast:370
+assert_return(() => invoke($6, `as-call-mid`, []), [value("i32", -1)]);
+
+// ./test/core/memory_grow.wast:371
+assert_return(() => invoke($6, `as-call-last`, []), [value("i32", -1)]);
+
+// ./test/core/memory_grow.wast:373
+assert_return(() => invoke($6, `as-call_indirect-first`, []), [value("i32", -1)]);
+
+// ./test/core/memory_grow.wast:374
+assert_return(() => invoke($6, `as-call_indirect-mid`, []), [value("i32", -1)]);
+
+// ./test/core/memory_grow.wast:375
+assert_return(() => invoke($6, `as-call_indirect-last`, []), [value("i32", -1)]);
+
+// ./test/core/memory_grow.wast:376
+assert_trap(() => invoke($6, `as-call_indirect-index`, []), `undefined element`);
+
+// ./test/core/memory_grow.wast:378
+assert_return(() => invoke($6, `as-local.set-value`, []), []);
+
+// ./test/core/memory_grow.wast:379
+assert_return(() => invoke($6, `as-local.tee-value`, []), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:380
+assert_return(() => invoke($6, `as-global.set-value`, []), []);
+
+// ./test/core/memory_grow.wast:382
+assert_return(() => invoke($6, `as-load-address`, []), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:383
+assert_return(() => invoke($6, `as-loadN-address`, []), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:384
+assert_return(() => invoke($6, `as-store-address`, []), []);
+
+// ./test/core/memory_grow.wast:385
+assert_return(() => invoke($6, `as-store-value`, []), []);
+
+// ./test/core/memory_grow.wast:386
+assert_return(() => invoke($6, `as-storeN-address`, []), []);
+
+// ./test/core/memory_grow.wast:387
+assert_return(() => invoke($6, `as-storeN-value`, []), []);
+
+// ./test/core/memory_grow.wast:389
+assert_return(() => invoke($6, `as-unary-operand`, []), [value("i32", 31)]);
+
+// ./test/core/memory_grow.wast:391
+assert_return(() => invoke($6, `as-binary-left`, []), [value("i32", 11)]);
+
+// ./test/core/memory_grow.wast:392
+assert_return(() => invoke($6, `as-binary-right`, []), [value("i32", 9)]);
+
+// ./test/core/memory_grow.wast:394
+assert_return(() => invoke($6, `as-test-operand`, []), [value("i32", 0)]);
+
+// ./test/core/memory_grow.wast:396
+assert_return(() => invoke($6, `as-compare-left`, []), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:397
+assert_return(() => invoke($6, `as-compare-right`, []), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:399
+assert_return(() => invoke($6, `as-memory.grow-size`, []), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:404
+let $7 = instantiate(`(module
+ (memory $$mem1 1)
+ (memory $$mem2 2)
+
+ (func (export "grow1") (param i32) (result i32)
+ (memory.grow $$mem1 (local.get 0))
+ )
+ (func (export "grow2") (param i32) (result i32)
+ (memory.grow $$mem2 (local.get 0))
+ )
+
+ (func (export "size1") (result i32) (memory.size $$mem1))
+ (func (export "size2") (result i32) (memory.size $$mem2))
+)`);
+
+// ./test/core/memory_grow.wast:419
+assert_return(() => invoke($7, `size1`, []), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:420
+assert_return(() => invoke($7, `size2`, []), [value("i32", 2)]);
+
+// ./test/core/memory_grow.wast:421
+assert_return(() => invoke($7, `grow1`, [3]), [value("i32", 1)]);
+
+// ./test/core/memory_grow.wast:422
+assert_return(() => invoke($7, `grow1`, [4]), [value("i32", 4)]);
+
+// ./test/core/memory_grow.wast:423
+assert_return(() => invoke($7, `grow1`, [1]), [value("i32", 8)]);
+
+// ./test/core/memory_grow.wast:424
+assert_return(() => invoke($7, `grow2`, [1]), [value("i32", 2)]);
+
+// ./test/core/memory_grow.wast:425
+assert_return(() => invoke($7, `grow2`, [1]), [value("i32", 3)]);
+
+// ./test/core/memory_grow.wast:430
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-i32-vs-f32 (result i32)
+ (memory.grow (f32.const 0))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/memory_grow.wast:439
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-size-empty-vs-i32 (result i32)
+ (memory.grow)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/memory_grow.wast:448
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-size-empty-vs-i32-in-block (result i32)
+ (i32.const 0)
+ (block (result i32) (memory.grow))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/memory_grow.wast:458
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-size-empty-vs-i32-in-loop (result i32)
+ (i32.const 0)
+ (loop (result i32) (memory.grow))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/memory_grow.wast:468
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (func $$type-size-empty-vs-i32-in-then (result i32)
+ (i32.const 0) (i32.const 0)
+ (if (result i32) (then (memory.grow)))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/memory_grow.wast:479
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-result-i32-vs-empty
+ (memory.grow (i32.const 1))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/memory_grow.wast:488
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-size-f32-vs-i32 (result i32)
+ (memory.grow (f32.const 0))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/memory_grow.wast:498
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-result-i32-vs-empty
+ (memory.grow (i32.const 0))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/memory_grow.wast:507
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-result-i32-vs-f32 (result f32)
+ (memory.grow (i32.const 0))
+ )
+ )`),
+ `type mismatch`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/memory_init0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_init0.wast.js
new file mode 100644
index 0000000000..17eb4cc186
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_init0.wast.js
@@ -0,0 +1,70 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/memory_init0.wast
+
+// ./test/core/multi-memory/memory_init0.wast:2
+let $0 = instantiate(`(module
+ (memory $$mem0 0)
+ (memory $$mem1 0)
+ (memory $$mem2 1)
+ (memory $$mem3 0)
+ (data $$mem2 "\\aa\\bb\\cc\\dd")
+
+ (func (export "init") (param i32 i32 i32)
+ (memory.init $$mem2 0
+ (local.get 0)
+ (local.get 1)
+ (local.get 2)))
+
+ (func (export "load8_u") (param i32) (result i32)
+ (i32.load8_u $$mem2 (local.get 0)))
+)`);
+
+// ./test/core/multi-memory/memory_init0.wast:19
+invoke($0, `init`, [0, 1, 2]);
+
+// ./test/core/multi-memory/memory_init0.wast:20
+assert_return(() => invoke($0, `load8_u`, [0]), [value("i32", 187)]);
+
+// ./test/core/multi-memory/memory_init0.wast:21
+assert_return(() => invoke($0, `load8_u`, [1]), [value("i32", 204)]);
+
+// ./test/core/multi-memory/memory_init0.wast:22
+assert_return(() => invoke($0, `load8_u`, [2]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_init0.wast:25
+invoke($0, `init`, [65532, 0, 4]);
+
+// ./test/core/multi-memory/memory_init0.wast:28
+assert_trap(() => invoke($0, `init`, [65534, 0, 3]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_init0.wast:30
+assert_return(() => invoke($0, `load8_u`, [65534]), [value("i32", 204)]);
+
+// ./test/core/multi-memory/memory_init0.wast:31
+assert_return(() => invoke($0, `load8_u`, [65535]), [value("i32", 221)]);
+
+// ./test/core/multi-memory/memory_init0.wast:34
+invoke($0, `init`, [65536, 0, 0]);
+
+// ./test/core/multi-memory/memory_init0.wast:35
+invoke($0, `init`, [0, 4, 0]);
+
+// ./test/core/multi-memory/memory_init0.wast:38
+assert_trap(() => invoke($0, `init`, [65537, 0, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_init0.wast:40
+assert_trap(() => invoke($0, `init`, [0, 5, 0]), `out of bounds memory access`);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size.wast.js
new file mode 100644
index 0000000000..60d2bd604f
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size.wast.js
@@ -0,0 +1,208 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/memory_size.wast
+
+// ./test/core/memory_size.wast:1
+let $0 = instantiate(`(module
+ (memory 0)
+ (func (export "size") (result i32) (memory.size))
+ (func (export "grow") (param $$sz i32) (drop (memory.grow (local.get $$sz))))
+)`);
+
+// ./test/core/memory_size.wast:7
+assert_return(() => invoke($0, `size`, []), [value("i32", 0)]);
+
+// ./test/core/memory_size.wast:8
+assert_return(() => invoke($0, `grow`, [1]), []);
+
+// ./test/core/memory_size.wast:9
+assert_return(() => invoke($0, `size`, []), [value("i32", 1)]);
+
+// ./test/core/memory_size.wast:10
+assert_return(() => invoke($0, `grow`, [4]), []);
+
+// ./test/core/memory_size.wast:11
+assert_return(() => invoke($0, `size`, []), [value("i32", 5)]);
+
+// ./test/core/memory_size.wast:12
+assert_return(() => invoke($0, `grow`, [0]), []);
+
+// ./test/core/memory_size.wast:13
+assert_return(() => invoke($0, `size`, []), [value("i32", 5)]);
+
+// ./test/core/memory_size.wast:15
+let $1 = instantiate(`(module
+ (memory 1)
+ (func (export "size") (result i32) (memory.size))
+ (func (export "grow") (param $$sz i32) (drop (memory.grow (local.get $$sz))))
+)`);
+
+// ./test/core/memory_size.wast:21
+assert_return(() => invoke($1, `size`, []), [value("i32", 1)]);
+
+// ./test/core/memory_size.wast:22
+assert_return(() => invoke($1, `grow`, [1]), []);
+
+// ./test/core/memory_size.wast:23
+assert_return(() => invoke($1, `size`, []), [value("i32", 2)]);
+
+// ./test/core/memory_size.wast:24
+assert_return(() => invoke($1, `grow`, [4]), []);
+
+// ./test/core/memory_size.wast:25
+assert_return(() => invoke($1, `size`, []), [value("i32", 6)]);
+
+// ./test/core/memory_size.wast:26
+assert_return(() => invoke($1, `grow`, [0]), []);
+
+// ./test/core/memory_size.wast:27
+assert_return(() => invoke($1, `size`, []), [value("i32", 6)]);
+
+// ./test/core/memory_size.wast:29
+let $2 = instantiate(`(module
+ (memory 0 2)
+ (func (export "size") (result i32) (memory.size))
+ (func (export "grow") (param $$sz i32) (drop (memory.grow (local.get $$sz))))
+)`);
+
+// ./test/core/memory_size.wast:35
+assert_return(() => invoke($2, `size`, []), [value("i32", 0)]);
+
+// ./test/core/memory_size.wast:36
+assert_return(() => invoke($2, `grow`, [3]), []);
+
+// ./test/core/memory_size.wast:37
+assert_return(() => invoke($2, `size`, []), [value("i32", 0)]);
+
+// ./test/core/memory_size.wast:38
+assert_return(() => invoke($2, `grow`, [1]), []);
+
+// ./test/core/memory_size.wast:39
+assert_return(() => invoke($2, `size`, []), [value("i32", 1)]);
+
+// ./test/core/memory_size.wast:40
+assert_return(() => invoke($2, `grow`, [0]), []);
+
+// ./test/core/memory_size.wast:41
+assert_return(() => invoke($2, `size`, []), [value("i32", 1)]);
+
+// ./test/core/memory_size.wast:42
+assert_return(() => invoke($2, `grow`, [4]), []);
+
+// ./test/core/memory_size.wast:43
+assert_return(() => invoke($2, `size`, []), [value("i32", 1)]);
+
+// ./test/core/memory_size.wast:44
+assert_return(() => invoke($2, `grow`, [1]), []);
+
+// ./test/core/memory_size.wast:45
+assert_return(() => invoke($2, `size`, []), [value("i32", 2)]);
+
+// ./test/core/memory_size.wast:47
+let $3 = instantiate(`(module
+ (memory 3 8)
+ (func (export "size") (result i32) (memory.size))
+ (func (export "grow") (param $$sz i32) (drop (memory.grow (local.get $$sz))))
+)`);
+
+// ./test/core/memory_size.wast:53
+assert_return(() => invoke($3, `size`, []), [value("i32", 3)]);
+
+// ./test/core/memory_size.wast:54
+assert_return(() => invoke($3, `grow`, [1]), []);
+
+// ./test/core/memory_size.wast:55
+assert_return(() => invoke($3, `size`, []), [value("i32", 4)]);
+
+// ./test/core/memory_size.wast:56
+assert_return(() => invoke($3, `grow`, [3]), []);
+
+// ./test/core/memory_size.wast:57
+assert_return(() => invoke($3, `size`, []), [value("i32", 7)]);
+
+// ./test/core/memory_size.wast:58
+assert_return(() => invoke($3, `grow`, [0]), []);
+
+// ./test/core/memory_size.wast:59
+assert_return(() => invoke($3, `size`, []), [value("i32", 7)]);
+
+// ./test/core/memory_size.wast:60
+assert_return(() => invoke($3, `grow`, [2]), []);
+
+// ./test/core/memory_size.wast:61
+assert_return(() => invoke($3, `size`, []), [value("i32", 7)]);
+
+// ./test/core/memory_size.wast:62
+assert_return(() => invoke($3, `grow`, [1]), []);
+
+// ./test/core/memory_size.wast:63
+assert_return(() => invoke($3, `size`, []), [value("i32", 8)]);
+
+// ./test/core/memory_size.wast:68
+let $4 = instantiate(`(module
+ (memory (export "mem1") 2 4)
+ (memory (export "mem2") 0)
+)`);
+
+// ./test/core/memory_size.wast:72
+register($4, `M`);
+
+// ./test/core/memory_size.wast:74
+let $5 = instantiate(`(module
+ (memory $$mem1 (import "M" "mem1") 1 5)
+ (memory $$mem2 (import "M" "mem2") 0)
+ (memory $$mem3 3)
+ (memory $$mem4 4 5)
+
+ (func (export "size1") (result i32) (memory.size $$mem1))
+ (func (export "size2") (result i32) (memory.size $$mem2))
+ (func (export "size3") (result i32) (memory.size $$mem3))
+ (func (export "size4") (result i32) (memory.size $$mem4))
+)`);
+
+// ./test/core/memory_size.wast:86
+assert_return(() => invoke($5, `size1`, []), [value("i32", 2)]);
+
+// ./test/core/memory_size.wast:87
+assert_return(() => invoke($5, `size2`, []), [value("i32", 0)]);
+
+// ./test/core/memory_size.wast:88
+assert_return(() => invoke($5, `size3`, []), [value("i32", 3)]);
+
+// ./test/core/memory_size.wast:89
+assert_return(() => invoke($5, `size4`, []), [value("i32", 4)]);
+
+// ./test/core/memory_size.wast:94
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-result-i32-vs-empty
+ (memory.size)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/memory_size.wast:103
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-result-i32-vs-f32 (result f32)
+ (memory.size)
+ )
+ )`),
+ `type mismatch`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size0.wast.js
new file mode 100644
index 0000000000..78995555a1
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size0.wast.js
@@ -0,0 +1,49 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/memory_size0.wast
+
+// ./test/core/multi-memory/memory_size0.wast:1
+let $0 = instantiate(`(module
+ (memory 0)
+ (memory 0)
+ (memory 0)
+ (memory 0)
+ (memory $$m 0)
+
+ (func (export "size") (result i32) (memory.size $$m))
+ (func (export "grow") (param $$sz i32) (drop (memory.grow $$m (local.get $$sz))))
+)`);
+
+// ./test/core/multi-memory/memory_size0.wast:12
+assert_return(() => invoke($0, `size`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size0.wast:13
+assert_return(() => invoke($0, `grow`, [1]), []);
+
+// ./test/core/multi-memory/memory_size0.wast:14
+assert_return(() => invoke($0, `size`, []), [value("i32", 1)]);
+
+// ./test/core/multi-memory/memory_size0.wast:15
+assert_return(() => invoke($0, `grow`, [4]), []);
+
+// ./test/core/multi-memory/memory_size0.wast:16
+assert_return(() => invoke($0, `size`, []), [value("i32", 5)]);
+
+// ./test/core/multi-memory/memory_size0.wast:17
+assert_return(() => invoke($0, `grow`, [0]), []);
+
+// ./test/core/multi-memory/memory_size0.wast:18
+assert_return(() => invoke($0, `size`, []), [value("i32", 5)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size1.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size1.wast.js
new file mode 100644
index 0000000000..fa14876f09
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size1.wast.js
@@ -0,0 +1,73 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/memory_size1.wast
+
+// ./test/core/multi-memory/memory_size1.wast:1
+let $0 = instantiate(`(module
+ (memory 0)
+ (memory 0)
+ (memory $$n 0)
+ (memory 0)
+ (memory $$m 0)
+
+ (func (export "size") (result i32) (memory.size $$m))
+ (func (export "grow") (param $$sz i32) (drop (memory.grow $$m (local.get $$sz))))
+
+ (func (export "sizen") (result i32) (memory.size $$n))
+ (func (export "grown") (param $$sz i32) (drop (memory.grow $$n (local.get $$sz))))
+)`);
+
+// ./test/core/multi-memory/memory_size1.wast:15
+assert_return(() => invoke($0, `size`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size1.wast:16
+assert_return(() => invoke($0, `sizen`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size1.wast:17
+assert_return(() => invoke($0, `grow`, [1]), []);
+
+// ./test/core/multi-memory/memory_size1.wast:18
+assert_return(() => invoke($0, `size`, []), [value("i32", 1)]);
+
+// ./test/core/multi-memory/memory_size1.wast:19
+assert_return(() => invoke($0, `sizen`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size1.wast:20
+assert_return(() => invoke($0, `grow`, [4]), []);
+
+// ./test/core/multi-memory/memory_size1.wast:21
+assert_return(() => invoke($0, `size`, []), [value("i32", 5)]);
+
+// ./test/core/multi-memory/memory_size1.wast:22
+assert_return(() => invoke($0, `sizen`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size1.wast:23
+assert_return(() => invoke($0, `grow`, [0]), []);
+
+// ./test/core/multi-memory/memory_size1.wast:24
+assert_return(() => invoke($0, `size`, []), [value("i32", 5)]);
+
+// ./test/core/multi-memory/memory_size1.wast:25
+assert_return(() => invoke($0, `sizen`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size1.wast:27
+assert_return(() => invoke($0, `grown`, [1]), []);
+
+// ./test/core/multi-memory/memory_size1.wast:28
+assert_return(() => invoke($0, `size`, []), [value("i32", 5)]);
+
+// ./test/core/multi-memory/memory_size1.wast:29
+assert_return(() => invoke($0, `sizen`, []), [value("i32", 1)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size2.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size2.wast.js
new file mode 100644
index 0000000000..8feeadb2ee
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size2.wast.js
@@ -0,0 +1,90 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/memory_size2.wast
+
+// ./test/core/multi-memory/memory_size2.wast:1
+let $0 = instantiate(`(module
+ (memory 0 0)
+ (memory 0 0)
+ (memory $$n 0 0)
+ (memory $$m 0 2)
+
+ (func (export "size") (result i32) (memory.size $$m))
+ (func (export "grow") (param $$sz i32) (drop (memory.grow $$m (local.get $$sz))))
+
+ (func (export "sizen") (result i32) (memory.size $$n))
+ (func (export "grown") (param $$sz i32) (drop (memory.grow $$n (local.get $$sz))))
+)`);
+
+// ./test/core/multi-memory/memory_size2.wast:14
+assert_return(() => invoke($0, `size`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size2.wast:15
+assert_return(() => invoke($0, `sizen`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size2.wast:16
+assert_return(() => invoke($0, `grow`, [3]), []);
+
+// ./test/core/multi-memory/memory_size2.wast:17
+assert_return(() => invoke($0, `sizen`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size2.wast:18
+assert_return(() => invoke($0, `size`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size2.wast:19
+assert_return(() => invoke($0, `grow`, [1]), []);
+
+// ./test/core/multi-memory/memory_size2.wast:20
+assert_return(() => invoke($0, `sizen`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size2.wast:21
+assert_return(() => invoke($0, `size`, []), [value("i32", 1)]);
+
+// ./test/core/multi-memory/memory_size2.wast:22
+assert_return(() => invoke($0, `grow`, [0]), []);
+
+// ./test/core/multi-memory/memory_size2.wast:23
+assert_return(() => invoke($0, `sizen`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size2.wast:24
+assert_return(() => invoke($0, `size`, []), [value("i32", 1)]);
+
+// ./test/core/multi-memory/memory_size2.wast:25
+assert_return(() => invoke($0, `grow`, [4]), []);
+
+// ./test/core/multi-memory/memory_size2.wast:26
+assert_return(() => invoke($0, `sizen`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size2.wast:27
+assert_return(() => invoke($0, `size`, []), [value("i32", 1)]);
+
+// ./test/core/multi-memory/memory_size2.wast:28
+assert_return(() => invoke($0, `grow`, [1]), []);
+
+// ./test/core/multi-memory/memory_size2.wast:29
+assert_return(() => invoke($0, `sizen`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size2.wast:30
+assert_return(() => invoke($0, `size`, []), [value("i32", 2)]);
+
+// ./test/core/multi-memory/memory_size2.wast:32
+assert_return(() => invoke($0, `grown`, [1]), []);
+
+// ./test/core/multi-memory/memory_size2.wast:33
+assert_return(() => invoke($0, `sizen`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_size2.wast:34
+assert_return(() => invoke($0, `size`, []), [value("i32", 2)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size3.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size3.wast.js
new file mode 100644
index 0000000000..f30a09f73a
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_size3.wast.js
@@ -0,0 +1,43 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/memory_size3.wast
+
+// ./test/core/multi-memory/memory_size3.wast:3
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (memory $$m 1)
+ (memory 0)
+ (func $$type-result-i32-vs-empty
+ (memory.size $$m)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/multi-memory/memory_size3.wast:14
+assert_invalid(
+ () => instantiate(`(module
+ (memory 0)
+ (memory 0)
+ (memory 0)
+ (memory $$m 1)
+ (func $$type-result-i32-vs-f32 (result f32)
+ (memory.size $$m)
+ )
+ )`),
+ `type mismatch`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/memory_trap0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_trap0.wast.js
new file mode 100644
index 0000000000..1739a5bcb6
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_trap0.wast.js
@@ -0,0 +1,78 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/memory_trap0.wast
+
+// ./test/core/multi-memory/memory_trap0.wast:1
+let $0 = instantiate(`(module
+ (memory 0)
+ (memory 0)
+ (memory $$m 1)
+
+ (func $$addr_limit (result i32)
+ (i32.mul (memory.size $$m) (i32.const 0x10000))
+ )
+
+ (func (export "store") (param $$i i32) (param $$v i32)
+ (i32.store $$m (i32.add (call $$addr_limit) (local.get $$i)) (local.get $$v))
+ )
+
+ (func (export "load") (param $$i i32) (result i32)
+ (i32.load $$m (i32.add (call $$addr_limit) (local.get $$i)))
+ )
+
+ (func (export "memory.grow") (param i32) (result i32)
+ (memory.grow $$m (local.get 0))
+ )
+)`);
+
+// ./test/core/multi-memory/memory_trap0.wast:23
+assert_return(() => invoke($0, `store`, [-4, 42]), []);
+
+// ./test/core/multi-memory/memory_trap0.wast:24
+assert_return(() => invoke($0, `load`, [-4]), [value("i32", 42)]);
+
+// ./test/core/multi-memory/memory_trap0.wast:25
+assert_trap(() => invoke($0, `store`, [-3, 305419896]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap0.wast:26
+assert_trap(() => invoke($0, `load`, [-3]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap0.wast:27
+assert_trap(() => invoke($0, `store`, [-2, 13]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap0.wast:28
+assert_trap(() => invoke($0, `load`, [-2]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap0.wast:29
+assert_trap(() => invoke($0, `store`, [-1, 13]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap0.wast:30
+assert_trap(() => invoke($0, `load`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap0.wast:31
+assert_trap(() => invoke($0, `store`, [0, 13]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap0.wast:32
+assert_trap(() => invoke($0, `load`, [0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap0.wast:33
+assert_trap(() => invoke($0, `store`, [-2147483648, 13]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap0.wast:34
+assert_trap(() => invoke($0, `load`, [-2147483648]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap0.wast:35
+assert_return(() => invoke($0, `memory.grow`, [65537]), [value("i32", -1)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/memory_trap1.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_trap1.wast.js
new file mode 100644
index 0000000000..ef68a1c0ec
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/memory_trap1.wast.js
@@ -0,0 +1,602 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/memory_trap1.wast
+
+// ./test/core/multi-memory/memory_trap1.wast:1
+let $0 = instantiate(`(module
+ (memory 0)
+ (memory 0)
+ (memory $$m 1)
+ (data (memory 2) (i32.const 0) "abcdefgh")
+ (data (memory 2) (i32.const 0xfff8) "abcdefgh")
+
+ (func (export "i32.load") (param $$a i32) (result i32)
+ (i32.load $$m (local.get $$a))
+ )
+ (func (export "i64.load") (param $$a i32) (result i64)
+ (i64.load $$m (local.get $$a))
+ )
+ (func (export "f32.load") (param $$a i32) (result f32)
+ (f32.load $$m (local.get $$a))
+ )
+ (func (export "f64.load") (param $$a i32) (result f64)
+ (f64.load $$m (local.get $$a))
+ )
+ (func (export "i32.load8_s") (param $$a i32) (result i32)
+ (i32.load8_s $$m (local.get $$a))
+ )
+ (func (export "i32.load8_u") (param $$a i32) (result i32)
+ (i32.load8_u $$m (local.get $$a))
+ )
+ (func (export "i32.load16_s") (param $$a i32) (result i32)
+ (i32.load16_s $$m (local.get $$a))
+ )
+ (func (export "i32.load16_u") (param $$a i32) (result i32)
+ (i32.load16_u $$m (local.get $$a))
+ )
+ (func (export "i64.load8_s") (param $$a i32) (result i64)
+ (i64.load8_s $$m (local.get $$a))
+ )
+ (func (export "i64.load8_u") (param $$a i32) (result i64)
+ (i64.load8_u $$m (local.get $$a))
+ )
+ (func (export "i64.load16_s") (param $$a i32) (result i64)
+ (i64.load16_s $$m (local.get $$a))
+ )
+ (func (export "i64.load16_u") (param $$a i32) (result i64)
+ (i64.load16_u $$m (local.get $$a))
+ )
+ (func (export "i64.load32_s") (param $$a i32) (result i64)
+ (i64.load32_s $$m (local.get $$a))
+ )
+ (func (export "i64.load32_u") (param $$a i32) (result i64)
+ (i64.load32_u $$m (local.get $$a))
+ )
+ (func (export "i32.store") (param $$a i32) (param $$v i32)
+ (i32.store $$m (local.get $$a) (local.get $$v))
+ )
+ (func (export "i64.store") (param $$a i32) (param $$v i64)
+ (i64.store $$m (local.get $$a) (local.get $$v))
+ )
+ (func (export "f32.store") (param $$a i32) (param $$v f32)
+ (f32.store $$m (local.get $$a) (local.get $$v))
+ )
+ (func (export "f64.store") (param $$a i32) (param $$v f64)
+ (f64.store $$m (local.get $$a) (local.get $$v))
+ )
+ (func (export "i32.store8") (param $$a i32) (param $$v i32)
+ (i32.store8 $$m (local.get $$a) (local.get $$v))
+ )
+ (func (export "i32.store16") (param $$a i32) (param $$v i32)
+ (i32.store16 $$m (local.get $$a) (local.get $$v))
+ )
+ (func (export "i64.store8") (param $$a i32) (param $$v i64)
+ (i64.store8 $$m (local.get $$a) (local.get $$v))
+ )
+ (func (export "i64.store16") (param $$a i32) (param $$v i64)
+ (i64.store16 $$m (local.get $$a) (local.get $$v))
+ )
+ (func (export "i64.store32") (param $$a i32) (param $$v i64)
+ (i64.store32 $$m (local.get $$a) (local.get $$v))
+ )
+)`);
+
+// ./test/core/multi-memory/memory_trap1.wast:79
+assert_trap(() => invoke($0, `i32.store`, [65536, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:80
+assert_trap(() => invoke($0, `i32.store`, [65535, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:81
+assert_trap(() => invoke($0, `i32.store`, [65534, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:82
+assert_trap(() => invoke($0, `i32.store`, [65533, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:83
+assert_trap(() => invoke($0, `i32.store`, [-1, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:84
+assert_trap(() => invoke($0, `i32.store`, [-2, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:85
+assert_trap(() => invoke($0, `i32.store`, [-3, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:86
+assert_trap(() => invoke($0, `i32.store`, [-4, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:87
+assert_trap(() => invoke($0, `i64.store`, [65536, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:88
+assert_trap(() => invoke($0, `i64.store`, [65535, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:89
+assert_trap(() => invoke($0, `i64.store`, [65534, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:90
+assert_trap(() => invoke($0, `i64.store`, [65533, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:91
+assert_trap(() => invoke($0, `i64.store`, [65532, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:92
+assert_trap(() => invoke($0, `i64.store`, [65531, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:93
+assert_trap(() => invoke($0, `i64.store`, [65530, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:94
+assert_trap(() => invoke($0, `i64.store`, [65529, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:95
+assert_trap(() => invoke($0, `i64.store`, [-1, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:96
+assert_trap(() => invoke($0, `i64.store`, [-2, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:97
+assert_trap(() => invoke($0, `i64.store`, [-3, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:98
+assert_trap(() => invoke($0, `i64.store`, [-4, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:99
+assert_trap(() => invoke($0, `i64.store`, [-5, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:100
+assert_trap(() => invoke($0, `i64.store`, [-6, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:101
+assert_trap(() => invoke($0, `i64.store`, [-7, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:102
+assert_trap(() => invoke($0, `i64.store`, [-8, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:103
+assert_trap(() => invoke($0, `f32.store`, [65536, value("f32", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:104
+assert_trap(() => invoke($0, `f32.store`, [65535, value("f32", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:105
+assert_trap(() => invoke($0, `f32.store`, [65534, value("f32", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:106
+assert_trap(() => invoke($0, `f32.store`, [65533, value("f32", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:107
+assert_trap(() => invoke($0, `f32.store`, [-1, value("f32", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:108
+assert_trap(() => invoke($0, `f32.store`, [-2, value("f32", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:109
+assert_trap(() => invoke($0, `f32.store`, [-3, value("f32", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:110
+assert_trap(() => invoke($0, `f32.store`, [-4, value("f32", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:111
+assert_trap(() => invoke($0, `f64.store`, [65536, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:112
+assert_trap(() => invoke($0, `f64.store`, [65535, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:113
+assert_trap(() => invoke($0, `f64.store`, [65534, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:114
+assert_trap(() => invoke($0, `f64.store`, [65533, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:115
+assert_trap(() => invoke($0, `f64.store`, [65532, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:116
+assert_trap(() => invoke($0, `f64.store`, [65531, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:117
+assert_trap(() => invoke($0, `f64.store`, [65530, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:118
+assert_trap(() => invoke($0, `f64.store`, [65529, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:119
+assert_trap(() => invoke($0, `f64.store`, [-1, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:120
+assert_trap(() => invoke($0, `f64.store`, [-2, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:121
+assert_trap(() => invoke($0, `f64.store`, [-3, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:122
+assert_trap(() => invoke($0, `f64.store`, [-4, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:123
+assert_trap(() => invoke($0, `f64.store`, [-5, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:124
+assert_trap(() => invoke($0, `f64.store`, [-6, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:125
+assert_trap(() => invoke($0, `f64.store`, [-7, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:126
+assert_trap(() => invoke($0, `f64.store`, [-8, value("f64", 0)]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:127
+assert_trap(() => invoke($0, `i32.store8`, [65536, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:128
+assert_trap(() => invoke($0, `i32.store8`, [-1, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:129
+assert_trap(() => invoke($0, `i32.store16`, [65536, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:130
+assert_trap(() => invoke($0, `i32.store16`, [65535, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:131
+assert_trap(() => invoke($0, `i32.store16`, [-1, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:132
+assert_trap(() => invoke($0, `i32.store16`, [-2, 0]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:133
+assert_trap(() => invoke($0, `i64.store8`, [65536, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:134
+assert_trap(() => invoke($0, `i64.store8`, [-1, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:135
+assert_trap(() => invoke($0, `i64.store16`, [65536, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:136
+assert_trap(() => invoke($0, `i64.store16`, [65535, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:137
+assert_trap(() => invoke($0, `i64.store16`, [-1, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:138
+assert_trap(() => invoke($0, `i64.store16`, [-2, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:139
+assert_trap(() => invoke($0, `i64.store32`, [65536, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:140
+assert_trap(() => invoke($0, `i64.store32`, [65535, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:141
+assert_trap(() => invoke($0, `i64.store32`, [65534, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:142
+assert_trap(() => invoke($0, `i64.store32`, [65533, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:143
+assert_trap(() => invoke($0, `i64.store32`, [-1, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:144
+assert_trap(() => invoke($0, `i64.store32`, [-2, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:145
+assert_trap(() => invoke($0, `i64.store32`, [-3, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:146
+assert_trap(() => invoke($0, `i64.store32`, [-4, 0n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:147
+assert_trap(() => invoke($0, `i32.load`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:148
+assert_trap(() => invoke($0, `i32.load`, [65535]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:149
+assert_trap(() => invoke($0, `i32.load`, [65534]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:150
+assert_trap(() => invoke($0, `i32.load`, [65533]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:151
+assert_trap(() => invoke($0, `i32.load`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:152
+assert_trap(() => invoke($0, `i32.load`, [-2]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:153
+assert_trap(() => invoke($0, `i32.load`, [-3]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:154
+assert_trap(() => invoke($0, `i32.load`, [-4]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:155
+assert_trap(() => invoke($0, `i64.load`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:156
+assert_trap(() => invoke($0, `i64.load`, [65535]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:157
+assert_trap(() => invoke($0, `i64.load`, [65534]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:158
+assert_trap(() => invoke($0, `i64.load`, [65533]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:159
+assert_trap(() => invoke($0, `i64.load`, [65532]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:160
+assert_trap(() => invoke($0, `i64.load`, [65531]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:161
+assert_trap(() => invoke($0, `i64.load`, [65530]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:162
+assert_trap(() => invoke($0, `i64.load`, [65529]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:163
+assert_trap(() => invoke($0, `i64.load`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:164
+assert_trap(() => invoke($0, `i64.load`, [-2]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:165
+assert_trap(() => invoke($0, `i64.load`, [-3]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:166
+assert_trap(() => invoke($0, `i64.load`, [-4]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:167
+assert_trap(() => invoke($0, `i64.load`, [-5]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:168
+assert_trap(() => invoke($0, `i64.load`, [-6]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:169
+assert_trap(() => invoke($0, `i64.load`, [-7]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:170
+assert_trap(() => invoke($0, `i64.load`, [-8]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:171
+assert_trap(() => invoke($0, `f32.load`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:172
+assert_trap(() => invoke($0, `f32.load`, [65535]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:173
+assert_trap(() => invoke($0, `f32.load`, [65534]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:174
+assert_trap(() => invoke($0, `f32.load`, [65533]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:175
+assert_trap(() => invoke($0, `f32.load`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:176
+assert_trap(() => invoke($0, `f32.load`, [-2]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:177
+assert_trap(() => invoke($0, `f32.load`, [-3]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:178
+assert_trap(() => invoke($0, `f32.load`, [-4]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:179
+assert_trap(() => invoke($0, `f64.load`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:180
+assert_trap(() => invoke($0, `f64.load`, [65535]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:181
+assert_trap(() => invoke($0, `f64.load`, [65534]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:182
+assert_trap(() => invoke($0, `f64.load`, [65533]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:183
+assert_trap(() => invoke($0, `f64.load`, [65532]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:184
+assert_trap(() => invoke($0, `f64.load`, [65531]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:185
+assert_trap(() => invoke($0, `f64.load`, [65530]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:186
+assert_trap(() => invoke($0, `f64.load`, [65529]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:187
+assert_trap(() => invoke($0, `f64.load`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:188
+assert_trap(() => invoke($0, `f64.load`, [-2]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:189
+assert_trap(() => invoke($0, `f64.load`, [-3]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:190
+assert_trap(() => invoke($0, `f64.load`, [-4]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:191
+assert_trap(() => invoke($0, `f64.load`, [-5]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:192
+assert_trap(() => invoke($0, `f64.load`, [-6]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:193
+assert_trap(() => invoke($0, `f64.load`, [-7]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:194
+assert_trap(() => invoke($0, `f64.load`, [-8]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:195
+assert_trap(() => invoke($0, `i32.load8_s`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:196
+assert_trap(() => invoke($0, `i32.load8_s`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:197
+assert_trap(() => invoke($0, `i32.load8_u`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:198
+assert_trap(() => invoke($0, `i32.load8_u`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:199
+assert_trap(() => invoke($0, `i32.load16_s`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:200
+assert_trap(() => invoke($0, `i32.load16_s`, [65535]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:201
+assert_trap(() => invoke($0, `i32.load16_s`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:202
+assert_trap(() => invoke($0, `i32.load16_s`, [-2]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:203
+assert_trap(() => invoke($0, `i32.load16_u`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:204
+assert_trap(() => invoke($0, `i32.load16_u`, [65535]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:205
+assert_trap(() => invoke($0, `i32.load16_u`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:206
+assert_trap(() => invoke($0, `i32.load16_u`, [-2]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:207
+assert_trap(() => invoke($0, `i64.load8_s`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:208
+assert_trap(() => invoke($0, `i64.load8_s`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:209
+assert_trap(() => invoke($0, `i64.load8_u`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:210
+assert_trap(() => invoke($0, `i64.load8_u`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:211
+assert_trap(() => invoke($0, `i64.load16_s`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:212
+assert_trap(() => invoke($0, `i64.load16_s`, [65535]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:213
+assert_trap(() => invoke($0, `i64.load16_s`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:214
+assert_trap(() => invoke($0, `i64.load16_s`, [-2]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:215
+assert_trap(() => invoke($0, `i64.load16_u`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:216
+assert_trap(() => invoke($0, `i64.load16_u`, [65535]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:217
+assert_trap(() => invoke($0, `i64.load16_u`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:218
+assert_trap(() => invoke($0, `i64.load16_u`, [-2]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:219
+assert_trap(() => invoke($0, `i64.load32_s`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:220
+assert_trap(() => invoke($0, `i64.load32_s`, [65535]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:221
+assert_trap(() => invoke($0, `i64.load32_s`, [65534]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:222
+assert_trap(() => invoke($0, `i64.load32_s`, [65533]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:223
+assert_trap(() => invoke($0, `i64.load32_s`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:224
+assert_trap(() => invoke($0, `i64.load32_s`, [-2]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:225
+assert_trap(() => invoke($0, `i64.load32_s`, [-3]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:226
+assert_trap(() => invoke($0, `i64.load32_s`, [-4]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:227
+assert_trap(() => invoke($0, `i64.load32_u`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:228
+assert_trap(() => invoke($0, `i64.load32_u`, [65535]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:229
+assert_trap(() => invoke($0, `i64.load32_u`, [65534]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:230
+assert_trap(() => invoke($0, `i64.load32_u`, [65533]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:231
+assert_trap(() => invoke($0, `i64.load32_u`, [-1]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:232
+assert_trap(() => invoke($0, `i64.load32_u`, [-2]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:233
+assert_trap(() => invoke($0, `i64.load32_u`, [-3]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:234
+assert_trap(() => invoke($0, `i64.load32_u`, [-4]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:237
+assert_return(() => invoke($0, `i64.load`, [65528]), [value("i64", 7523094288207667809n)]);
+
+// ./test/core/multi-memory/memory_trap1.wast:238
+assert_return(() => invoke($0, `i64.load`, [0]), [value("i64", 7523094288207667809n)]);
+
+// ./test/core/multi-memory/memory_trap1.wast:242
+assert_return(() => invoke($0, `i64.store`, [65528, 0n]), []);
+
+// ./test/core/multi-memory/memory_trap1.wast:243
+assert_trap(() => invoke($0, `i32.store`, [65533, 305419896]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:244
+assert_return(() => invoke($0, `i32.load`, [65532]), [value("i32", 0)]);
+
+// ./test/core/multi-memory/memory_trap1.wast:245
+assert_trap(() => invoke($0, `i64.store`, [65529, 1311768467294899695n]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/memory_trap1.wast:246
+assert_return(() => invoke($0, `i64.load`, [65528]), [value("i64", 0n)]);
+
+// ./test/core/multi-memory/memory_trap1.wast:247
+assert_trap(
+ () => invoke($0, `f32.store`, [65533, value("f32", 305419900)]),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/memory_trap1.wast:248
+assert_return(() => invoke($0, `f32.load`, [65532]), [value("f32", 0)]);
+
+// ./test/core/multi-memory/memory_trap1.wast:249
+assert_trap(
+ () => invoke($0, `f64.store`, [65529, value("f64", 1311768467294899700)]),
+ `out of bounds memory access`,
+);
+
+// ./test/core/multi-memory/memory_trap1.wast:250
+assert_return(() => invoke($0, `f64.load`, [65528]), [value("f64", 0)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/simd_load.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/simd_load.wast.js
new file mode 100644
index 0000000000..e609e1fe58
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/simd_load.wast.js
@@ -0,0 +1,295 @@
+// |jit-test| skip-if: !wasmSimdEnabled()
+
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/simd/simd_load.wast
+
+// ./test/core/simd/simd_load.wast:3
+let $0 = instantiate(`(module
+ (memory 1)
+ (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f\\00\\01\\02\\03")
+ (func (export "v128.load") (result v128)
+ (v128.load (i32.const 0))
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:11
+assert_return(
+ () => invoke($0, `v128.load`, []),
+ [
+ i8x16([0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf]),
+ ],
+);
+
+// ./test/core/simd/simd_load.wast:12
+assert_return(
+ () => invoke($0, `v128.load`, []),
+ [i16x8([0x100, 0x302, 0x504, 0x706, 0x908, 0xb0a, 0xd0c, 0xf0e])],
+);
+
+// ./test/core/simd/simd_load.wast:13
+assert_return(() => invoke($0, `v128.load`, []), [i32x4([0x3020100, 0x7060504, 0xb0a0908, 0xf0e0d0c])]);
+
+// ./test/core/simd/simd_load.wast:18
+let $1 = instantiate(`(module (memory 1)
+ (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f\\00\\01\\02\\03")
+ (func (export "as-i8x16_extract_lane_s-value/0") (result i32)
+ (i8x16.extract_lane_s 0 (v128.load (i32.const 0)))
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:24
+assert_return(() => invoke($1, `as-i8x16_extract_lane_s-value/0`, []), [value("i32", 0)]);
+
+// ./test/core/simd/simd_load.wast:26
+let $2 = instantiate(`(module (memory 1)
+ (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f\\00\\01\\02\\03")
+ (func (export "as-i8x16.eq-operand") (result v128)
+ (i8x16.eq (v128.load offset=0 (i32.const 0)) (v128.load offset=16 (i32.const 0)))
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:32
+assert_return(() => invoke($2, `as-i8x16.eq-operand`, []), [i32x4([0xffffffff, 0x0, 0x0, 0x0])]);
+
+// ./test/core/simd/simd_load.wast:34
+let $3 = instantiate(`(module (memory 1)
+ (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f\\00\\01\\02\\03")
+ (func (export "as-v128.not-operand") (result v128)
+ (v128.not (v128.load (i32.const 0)))
+ )
+ (func (export "as-i8x16.all_true-operand") (result i32)
+ (i8x16.all_true (v128.load (i32.const 0)))
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:43
+assert_return(
+ () => invoke($3, `as-v128.not-operand`, []),
+ [i32x4([0xfcfdfeff, 0xf8f9fafb, 0xf4f5f6f7, 0xf0f1f2f3])],
+);
+
+// ./test/core/simd/simd_load.wast:44
+assert_return(() => invoke($3, `as-i8x16.all_true-operand`, []), [value("i32", 0)]);
+
+// ./test/core/simd/simd_load.wast:46
+let $4 = instantiate(`(module (memory 1)
+ (data (offset (i32.const 0)) "\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA")
+ (data (offset (i32.const 16)) "\\BB\\BB\\BB\\BB\\BB\\BB\\BB\\BB\\BB\\BB\\BB\\BB\\BB\\BB\\BB\\BB")
+ (data (offset (i32.const 32)) "\\F0\\F0\\F0\\F0\\FF\\FF\\FF\\FF\\00\\00\\00\\00\\FF\\00\\FF\\00")
+ (func (export "as-v128.bitselect-operand") (result v128)
+ (v128.bitselect (v128.load (i32.const 0)) (v128.load (i32.const 16)) (v128.load (i32.const 32)))
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:54
+assert_return(
+ () => invoke($4, `as-v128.bitselect-operand`, []),
+ [i32x4([0xabababab, 0xaaaaaaaa, 0xbbbbbbbb, 0xbbaabbaa])],
+);
+
+// ./test/core/simd/simd_load.wast:56
+let $5 = instantiate(`(module (memory 1)
+ (data (offset (i32.const 0)) "\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA")
+ (func (export "as-i8x16.shl-operand") (result v128)
+ (i8x16.shl (v128.load (i32.const 0)) (i32.const 1))
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:62
+assert_return(
+ () => invoke($5, `as-i8x16.shl-operand`, []),
+ [i32x4([0x54545454, 0x54545454, 0x54545454, 0x54545454])],
+);
+
+// ./test/core/simd/simd_load.wast:64
+let $6 = instantiate(`(module (memory 1)
+ (data (offset (i32.const 0)) "\\02\\00\\00\\00\\02\\00\\00\\00\\02\\00\\00\\00\\02\\00\\00\\00")
+ (data (offset (i32.const 16)) "\\03\\00\\00\\00\\03\\00\\00\\00\\03\\00\\00\\00\\03\\00\\00\\00")
+ (func (export "as-add/sub-operand") (result v128)
+ ;; 2 2 2 2 + 3 3 3 3 = 5 5 5 5
+ ;; 5 5 5 5 - 3 3 3 3 = 2 2 2 2
+ (i8x16.sub
+ (i8x16.add (v128.load (i32.const 0)) (v128.load (i32.const 16)))
+ (v128.load (i32.const 16))
+ )
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:76
+assert_return(() => invoke($6, `as-add/sub-operand`, []), [i32x4([0x2, 0x2, 0x2, 0x2])]);
+
+// ./test/core/simd/simd_load.wast:78
+let $7 = instantiate(`(module (memory 1)
+ (data (offset (i32.const 0)) "\\00\\00\\00\\43\\00\\00\\80\\3f\\66\\66\\e6\\3f\\00\\00\\80\\bf") ;; 128 1.0 1.8 -1
+ (data (offset (i32.const 16)) "\\00\\00\\00\\40\\00\\00\\00\\40\\00\\00\\00\\40\\00\\00\\00\\40") ;; 2.0 2.0 2.0 2.0
+ (func (export "as-f32x4.mul-operand") (result v128)
+ (f32x4.mul (v128.load (i32.const 0)) (v128.load (i32.const 16)))
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:85
+assert_return(
+ () => invoke($7, `as-f32x4.mul-operand`, []),
+ [
+ new F32x4Pattern(
+ value("f32", 256),
+ value("f32", 2),
+ value("f32", 3.6),
+ value("f32", -2),
+ ),
+ ],
+);
+
+// ./test/core/simd/simd_load.wast:87
+let $8 = instantiate(`(module (memory 1)
+ (data (offset (i32.const 0)) "\\ff\\ff\\ff\\ff\\ff\\ff\\ff\\ff\\ff\\ff\\ff\\ff\\ff\\ff\\ff\\ff") ;; 1111 ...
+ (func (export "as-f32x4.abs-operand") (result v128)
+ (f32x4.abs (v128.load (i32.const 0)))
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:93
+assert_return(
+ () => invoke($8, `as-f32x4.abs-operand`, []),
+ [i32x4([0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff])],
+);
+
+// ./test/core/simd/simd_load.wast:95
+let $9 = instantiate(`(module (memory 1)
+ (data (offset (i32.const 0)) "\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA\\AA")
+ (data (offset (i32.const 16)) "\\02\\00\\00\\00\\02\\00\\00\\00\\02\\00\\00\\00\\02\\00\\00\\00")
+ (func (export "as-f32x4.min-operand") (result v128)
+ (f32x4.min (v128.load (i32.const 0)) (v128.load offset=16 (i32.const 1)))
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:102
+assert_return(
+ () => invoke($9, `as-f32x4.min-operand`, []),
+ [i32x4([0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa])],
+);
+
+// ./test/core/simd/simd_load.wast:104
+let $10 = instantiate(`(module (memory 1)
+ (data (offset (i32.const 0)) "\\00\\00\\00\\43\\00\\00\\80\\3f\\66\\66\\e6\\3f\\00\\00\\80\\bf") ;; 128 1.0 1.8 -1
+ (func (export "as-i32x4.trunc_sat_f32x4_s-operand") (result v128)
+ (i32x4.trunc_sat_f32x4_s (v128.load (i32.const 0)))
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:110
+assert_return(
+ () => invoke($10, `as-i32x4.trunc_sat_f32x4_s-operand`, []),
+ [i32x4([0x80, 0x1, 0x1, 0xffffffff])],
+);
+
+// ./test/core/simd/simd_load.wast:112
+let $11 = instantiate(`(module (memory 1)
+ (data (offset (i32.const 0)) "\\02\\00\\00\\00\\02\\00\\00\\00\\02\\00\\00\\00\\02\\00\\00\\00")
+ (func (export "as-f32x4.convert_i32x4_u-operand") (result v128)
+ (f32x4.convert_i32x4_u (v128.load (i32.const 0)))
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:118
+assert_return(
+ () => invoke($11, `as-f32x4.convert_i32x4_u-operand`, []),
+ [
+ new F32x4Pattern(
+ value("f32", 2),
+ value("f32", 2),
+ value("f32", 2),
+ value("f32", 2),
+ ),
+ ],
+);
+
+// ./test/core/simd/simd_load.wast:120
+let $12 = instantiate(`(module (memory 1)
+ (data (offset (i32.const 0)) "\\64\\65\\66\\67\\68\\69\\6a\\6b\\6c\\6d\\6e\\6f\\70\\71\\72\\73") ;; 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
+ (data (offset (i32.const 16)) "\\0f\\0e\\0d\\0c\\0b\\0a\\09\\08\\07\\06\\05\\04\\03\\02\\01\\00") ;; 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
+ (func (export "as-i8x16.swizzle-operand") (result v128)
+ (i8x16.swizzle (v128.load (i32.const 0)) (v128.load offset=15 (i32.const 1)))
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:127
+assert_return(
+ () => invoke($12, `as-i8x16.swizzle-operand`, []),
+ [
+ i8x16([0x73, 0x72, 0x71, 0x70, 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64]),
+ ],
+);
+
+// ./test/core/simd/simd_load.wast:129
+let $13 = instantiate(`(module (memory 1)
+ (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f\\00\\01\\02\\03")
+ (func (export "as-br-value") (result v128)
+ (block (result v128) (br 0 (v128.load (i32.const 0))))
+ )
+)`);
+
+// ./test/core/simd/simd_load.wast:135
+assert_return(() => invoke($13, `as-br-value`, []), [i32x4([0x3020100, 0x7060504, 0xb0a0908, 0xf0e0d0c])]);
+
+// ./test/core/simd/simd_load.wast:140
+assert_malformed(
+ () => instantiate(`(memory 1) (func (local v128) (drop (v128.load8 (i32.const 0)))) `),
+ `unknown operator`,
+);
+
+// ./test/core/simd/simd_load.wast:147
+assert_malformed(
+ () => instantiate(`(memory 1) (func (local v128) (drop (v128.load16 (i32.const 0)))) `),
+ `unknown operator`,
+);
+
+// ./test/core/simd/simd_load.wast:154
+assert_malformed(
+ () => instantiate(`(memory 1) (func (local v128) (drop (v128.load32 (i32.const 0)))) `),
+ `unknown operator`,
+);
+
+// ./test/core/simd/simd_load.wast:165
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (local v128) (drop (v128.load (f32.const 0)))))`),
+ `type mismatch`,
+);
+
+// ./test/core/simd/simd_load.wast:169
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (local v128) (block (br_if 0 (v128.load (i32.const 0))))))`),
+ `type mismatch`,
+);
+
+// ./test/core/simd/simd_load.wast:173
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (local v128) (v128.load (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/simd/simd_load.wast:181
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (drop (v128.load (local.get 2)))))`),
+ `unknown local 2`,
+);
+
+// ./test/core/simd/simd_load.wast:185
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (drop (v128.load))))`),
+ `type mismatch`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/simd_memory-multi.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/simd_memory-multi.wast.js
new file mode 100644
index 0000000000..7214d0785e
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/simd_memory-multi.wast.js
@@ -0,0 +1,58 @@
+// |jit-test| skip-if: !wasmSimdEnabled()
+
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/simd/simd_memory-multi.wast
+
+// ./test/core/simd/simd_memory-multi.wast:5
+let $0 = instantiate(`(module
+ (memory 1)
+ (memory $$m 1)
+
+ (func
+ (local $$v v128)
+
+ (drop (v128.load8_lane 1 (i32.const 0) (local.get $$v)))
+ (drop (v128.load8_lane 1 offset=0 1 (i32.const 0) (local.get $$v)))
+ (drop (v128.load8_lane 1 offset=0 align=1 1 (i32.const 0) (local.get $$v)))
+ (drop (v128.load8_lane 1 align=1 1 (i32.const 0) (local.get $$v)))
+
+ (drop (v128.load8_lane $$m 1 (i32.const 0) (local.get $$v)))
+ (drop (v128.load8_lane $$m offset=0 1 (i32.const 0) (local.get $$v)))
+ (drop (v128.load8_lane $$m offset=0 align=1 1 (i32.const 0) (local.get $$v)))
+ (drop (v128.load8_lane $$m align=1 1 (i32.const 0) (local.get $$v)))
+
+ (drop (v128.load8_lane 1 1 (i32.const 0) (local.get $$v)))
+ (drop (v128.load8_lane 1 offset=0 1 (i32.const 0) (local.get $$v)))
+ (drop (v128.load8_lane 1 offset=0 align=1 1 (i32.const 0) (local.get $$v)))
+ (drop (v128.load8_lane 1 align=1 1 (i32.const 0) (local.get $$v)))
+
+ (v128.store8_lane 1 (i32.const 0) (local.get $$v))
+ (v128.store8_lane offset=0 1 (i32.const 0) (local.get $$v))
+ (v128.store8_lane offset=0 align=1 1 (i32.const 0) (local.get $$v))
+ (v128.store8_lane align=1 1 (i32.const 0) (local.get $$v))
+
+ (v128.store8_lane $$m 1 (i32.const 0) (local.get $$v))
+ (v128.store8_lane $$m offset=0 1 (i32.const 0) (local.get $$v))
+ (v128.store8_lane $$m offset=0 align=1 1 (i32.const 0) (local.get $$v))
+ (v128.store8_lane $$m align=1 1 (i32.const 0) (local.get $$v))
+
+ (v128.store8_lane 1 1 (i32.const 0) (local.get $$v))
+ (v128.store8_lane 1 offset=0 1 (i32.const 0) (local.get $$v))
+ (v128.store8_lane 1 offset=0 align=1 1 (i32.const 0) (local.get $$v))
+ (v128.store8_lane 1 align=1 1 (i32.const 0) (local.get $$v))
+ )
+)`);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/simd_store.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/simd_store.wast.js
new file mode 100644
index 0000000000..aaecc09ddd
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/simd_store.wast.js
@@ -0,0 +1,238 @@
+// |jit-test| skip-if: !wasmSimdEnabled()
+
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/simd/simd_store.wast
+
+// ./test/core/simd/simd_store.wast:3
+let $0 = instantiate(`(module
+ (memory 1)
+ (func (export "v128.store_i8x16") (result v128)
+ (v128.store (i32.const 0) (v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15))
+ (v128.load (i32.const 0))
+ )
+ (func (export "v128.store_i16x8") (result v128)
+ (v128.store (i32.const 0) (v128.const i16x8 0 1 2 3 4 5 6 7))
+ (v128.load (i32.const 0))
+ )
+ (func (export "v128.store_i16x8_2") (result v128)
+ (v128.store (i32.const 0) (v128.const i16x8 012_345 012_345 012_345 012_345 012_345 012_345 012_345 012_345))
+ (v128.load (i32.const 0))
+ )
+ (func (export "v128.store_i16x8_3") (result v128)
+ (v128.store (i32.const 0) (v128.const i16x8 0x0_1234 0x0_1234 0x0_1234 0x0_1234 0x0_1234 0x0_1234 0x0_1234 0x0_1234))
+ (v128.load (i32.const 0))
+ )
+ (func (export "v128.store_i32x4") (result v128)
+ (v128.store (i32.const 0) (v128.const i32x4 0 1 2 3))
+ (v128.load (i32.const 0))
+ )
+ (func (export "v128.store_i32x4_2") (result v128)
+ (v128.store (i32.const 0) (v128.const i32x4 0_123_456_789 0_123_456_789 0_123_456_789 0_123_456_789))
+ (v128.load (i32.const 0))
+ )
+ (func (export "v128.store_i32x4_3") (result v128)
+ (v128.store (i32.const 0) (v128.const i32x4 0x0_1234_5678 0x0_1234_5678 0x0_1234_5678 0x0_1234_5678))
+ (v128.load (i32.const 0))
+ )
+
+ (func (export "v128.store_f32x4") (result v128)
+ (v128.store (i32.const 0) (v128.const f32x4 0 1 2 3))
+ (v128.load (i32.const 0))
+ )
+)`);
+
+// ./test/core/simd/simd_store.wast:40
+assert_return(
+ () => invoke($0, `v128.store_i8x16`, []),
+ [
+ i8x16([0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf]),
+ ],
+);
+
+// ./test/core/simd/simd_store.wast:41
+assert_return(() => invoke($0, `v128.store_i16x8`, []), [i16x8([0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7])]);
+
+// ./test/core/simd/simd_store.wast:42
+assert_return(
+ () => invoke($0, `v128.store_i16x8_2`, []),
+ [i16x8([0x3039, 0x3039, 0x3039, 0x3039, 0x3039, 0x3039, 0x3039, 0x3039])],
+);
+
+// ./test/core/simd/simd_store.wast:43
+assert_return(
+ () => invoke($0, `v128.store_i16x8_3`, []),
+ [i16x8([0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234, 0x1234])],
+);
+
+// ./test/core/simd/simd_store.wast:44
+assert_return(() => invoke($0, `v128.store_i32x4`, []), [i32x4([0x0, 0x1, 0x2, 0x3])]);
+
+// ./test/core/simd/simd_store.wast:45
+assert_return(
+ () => invoke($0, `v128.store_i32x4_2`, []),
+ [i32x4([0x75bcd15, 0x75bcd15, 0x75bcd15, 0x75bcd15])],
+);
+
+// ./test/core/simd/simd_store.wast:46
+assert_return(
+ () => invoke($0, `v128.store_i32x4_3`, []),
+ [i32x4([0x12345678, 0x12345678, 0x12345678, 0x12345678])],
+);
+
+// ./test/core/simd/simd_store.wast:47
+assert_return(
+ () => invoke($0, `v128.store_f32x4`, []),
+ [
+ new F32x4Pattern(
+ value("f32", 0),
+ value("f32", 1),
+ value("f32", 2),
+ value("f32", 3),
+ ),
+ ],
+);
+
+// ./test/core/simd/simd_store.wast:52
+let $1 = instantiate(`(module
+ (memory 1)
+ (func (export "as-block-value")
+ (block (v128.store (i32.const 0) (v128.const i32x4 0 0 0 0)))
+ )
+ (func (export "as-loop-value")
+ (loop (v128.store (i32.const 0) (v128.const i32x4 0 0 0 0)))
+ )
+ (func (export "as-br-value")
+ (block (br 0 (v128.store (i32.const 0) (v128.const i32x4 0 0 0 0))))
+ )
+ (func (export "as-br_if-value")
+ (block
+ (br_if 0 (v128.store (i32.const 0) (v128.const i32x4 0 0 0 0)) (i32.const 1))
+ )
+ )
+ (func (export "as-br_if-value-cond")
+ (block
+ (br_if 0 (i32.const 6) (v128.store (i32.const 0) (v128.const i32x4 0 0 0 0)))
+ )
+ )
+ (func (export "as-br_table-value")
+ (block
+ (br_table 0 (v128.store (i32.const 0) (v128.const i32x4 0 0 0 0)) (i32.const 1))
+ )
+ )
+ (func (export "as-return-value")
+ (return (v128.store (i32.const 0) (v128.const i32x4 0 0 0 0)))
+ )
+ (func (export "as-if-then")
+ (if (i32.const 1) (then (v128.store (i32.const 0) (v128.const i32x4 0 0 0 0))))
+ )
+ (func (export "as-if-else")
+ (if (i32.const 0) (then) (else (v128.store (i32.const 0) (v128.const i32x4 0 0 0 0))))
+ )
+)`);
+
+// ./test/core/simd/simd_store.wast:89
+assert_return(() => invoke($1, `as-block-value`, []), []);
+
+// ./test/core/simd/simd_store.wast:90
+assert_return(() => invoke($1, `as-loop-value`, []), []);
+
+// ./test/core/simd/simd_store.wast:91
+assert_return(() => invoke($1, `as-br-value`, []), []);
+
+// ./test/core/simd/simd_store.wast:92
+assert_return(() => invoke($1, `as-br_if-value`, []), []);
+
+// ./test/core/simd/simd_store.wast:93
+assert_return(() => invoke($1, `as-br_if-value-cond`, []), []);
+
+// ./test/core/simd/simd_store.wast:94
+assert_return(() => invoke($1, `as-br_table-value`, []), []);
+
+// ./test/core/simd/simd_store.wast:95
+assert_return(() => invoke($1, `as-return-value`, []), []);
+
+// ./test/core/simd/simd_store.wast:96
+assert_return(() => invoke($1, `as-if-then`, []), []);
+
+// ./test/core/simd/simd_store.wast:97
+assert_return(() => invoke($1, `as-if-else`, []), []);
+
+// ./test/core/simd/simd_store.wast:102
+assert_malformed(
+ () => instantiate(`(memory 1) (func (v128.store8 (i32.const 0) (v128.const i32x4 0 0 0 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/simd/simd_store.wast:109
+assert_malformed(
+ () => instantiate(`(memory 1) (func (v128.store16 (i32.const 0) (v128.const i32x4 0 0 0 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/simd/simd_store.wast:116
+assert_malformed(
+ () => instantiate(`(memory 1) (func (v128.store32 (i32.const 0) (v128.const i32x4 0 0 0 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/simd/simd_store.wast:127
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (v128.store (f32.const 0) (v128.const i32x4 0 0 0 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/simd/simd_store.wast:131
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (local v128) (block (br_if 0 (v128.store)))))`),
+ `type mismatch`,
+);
+
+// ./test/core/simd/simd_store.wast:135
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (result v128) (v128.store (i32.const 0) (v128.const i32x4 0 0 0 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/simd/simd_store.wast:143
+assert_invalid(
+ () => instantiate(`(module (memory 0)
+ (func $$v128.store-1st-arg-empty
+ (v128.store (v128.const i32x4 0 0 0 0))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/simd/simd_store.wast:151
+assert_invalid(
+ () => instantiate(`(module (memory 0)
+ (func $$v128.store-2nd-arg-empty
+ (v128.store (i32.const 0))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/simd/simd_store.wast:159
+assert_invalid(
+ () => instantiate(`(module (memory 0)
+ (func $$v128.store-arg-empty
+ (v128.store)
+ )
+ )`),
+ `type mismatch`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/start0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/start0.wast.js
new file mode 100644
index 0000000000..90cd5d63ac
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/start0.wast.js
@@ -0,0 +1,73 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/start0.wast
+
+// ./test/core/multi-memory/start0.wast:1
+let $0 = instantiate(`(module
+ (memory 0)
+ (memory $$m (data "A"))
+ (memory $$n 1)
+
+ (func $$inc
+ (i32.store8 $$m
+ (i32.const 0)
+ (i32.add
+ (i32.load8_u $$m (i32.const 0))
+ (i32.const 1)
+ )
+ )
+ )
+ (func $$get (result i32)
+ (return (i32.load8_u $$m (i32.const 0)))
+ )
+ (func $$getn (result i32)
+ (return (i32.load8_u $$n (i32.const 0)))
+ )
+ (func $$main
+ (call $$inc)
+ (call $$inc)
+ (call $$inc)
+ )
+
+ (start $$main)
+ (export "inc" (func $$inc))
+ (export "get" (func $$get))
+ (export "getn" (func $$getn))
+)`);
+
+// ./test/core/multi-memory/start0.wast:32
+assert_return(() => invoke($0, `get`, []), [value("i32", 68)]);
+
+// ./test/core/multi-memory/start0.wast:33
+assert_return(() => invoke($0, `getn`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/start0.wast:35
+invoke($0, `inc`, []);
+
+// ./test/core/multi-memory/start0.wast:36
+assert_return(() => invoke($0, `get`, []), [value("i32", 69)]);
+
+// ./test/core/multi-memory/start0.wast:37
+assert_return(() => invoke($0, `getn`, []), [value("i32", 0)]);
+
+// ./test/core/multi-memory/start0.wast:39
+invoke($0, `inc`, []);
+
+// ./test/core/multi-memory/start0.wast:40
+assert_return(() => invoke($0, `get`, []), [value("i32", 70)]);
+
+// ./test/core/multi-memory/start0.wast:41
+assert_return(() => invoke($0, `getn`, []), [value("i32", 0)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/store.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/store.wast.js
new file mode 100644
index 0000000000..8c9a75f0c2
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/store.wast.js
@@ -0,0 +1,803 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/store.wast
+
+// ./test/core/store.wast:3
+let $0 = instantiate(`(module
+ (memory $$mem1 1)
+ (memory $$mem2 1)
+
+ (func (export "load1") (param i32) (result i64)
+ (i64.load $$mem1 (local.get 0))
+ )
+ (func (export "load2") (param i32) (result i64)
+ (i64.load $$mem2 (local.get 0))
+ )
+
+ (func (export "store1") (param i32 i64)
+ (i64.store $$mem1 (local.get 0) (local.get 1))
+ )
+ (func (export "store2") (param i32 i64)
+ (i64.store $$mem2 (local.get 0) (local.get 1))
+ )
+)`);
+
+// ./test/core/store.wast:22
+invoke($0, `store1`, [0, 1n]);
+
+// ./test/core/store.wast:23
+invoke($0, `store2`, [0, 2n]);
+
+// ./test/core/store.wast:24
+assert_return(() => invoke($0, `load1`, [0]), [value("i64", 1n)]);
+
+// ./test/core/store.wast:25
+assert_return(() => invoke($0, `load2`, [0]), [value("i64", 2n)]);
+
+// ./test/core/store.wast:28
+let $1 = instantiate(`(module $$M1
+ (memory (export "mem") 1)
+
+ (func (export "load") (param i32) (result i64)
+ (i64.load (local.get 0))
+ )
+ (func (export "store") (param i32 i64)
+ (i64.store (local.get 0) (local.get 1))
+ )
+)`);
+register($1, `M1`);
+
+// ./test/core/store.wast:38
+register($1, `M1`);
+
+// ./test/core/store.wast:40
+let $2 = instantiate(`(module $$M2
+ (memory (export "mem") 1)
+
+ (func (export "load") (param i32) (result i64)
+ (i64.load (local.get 0))
+ )
+ (func (export "store") (param i32 i64)
+ (i64.store (local.get 0) (local.get 1))
+ )
+)`);
+register($2, `M2`);
+
+// ./test/core/store.wast:50
+register($2, `M2`);
+
+// ./test/core/store.wast:52
+invoke(`M1`, `store`, [0, 1n]);
+
+// ./test/core/store.wast:53
+invoke(`M2`, `store`, [0, 2n]);
+
+// ./test/core/store.wast:54
+assert_return(() => invoke(`M1`, `load`, [0]), [value("i64", 1n)]);
+
+// ./test/core/store.wast:55
+assert_return(() => invoke(`M2`, `load`, [0]), [value("i64", 2n)]);
+
+// ./test/core/store.wast:57
+let $3 = instantiate(`(module
+ (memory $$mem1 (import "M1" "mem") 1)
+ (memory $$mem2 (import "M2" "mem") 1)
+
+ (func (export "load1") (param i32) (result i64)
+ (i64.load $$mem1 (local.get 0))
+ )
+ (func (export "load2") (param i32) (result i64)
+ (i64.load $$mem2 (local.get 0))
+ )
+
+ (func (export "store1") (param i32 i64)
+ (i64.store $$mem1 (local.get 0) (local.get 1))
+ )
+ (func (export "store2") (param i32 i64)
+ (i64.store $$mem2 (local.get 0) (local.get 1))
+ )
+)`);
+
+// ./test/core/store.wast:76
+invoke($3, `store1`, [0, 1n]);
+
+// ./test/core/store.wast:77
+invoke($3, `store2`, [0, 2n]);
+
+// ./test/core/store.wast:78
+assert_return(() => invoke($3, `load1`, [0]), [value("i64", 1n)]);
+
+// ./test/core/store.wast:79
+assert_return(() => invoke($3, `load2`, [0]), [value("i64", 2n)]);
+
+// ./test/core/store.wast:82
+let $4 = instantiate(`(module
+ (memory (export "mem") 2)
+)`);
+
+// ./test/core/store.wast:85
+register($4, `M`);
+
+// ./test/core/store.wast:87
+let $5 = instantiate(`(module
+ (memory $$mem1 (import "M" "mem") 2)
+ (memory $$mem2 3)
+
+ (data (memory $$mem1) (i32.const 20) "\\01\\02\\03\\04\\05")
+ (data (memory $$mem2) (i32.const 50) "\\0A\\0B\\0C\\0D\\0E")
+
+ (func (export "read1") (param i32) (result i32)
+ (i32.load8_u $$mem1 (local.get 0))
+ )
+ (func (export "read2") (param i32) (result i32)
+ (i32.load8_u $$mem2 (local.get 0))
+ )
+
+ (func (export "copy-1-to-2")
+ (local $$i i32)
+ (local.set $$i (i32.const 20))
+ (loop $$cont
+ (br_if 1 (i32.eq (local.get $$i) (i32.const 23)))
+ (i32.store8 $$mem2 (local.get $$i) (i32.load8_u $$mem1 (local.get $$i)))
+ (local.set $$i (i32.add (local.get $$i) (i32.const 1)))
+ (br $$cont)
+ )
+ )
+
+ (func (export "copy-2-to-1")
+ (local $$i i32)
+ (local.set $$i (i32.const 50))
+ (loop $$cont
+ (br_if 1 (i32.eq (local.get $$i) (i32.const 54)))
+ (i32.store8 $$mem1 (local.get $$i) (i32.load8_u $$mem2 (local.get $$i)))
+ (local.set $$i (i32.add (local.get $$i) (i32.const 1)))
+ (br $$cont)
+ )
+ )
+)`);
+
+// ./test/core/store.wast:124
+assert_return(() => invoke($5, `read2`, [20]), [value("i32", 0)]);
+
+// ./test/core/store.wast:125
+assert_return(() => invoke($5, `read2`, [21]), [value("i32", 0)]);
+
+// ./test/core/store.wast:126
+assert_return(() => invoke($5, `read2`, [22]), [value("i32", 0)]);
+
+// ./test/core/store.wast:127
+assert_return(() => invoke($5, `read2`, [23]), [value("i32", 0)]);
+
+// ./test/core/store.wast:128
+assert_return(() => invoke($5, `read2`, [24]), [value("i32", 0)]);
+
+// ./test/core/store.wast:129
+invoke($5, `copy-1-to-2`, []);
+
+// ./test/core/store.wast:130
+assert_return(() => invoke($5, `read2`, [20]), [value("i32", 1)]);
+
+// ./test/core/store.wast:131
+assert_return(() => invoke($5, `read2`, [21]), [value("i32", 2)]);
+
+// ./test/core/store.wast:132
+assert_return(() => invoke($5, `read2`, [22]), [value("i32", 3)]);
+
+// ./test/core/store.wast:133
+assert_return(() => invoke($5, `read2`, [23]), [value("i32", 0)]);
+
+// ./test/core/store.wast:134
+assert_return(() => invoke($5, `read2`, [24]), [value("i32", 0)]);
+
+// ./test/core/store.wast:136
+assert_return(() => invoke($5, `read1`, [50]), [value("i32", 0)]);
+
+// ./test/core/store.wast:137
+assert_return(() => invoke($5, `read1`, [51]), [value("i32", 0)]);
+
+// ./test/core/store.wast:138
+assert_return(() => invoke($5, `read1`, [52]), [value("i32", 0)]);
+
+// ./test/core/store.wast:139
+assert_return(() => invoke($5, `read1`, [53]), [value("i32", 0)]);
+
+// ./test/core/store.wast:140
+assert_return(() => invoke($5, `read1`, [54]), [value("i32", 0)]);
+
+// ./test/core/store.wast:141
+invoke($5, `copy-2-to-1`, []);
+
+// ./test/core/store.wast:142
+assert_return(() => invoke($5, `read1`, [50]), [value("i32", 10)]);
+
+// ./test/core/store.wast:143
+assert_return(() => invoke($5, `read1`, [51]), [value("i32", 11)]);
+
+// ./test/core/store.wast:144
+assert_return(() => invoke($5, `read1`, [52]), [value("i32", 12)]);
+
+// ./test/core/store.wast:145
+assert_return(() => invoke($5, `read1`, [53]), [value("i32", 13)]);
+
+// ./test/core/store.wast:146
+assert_return(() => invoke($5, `read1`, [54]), [value("i32", 0)]);
+
+// ./test/core/store.wast:151
+let $6 = instantiate(`(module
+ (memory 1)
+
+ (func (export "as-block-value")
+ (block (i32.store (i32.const 0) (i32.const 1)))
+ )
+ (func (export "as-loop-value")
+ (loop (i32.store (i32.const 0) (i32.const 1)))
+ )
+
+ (func (export "as-br-value")
+ (block (br 0 (i32.store (i32.const 0) (i32.const 1))))
+ )
+ (func (export "as-br_if-value")
+ (block
+ (br_if 0 (i32.store (i32.const 0) (i32.const 1)) (i32.const 1))
+ )
+ )
+ (func (export "as-br_if-value-cond")
+ (block
+ (br_if 0 (i32.const 6) (i32.store (i32.const 0) (i32.const 1)))
+ )
+ )
+ (func (export "as-br_table-value")
+ (block
+ (br_table 0 (i32.store (i32.const 0) (i32.const 1)) (i32.const 1))
+ )
+ )
+
+ (func (export "as-return-value")
+ (return (i32.store (i32.const 0) (i32.const 1)))
+ )
+
+ (func (export "as-if-then")
+ (if (i32.const 1) (then (i32.store (i32.const 0) (i32.const 1))))
+ )
+ (func (export "as-if-else")
+ (if (i32.const 0) (then) (else (i32.store (i32.const 0) (i32.const 1))))
+ )
+)`);
+
+// ./test/core/store.wast:192
+assert_return(() => invoke($6, `as-block-value`, []), []);
+
+// ./test/core/store.wast:193
+assert_return(() => invoke($6, `as-loop-value`, []), []);
+
+// ./test/core/store.wast:195
+assert_return(() => invoke($6, `as-br-value`, []), []);
+
+// ./test/core/store.wast:196
+assert_return(() => invoke($6, `as-br_if-value`, []), []);
+
+// ./test/core/store.wast:197
+assert_return(() => invoke($6, `as-br_if-value-cond`, []), []);
+
+// ./test/core/store.wast:198
+assert_return(() => invoke($6, `as-br_table-value`, []), []);
+
+// ./test/core/store.wast:200
+assert_return(() => invoke($6, `as-return-value`, []), []);
+
+// ./test/core/store.wast:202
+assert_return(() => invoke($6, `as-if-then`, []), []);
+
+// ./test/core/store.wast:203
+assert_return(() => invoke($6, `as-if-else`, []), []);
+
+// ./test/core/store.wast:205
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (i32.store32 (local.get 0) (i32.const 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/store.wast:212
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (i32.store64 (local.get 0) (i64.const 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/store.wast:220
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (i64.store64 (local.get 0) (i64.const 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/store.wast:228
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (f32.store32 (local.get 0) (f32.const 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/store.wast:235
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (f32.store64 (local.get 0) (f64.const 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/store.wast:243
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (f64.store32 (local.get 0) (f32.const 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/store.wast:250
+assert_malformed(
+ () => instantiate(`(memory 1) (func (param i32) (f64.store64 (local.get 0) (f64.const 0))) `),
+ `unknown operator`,
+);
+
+// ./test/core/store.wast:259
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (param i32) (result i32) (i32.store (i32.const 0) (i32.const 1))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:263
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (param i64) (result i64) (i64.store (i32.const 0) (i64.const 1))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:267
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (param f32) (result f32) (f32.store (i32.const 0) (f32.const 1))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:271
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (param f64) (result f64) (f64.store (i32.const 0) (f64.const 1))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:275
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (param i32) (result i32) (i32.store8 (i32.const 0) (i32.const 1))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:279
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (param i32) (result i32) (i32.store16 (i32.const 0) (i32.const 1))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:283
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (param i64) (result i64) (i64.store8 (i32.const 0) (i64.const 1))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:287
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (param i64) (result i64) (i64.store16 (i32.const 0) (i64.const 1))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:291
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (param i64) (result i64) (i64.store32 (i32.const 0) (i64.const 1))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:297
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-address-empty
+ (i32.store)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:306
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-value-empty
+ (i32.const 0) (i32.store)
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:315
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-address-empty-in-block
+ (i32.const 0) (i32.const 0)
+ (block (i32.store))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:325
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-value-empty-in-block
+ (i32.const 0)
+ (block (i32.const 0) (i32.store))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:335
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-address-empty-in-loop
+ (i32.const 0) (i32.const 0)
+ (loop (i32.store))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:345
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-value-empty-in-loop
+ (i32.const 0)
+ (loop (i32.const 0) (i32.store))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:355
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-address-empty-in-then
+ (i32.const 0) (i32.const 0)
+ (if (then (i32.store)))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:365
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-value-empty-in-then
+ (i32.const 0)
+ (if (then (i32.const 0) (i32.store)))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:375
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-address-empty-in-else
+ (i32.const 0) (i32.const 0)
+ (if (result i32) (then (i32.const 0)) (else (i32.store)))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:385
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-value-empty-in-else
+ (i32.const 0)
+ (if (result i32) (then (i32.const 0)) (else (i32.const 0) (i32.store)))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:395
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-address-empty-in-br
+ (i32.const 0) (i32.const 0)
+ (block (br 0 (i32.store)))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:405
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-value-empty-in-br
+ (i32.const 0)
+ (block (br 0 (i32.const 0) (i32.store)))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:415
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-address-empty-in-br_if
+ (i32.const 0) (i32.const 0)
+ (block (br_if 0 (i32.store) (i32.const 1)) )
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:425
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-value-empty-in-br_if
+ (i32.const 0)
+ (block (br_if 0 (i32.const 0) (i32.store) (i32.const 1)) )
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:435
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-address-empty-in-br_table
+ (i32.const 0) (i32.const 0)
+ (block (br_table 0 (i32.store)))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:445
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-value-empty-in-br_table
+ (i32.const 0)
+ (block (br_table 0 (i32.const 0) (i32.store)))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:455
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-address-empty-in-return
+ (return (i32.store))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:464
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-value-empty-in-return
+ (return (i32.const 0) (i32.store))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:473
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-address-empty-in-select
+ (select (i32.store) (i32.const 1) (i32.const 2))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:482
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-value-empty-in-select
+ (select (i32.const 0) (i32.store) (i32.const 1) (i32.const 2))
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:491
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-address-empty-in-call
+ (call 1 (i32.store))
+ )
+ (func (param i32) (result i32) (local.get 0))
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:501
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$type-value-empty-in-call
+ (call 1 (i32.const 0) (i32.store))
+ )
+ (func (param i32) (result i32) (local.get 0))
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:511
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$f (param i32) (result i32) (local.get 0))
+ (type $$sig (func (param i32) (result i32)))
+ (table funcref (elem $$f))
+ (func $$type-address-empty-in-call_indirect
+ (block (result i32)
+ (call_indirect (type $$sig)
+ (i32.store) (i32.const 0)
+ )
+ )
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:527
+assert_invalid(
+ () => instantiate(`(module
+ (memory 1)
+ (func $$f (param i32) (result i32) (local.get 0))
+ (type $$sig (func (param i32) (result i32)))
+ (table funcref (elem $$f))
+ (func $$type-value-empty-in-call_indirect
+ (block (result i32)
+ (call_indirect (type $$sig)
+ (i32.const 0) (i32.store) (i32.const 0)
+ )
+ )
+ )
+ )`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:547
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i32.store (f32.const 0) (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:548
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i32.store8 (f32.const 0) (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:549
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i32.store16 (f32.const 0) (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:550
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i64.store (f32.const 0) (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:551
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i64.store8 (f32.const 0) (i64.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:552
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i64.store16 (f32.const 0) (i64.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:553
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i64.store32 (f32.const 0) (i64.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:554
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (f32.store (f32.const 0) (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:555
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (f64.store (f32.const 0) (f64.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:557
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i32.store (i32.const 0) (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:558
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i32.store8 (i32.const 0) (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:559
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i32.store16 (i32.const 0) (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:560
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i64.store (i32.const 0) (f32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:561
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i64.store8 (i32.const 0) (f64.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:562
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i64.store16 (i32.const 0) (f64.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:563
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (i64.store32 (i32.const 0) (f64.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:564
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (f32.store (i32.const 0) (i32.const 0))))`),
+ `type mismatch`,
+);
+
+// ./test/core/store.wast:565
+assert_invalid(
+ () => instantiate(`(module (memory 1) (func (f64.store (i32.const 0) (i64.const 0))))`),
+ `type mismatch`,
+);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/store0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/store0.wast.js
new file mode 100644
index 0000000000..9850d62a5a
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/store0.wast.js
@@ -0,0 +1,48 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/store0.wast
+
+// ./test/core/multi-memory/store0.wast:3
+let $0 = instantiate(`(module
+ (memory $$mem1 1)
+ (memory $$mem2 1)
+
+ (func (export "load1") (param i32) (result i64)
+ (i64.load $$mem1 (local.get 0))
+ )
+ (func (export "load2") (param i32) (result i64)
+ (i64.load $$mem2 (local.get 0))
+ )
+
+ (func (export "store1") (param i32 i64)
+ (i64.store $$mem1 (local.get 0) (local.get 1))
+ )
+ (func (export "store2") (param i32 i64)
+ (i64.store $$mem2 (local.get 0) (local.get 1))
+ )
+)`);
+
+// ./test/core/multi-memory/store0.wast:22
+invoke($0, `store1`, [0, 1n]);
+
+// ./test/core/multi-memory/store0.wast:23
+invoke($0, `store2`, [0, 2n]);
+
+// ./test/core/multi-memory/store0.wast:24
+assert_return(() => invoke($0, `load1`, [0]), [value("i64", 1n)]);
+
+// ./test/core/multi-memory/store0.wast:25
+assert_return(() => invoke($0, `load2`, [0]), [value("i64", 2n)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/store1.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/store1.wast.js
new file mode 100644
index 0000000000..e79c256871
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/store1.wast.js
@@ -0,0 +1,92 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/store1.wast
+
+// ./test/core/multi-memory/store1.wast:1
+let $0 = instantiate(`(module $$M1
+ (memory (export "mem") 1)
+
+ (func (export "load") (param i32) (result i64)
+ (i64.load (local.get 0))
+ )
+ (func (export "store") (param i32 i64)
+ (i64.store (local.get 0) (local.get 1))
+ )
+)`);
+register($0, `M1`);
+
+// ./test/core/multi-memory/store1.wast:11
+register($0, `M1`);
+
+// ./test/core/multi-memory/store1.wast:13
+let $1 = instantiate(`(module $$M2
+ (memory (export "mem") 1)
+
+ (func (export "load") (param i32) (result i64)
+ (i64.load (local.get 0))
+ )
+ (func (export "store") (param i32 i64)
+ (i64.store (local.get 0) (local.get 1))
+ )
+)`);
+register($1, `M2`);
+
+// ./test/core/multi-memory/store1.wast:23
+register($1, `M2`);
+
+// ./test/core/multi-memory/store1.wast:25
+invoke(`M1`, `store`, [0, 1n]);
+
+// ./test/core/multi-memory/store1.wast:26
+invoke(`M2`, `store`, [0, 2n]);
+
+// ./test/core/multi-memory/store1.wast:27
+assert_return(() => invoke(`M1`, `load`, [0]), [value("i64", 1n)]);
+
+// ./test/core/multi-memory/store1.wast:28
+assert_return(() => invoke(`M2`, `load`, [0]), [value("i64", 2n)]);
+
+// ./test/core/multi-memory/store1.wast:30
+let $2 = instantiate(`(module
+ (memory $$mem1 (import "M1" "mem") 1)
+ (memory $$mem2 (import "M2" "mem") 1)
+
+ (func (export "load1") (param i32) (result i64)
+ (i64.load $$mem1 (local.get 0))
+ )
+ (func (export "load2") (param i32) (result i64)
+ (i64.load $$mem2 (local.get 0))
+ )
+
+ (func (export "store1") (param i32 i64)
+ (i64.store $$mem1 (local.get 0) (local.get 1))
+ )
+ (func (export "store2") (param i32 i64)
+ (i64.store $$mem2 (local.get 0) (local.get 1))
+ )
+)`);
+
+// ./test/core/multi-memory/store1.wast:49
+invoke($2, `store1`, [0, 1n]);
+
+// ./test/core/multi-memory/store1.wast:50
+invoke($2, `store2`, [0, 2n]);
+
+// ./test/core/multi-memory/store1.wast:51
+assert_return(() => invoke($2, `load1`, [0]), [value("i64", 1n)]);
+
+// ./test/core/multi-memory/store1.wast:52
+assert_return(() => invoke($2, `load2`, [0]), [value("i64", 2n)]);
diff --git a/js/src/jit-test/tests/wasm/spec/multi-memory/traps0.wast.js b/js/src/jit-test/tests/wasm/spec/multi-memory/traps0.wast.js
new file mode 100644
index 0000000000..ff6a6baa7a
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/spec/multi-memory/traps0.wast.js
@@ -0,0 +1,80 @@
+/* Copyright 2021 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ./test/core/multi-memory/traps0.wast
+
+// ./test/core/multi-memory/traps0.wast:1
+let $0 = instantiate(`(module
+ (memory $$mem0 1)
+ (memory $$mem1 1)
+ (memory $$mem2 1)
+
+ (func (export "no_dce.i32.load") (param $$i i32) (drop (i32.load $$mem1 (local.get $$i))))
+ (func (export "no_dce.i32.load16_s") (param $$i i32) (drop (i32.load16_s $$mem1 (local.get $$i))))
+ (func (export "no_dce.i32.load16_u") (param $$i i32) (drop (i32.load16_u $$mem1 (local.get $$i))))
+ (func (export "no_dce.i32.load8_s") (param $$i i32) (drop (i32.load8_s $$mem1 (local.get $$i))))
+ (func (export "no_dce.i32.load8_u") (param $$i i32) (drop (i32.load8_u $$mem1 (local.get $$i))))
+ (func (export "no_dce.i64.load") (param $$i i32) (drop (i64.load $$mem1 (local.get $$i))))
+ (func (export "no_dce.i64.load32_s") (param $$i i32) (drop (i64.load32_s $$mem1 (local.get $$i))))
+ (func (export "no_dce.i64.load32_u") (param $$i i32) (drop (i64.load32_u $$mem2 (local.get $$i))))
+ (func (export "no_dce.i64.load16_s") (param $$i i32) (drop (i64.load16_s $$mem2 (local.get $$i))))
+ (func (export "no_dce.i64.load16_u") (param $$i i32) (drop (i64.load16_u $$mem2 (local.get $$i))))
+ (func (export "no_dce.i64.load8_s") (param $$i i32) (drop (i64.load8_s $$mem2 (local.get $$i))))
+ (func (export "no_dce.i64.load8_u") (param $$i i32) (drop (i64.load8_u $$mem2 (local.get $$i))))
+ (func (export "no_dce.f32.load") (param $$i i32) (drop (f32.load $$mem2 (local.get $$i))))
+ (func (export "no_dce.f64.load") (param $$i i32) (drop (f64.load $$mem2 (local.get $$i))))
+)`);
+
+// ./test/core/multi-memory/traps0.wast:22
+assert_trap(() => invoke($0, `no_dce.i32.load`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/traps0.wast:23
+assert_trap(() => invoke($0, `no_dce.i32.load16_s`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/traps0.wast:24
+assert_trap(() => invoke($0, `no_dce.i32.load16_u`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/traps0.wast:25
+assert_trap(() => invoke($0, `no_dce.i32.load8_s`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/traps0.wast:26
+assert_trap(() => invoke($0, `no_dce.i32.load8_u`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/traps0.wast:27
+assert_trap(() => invoke($0, `no_dce.i64.load`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/traps0.wast:28
+assert_trap(() => invoke($0, `no_dce.i64.load32_s`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/traps0.wast:29
+assert_trap(() => invoke($0, `no_dce.i64.load32_u`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/traps0.wast:30
+assert_trap(() => invoke($0, `no_dce.i64.load16_s`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/traps0.wast:31
+assert_trap(() => invoke($0, `no_dce.i64.load16_u`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/traps0.wast:32
+assert_trap(() => invoke($0, `no_dce.i64.load8_s`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/traps0.wast:33
+assert_trap(() => invoke($0, `no_dce.i64.load8_u`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/traps0.wast:34
+assert_trap(() => invoke($0, `no_dce.f32.load`, [65536]), `out of bounds memory access`);
+
+// ./test/core/multi-memory/traps0.wast:35
+assert_trap(() => invoke($0, `no_dce.f64.load`, [65536]), `out of bounds memory access`);