Line data Source code
1 : // Copyright 2015 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "test/unittests/test-utils.h"
6 :
7 : #include "src/handles.h"
8 : #include "src/objects-inl.h"
9 : #include "src/wasm/module-decoder.h"
10 : #include "src/wasm/wasm-features.h"
11 : #include "src/wasm/wasm-limits.h"
12 : #include "src/wasm/wasm-opcodes.h"
13 : #include "test/common/wasm/flag-utils.h"
14 : #include "test/common/wasm/wasm-macro-gen.h"
15 : #include "testing/gmock-support.h"
16 :
17 : using testing::HasSubstr;
18 :
19 : namespace v8 {
20 : namespace internal {
21 : namespace wasm {
22 : namespace module_decoder_unittest {
23 :
24 : #define WASM_INIT_EXPR_I32V_1(val) WASM_I32V_1(val), kExprEnd
25 : #define WASM_INIT_EXPR_I32V_2(val) WASM_I32V_2(val), kExprEnd
26 : #define WASM_INIT_EXPR_I32V_3(val) WASM_I32V_3(val), kExprEnd
27 : #define WASM_INIT_EXPR_I32V_4(val) WASM_I32V_4(val), kExprEnd
28 : #define WASM_INIT_EXPR_I32V_5(val) WASM_I32V_5(val), kExprEnd
29 : #define WASM_INIT_EXPR_F32(val) WASM_F32(val), kExprEnd
30 : #define WASM_INIT_EXPR_I64(val) WASM_I64(val), kExprEnd
31 : #define WASM_INIT_EXPR_F64(val) WASM_F64(val), kExprEnd
32 : #define WASM_INIT_EXPR_ANYREF WASM_REF_NULL, kExprEnd
33 : #define WASM_INIT_EXPR_GLOBAL(index) WASM_GET_GLOBAL(index), kExprEnd
34 :
35 : #define EMPTY_BODY 0
36 : #define NOP_BODY 2, 0, kExprNop
37 :
38 : #define SIG_ENTRY_i_i SIG_ENTRY_x_x(kLocalI32, kLocalI32)
39 :
40 : #define UNKNOWN_SECTION(size) 0, U32V_1(size + 5), ADD_COUNT('l', 'u', 'l', 'z')
41 :
42 : template <typename... Args>
43 : std::integral_constant<size_t, sizeof...(Args)> CountArgsHelper(Args...);
44 : #define COUNT_ARGS(...) (decltype(CountArgsHelper(__VA_ARGS__))::value)
45 :
46 : template <size_t num>
47 : struct CheckLEB1 : std::integral_constant<size_t, num> {
48 : static_assert(num <= I32V_MAX(1), "LEB range check");
49 : };
50 : #define CHECK_LEB1(num) CheckLEB1<num>::value
51 :
52 : #define ADD_COUNT(...) CHECK_LEB1(COUNT_ARGS(__VA_ARGS__)), __VA_ARGS__
53 :
54 : #define SECTION(name, ...) k##name##SectionCode, ADD_COUNT(__VA_ARGS__)
55 :
56 : #define SIGNATURES_SECTION(count, ...) SECTION(Type, U32V_1(count), __VA_ARGS__)
57 : #define FUNCTION_SIGNATURES_SECTION(count, ...) \
58 : SECTION(Function, U32V_1(count), __VA_ARGS__)
59 :
60 : #define FOO_STRING ADD_COUNT('f', 'o', 'o')
61 : #define NO_LOCAL_NAMES 0
62 :
63 : #define EMPTY_SIGNATURES_SECTION SECTION(Type, ENTRY_COUNT(0))
64 : #define EMPTY_FUNCTION_SIGNATURES_SECTION SECTION(Function, ENTRY_COUNT(0))
65 : #define EMPTY_FUNCTION_BODIES_SECTION SECTION(Code, ENTRY_COUNT(0))
66 : #define SECTION_NAMES(...) \
67 : SECTION(Unknown, ADD_COUNT('n', 'a', 'm', 'e'), ##__VA_ARGS__)
68 : #define EMPTY_NAMES_SECTION SECTION_NAMES()
69 : #define SECTION_SRC_MAP(...) \
70 : SECTION(Unknown, \
71 : ADD_COUNT('s', 'o', 'u', 'r', 'c', 'e', 'M', 'a', 'p', 'p', 'i', \
72 : 'n', 'g', 'U', 'R', 'L'), \
73 : ADD_COUNT(__VA_ARGS__))
74 :
75 : #define FAIL_IF_NO_EXPERIMENTAL_EH(data) \
76 : do { \
77 : ModuleResult result = DecodeModule((data), (data) + sizeof((data))); \
78 : EXPECT_FALSE(result.ok()); \
79 : } while (false)
80 :
81 : #define X1(...) __VA_ARGS__
82 : #define X2(...) __VA_ARGS__, __VA_ARGS__
83 : #define X3(...) __VA_ARGS__, __VA_ARGS__, __VA_ARGS__
84 : #define X4(...) __VA_ARGS__, __VA_ARGS__, __VA_ARGS__, __VA_ARGS__
85 :
86 : #define ONE_EMPTY_FUNCTION(sig_index) \
87 : SECTION(Function, ENTRY_COUNT(1), X1(sig_index))
88 :
89 : #define TWO_EMPTY_FUNCTIONS(sig_index) \
90 : SECTION(Function, ENTRY_COUNT(2), X2(sig_index))
91 :
92 : #define THREE_EMPTY_FUNCTIONS(sig_index) \
93 : SECTION(Function, ENTRY_COUNT(3), X3(sig_index))
94 :
95 : #define FOUR_EMPTY_FUNCTIONS(sig_index) \
96 : SECTION(Function, ENTRY_COUNT(4), X4(sig_index))
97 :
98 : #define ONE_EMPTY_BODY SECTION(Code, ENTRY_COUNT(1), X1(EMPTY_BODY))
99 : #define TWO_EMPTY_BODIES SECTION(Code, ENTRY_COUNT(2), X2(EMPTY_BODY))
100 : #define THREE_EMPTY_BODIES SECTION(Code, ENTRY_COUNT(3), X3(EMPTY_BODY))
101 : #define FOUR_EMPTY_BODIES SECTION(Code, ENTRY_COUNT(4), X4(EMPTY_BODY))
102 :
103 : #define SIGNATURES_SECTION_VOID_VOID \
104 : SECTION(Type, ENTRY_COUNT(1), SIG_ENTRY_v_v)
105 :
106 : #define LINEAR_MEMORY_INDEX_0 0
107 :
108 : #define EXCEPTION_ENTRY(sig_index) U32V_1(kExceptionAttribute), sig_index
109 :
110 : #define EXPECT_VERIFIES(data) \
111 : do { \
112 : ModuleResult result = DecodeModule(data, data + sizeof(data)); \
113 : EXPECT_TRUE(result.ok()); \
114 : } while (false)
115 :
116 : #define EXPECT_FAILURE_LEN(data, length) \
117 : do { \
118 : ModuleResult result = DecodeModule(data, data + length); \
119 : EXPECT_FALSE(result.ok()); \
120 : } while (false)
121 :
122 : #define EXPECT_FAILURE(data) EXPECT_FAILURE_LEN(data, sizeof(data))
123 :
124 : #define EXPECT_OFF_END_FAILURE(data, min) \
125 : do { \
126 : STATIC_ASSERT(min < arraysize(data)); \
127 : for (size_t length = min; length < arraysize(data); length++) { \
128 : EXPECT_FAILURE_LEN(data, length); \
129 : } \
130 : } while (false)
131 :
132 : #define EXPECT_OK(result) \
133 : do { \
134 : EXPECT_TRUE(result.ok()); \
135 : if (!result.ok()) return; \
136 : } while (false)
137 :
138 : #define EXPECT_NOT_OK(result, msg) \
139 : do { \
140 : EXPECT_FALSE(result.ok()); \
141 : EXPECT_THAT(result.error().message(), HasSubstr(msg)); \
142 : } while (false)
143 :
144 : static size_t SizeOfVarInt(size_t value) {
145 : size_t size = 0;
146 13 : do {
147 13 : size++;
148 13 : value = value >> 7;
149 : } while (value > 0);
150 : return size;
151 : }
152 :
153 : struct ValueTypePair {
154 : uint8_t code;
155 : ValueType type;
156 : } kValueTypes[] = {
157 : {kLocalI32, kWasmI32}, // --
158 : {kLocalI64, kWasmI64}, // --
159 : {kLocalF32, kWasmF32}, // --
160 : {kLocalF64, kWasmF64}, // --
161 : {kLocalAnyFunc, kWasmAnyFunc}, // --
162 : {kLocalAnyRef, kWasmAnyRef} // --
163 : };
164 :
165 226 : class WasmModuleVerifyTest : public TestWithIsolateAndZone {
166 : public:
167 : WasmFeatures enabled_features_;
168 :
169 235 : ModuleResult DecodeModule(const byte* module_start, const byte* module_end) {
170 : // Add the wasm magic and version number automatically.
171 235 : size_t size = static_cast<size_t>(module_end - module_start);
172 235 : byte header[] = {WASM_MODULE_HEADER};
173 235 : size_t total = sizeof(header) + size;
174 235 : auto temp = new byte[total];
175 : memcpy(temp, header, sizeof(header));
176 235 : if (size > 0) {
177 234 : memcpy(temp + sizeof(header), module_start, size);
178 : }
179 : ModuleResult result = DecodeWasmModule(
180 : enabled_features_, temp, temp + total, false, kWasmOrigin,
181 705 : isolate()->counters(), isolate()->allocator());
182 235 : delete[] temp;
183 235 : return result;
184 : }
185 64 : ModuleResult DecodeModuleNoHeader(const byte* module_start,
186 : const byte* module_end) {
187 : return DecodeWasmModule(enabled_features_, module_start, module_end, false,
188 : kWasmOrigin, isolate()->counters(),
189 192 : isolate()->allocator());
190 : }
191 : };
192 :
193 : namespace {
194 : class EnableBoolScope {
195 : public:
196 : bool prev_;
197 : bool* ptr_;
198 : explicit EnableBoolScope(bool* ptr, bool val = true)
199 49 : : prev_(*ptr), ptr_(ptr) {
200 49 : *ptr = val;
201 : }
202 41 : ~EnableBoolScope() { *ptr_ = prev_; }
203 : };
204 :
205 : #define WASM_FEATURE_SCOPE(feat) \
206 : EnableBoolScope feat##_scope(&this->enabled_features_.feat)
207 :
208 : #define WASM_FEATURE_SCOPE_VAL(feat, val) \
209 : EnableBoolScope feat##_scope(&this->enabled_features_.feat, val)
210 : } // namespace
211 :
212 15189 : TEST_F(WasmModuleVerifyTest, WrongMagic) {
213 33 : for (uint32_t x = 1; x; x <<= 1) {
214 32 : const byte data[] = {U32_LE(kWasmMagic ^ x), U32_LE(kWasmVersion)};
215 64 : ModuleResult result = DecodeModuleNoHeader(data, data + sizeof(data));
216 64 : EXPECT_FALSE(result.ok());
217 32 : }
218 1 : }
219 :
220 15189 : TEST_F(WasmModuleVerifyTest, WrongVersion) {
221 33 : for (uint32_t x = 1; x; x <<= 1) {
222 32 : const byte data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion ^ x)};
223 64 : ModuleResult result = DecodeModuleNoHeader(data, data + sizeof(data));
224 64 : EXPECT_FALSE(result.ok());
225 32 : }
226 1 : }
227 :
228 15189 : TEST_F(WasmModuleVerifyTest, DecodeEmpty) {
229 2 : ModuleResult result = DecodeModule(nullptr, nullptr);
230 2 : EXPECT_TRUE(result.ok());
231 1 : }
232 :
233 15189 : TEST_F(WasmModuleVerifyTest, OneGlobal) {
234 : static const byte data[] = {
235 : SECTION(Global, // --
236 : ENTRY_COUNT(1), // --
237 : kLocalI32, // local type
238 : 0, // immutable
239 : WASM_INIT_EXPR_I32V_1(13)) // init
240 1 : };
241 :
242 : {
243 : // Should decode to exactly one global.
244 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
245 3 : EXPECT_OK(result);
246 3 : EXPECT_EQ(1u, result.value()->globals.size());
247 3 : EXPECT_EQ(0u, result.value()->functions.size());
248 3 : EXPECT_EQ(0u, result.value()->data_segments.size());
249 :
250 1 : const WasmGlobal* global = &result.value()->globals.back();
251 :
252 2 : EXPECT_EQ(kWasmI32, global->type);
253 2 : EXPECT_EQ(0u, global->offset);
254 2 : EXPECT_FALSE(global->mutability);
255 2 : EXPECT_EQ(WasmInitExpr::kI32Const, global->init.kind);
256 3 : EXPECT_EQ(13, global->init.val.i32_const);
257 : }
258 :
259 36 : EXPECT_OFF_END_FAILURE(data, 1);
260 : }
261 :
262 15189 : TEST_F(WasmModuleVerifyTest, AnyRefGlobal) {
263 1 : WASM_FEATURE_SCOPE(anyref);
264 : static const byte data[] = {
265 : SECTION(Global, // --
266 : ENTRY_COUNT(1), // --
267 : kLocalAnyRef, // local type
268 : 0, // immutable
269 : WASM_INIT_EXPR_ANYREF) // init
270 : };
271 :
272 : {
273 : // Should decode to exactly one global.
274 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
275 3 : EXPECT_OK(result);
276 3 : EXPECT_EQ(1u, result.value()->globals.size());
277 3 : EXPECT_EQ(0u, result.value()->functions.size());
278 3 : EXPECT_EQ(0u, result.value()->data_segments.size());
279 :
280 1 : const WasmGlobal* global = &result.value()->globals.back();
281 :
282 2 : EXPECT_EQ(kWasmAnyRef, global->type);
283 2 : EXPECT_FALSE(global->mutability);
284 3 : EXPECT_EQ(WasmInitExpr::kAnyRefConst, global->init.kind);
285 : }
286 : }
287 :
288 15189 : TEST_F(WasmModuleVerifyTest, AnyRefGlobalWithGlobalInit) {
289 1 : WASM_FEATURE_SCOPE(anyref);
290 : static const byte data[] = {
291 : SECTION(Import, // --
292 : ENTRY_COUNT(1), // number of imports
293 : ADD_COUNT('m'), // module name
294 : ADD_COUNT('f'), // global name
295 : kExternalGlobal, // import kind
296 : kLocalAnyRef, // type
297 : 0), // mutability
298 : SECTION(Global, // --
299 : ENTRY_COUNT(1),
300 : kLocalAnyRef, // local type
301 : 0, // immutable
302 : WASM_INIT_EXPR_GLOBAL(0)),
303 : };
304 :
305 : {
306 : // Should decode to exactly one global.
307 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
308 3 : EXPECT_OK(result);
309 3 : EXPECT_EQ(2u, result.value()->globals.size());
310 3 : EXPECT_EQ(0u, result.value()->functions.size());
311 3 : EXPECT_EQ(0u, result.value()->data_segments.size());
312 :
313 1 : const WasmGlobal* global = &result.value()->globals.back();
314 :
315 2 : EXPECT_EQ(kWasmAnyRef, global->type);
316 2 : EXPECT_FALSE(global->mutability);
317 3 : EXPECT_EQ(WasmInitExpr::kGlobalIndex, global->init.kind);
318 : }
319 : }
320 :
321 15189 : TEST_F(WasmModuleVerifyTest, Global_invalid_type) {
322 : static const byte data[] = {
323 : SECTION(Global, // --
324 : ENTRY_COUNT(1), // --
325 : 64, // invalid memory type
326 : 1, // mutable
327 : WASM_INIT_EXPR_I32V_1(33)), // init
328 1 : };
329 :
330 5 : EXPECT_FAILURE(data);
331 1 : }
332 :
333 15189 : TEST_F(WasmModuleVerifyTest, Global_invalid_type2) {
334 : static const byte data[] = {
335 : SECTION(Global, // --
336 : ENTRY_COUNT(1), // --
337 : kLocalVoid, // invalid memory type
338 : 1, // mutable
339 : WASM_INIT_EXPR_I32V_1(33)), // init
340 1 : };
341 :
342 5 : EXPECT_FAILURE(data);
343 1 : }
344 :
345 15189 : TEST_F(WasmModuleVerifyTest, ZeroGlobals) {
346 : static const byte data[] = {SECTION(Global, ENTRY_COUNT(0))};
347 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
348 2 : EXPECT_OK(result);
349 : }
350 :
351 15189 : TEST_F(WasmModuleVerifyTest, ExportMutableGlobal) {
352 : {
353 : static const byte data[] = {
354 : SECTION(Global, // --
355 : ENTRY_COUNT(1), // --
356 : kLocalI32, // local type
357 : 0, // immutable
358 : WASM_INIT_EXPR_I32V_1(13)), // init
359 : SECTION(Export, // --
360 : ENTRY_COUNT(1), // export count
361 : ADD_COUNT('n', 'a', 'm', 'e'), // name
362 : kExternalGlobal, // global
363 : 0), // global index
364 1 : };
365 4 : EXPECT_VERIFIES(data);
366 : }
367 : {
368 : static const byte data[] = {
369 : SECTION(Global, // --
370 : ENTRY_COUNT(1), // --
371 : kLocalI32, // local type
372 : 1, // mutable
373 : WASM_INIT_EXPR_I32V_1(13)), // init
374 : SECTION(Export, // --
375 : ENTRY_COUNT(1), // export count
376 : ADD_COUNT('n', 'a', 'm', 'e'), // name
377 : kExternalGlobal, // global
378 : 0), // global index
379 1 : };
380 4 : EXPECT_VERIFIES(data);
381 : }
382 1 : }
383 :
384 7 : static void AppendUint32v(std::vector<byte>& buffer, uint32_t val) {
385 : while (true) {
386 13 : uint32_t next = val >> 7;
387 13 : uint32_t out = val & 0x7F;
388 13 : if (next) {
389 12 : buffer.push_back(static_cast<byte>(0x80 | out));
390 : val = next;
391 : } else {
392 14 : buffer.push_back(static_cast<byte>(out));
393 : break;
394 : }
395 6 : }
396 7 : }
397 :
398 15189 : TEST_F(WasmModuleVerifyTest, NGlobals) {
399 : static const byte data[] = {
400 : kLocalF32, // memory type
401 : 0, // immutable
402 : WASM_INIT_EXPR_F32(7.7), // init
403 1 : };
404 :
405 15 : for (uint32_t i = 0; i < kV8MaxWasmGlobals; i = i * 13 + 1) {
406 : std::vector<byte> buffer;
407 14 : size_t size = SizeOfVarInt(i) + i * sizeof(data);
408 7 : const byte globals[] = {kGlobalSectionCode, U32V_5(size)};
409 49 : for (size_t g = 0; g != sizeof(globals); ++g) {
410 42 : buffer.push_back(globals[g]);
411 : }
412 7 : AppendUint32v(buffer, i); // Number of globals.
413 435760 : for (uint32_t j = 0; j < i; j++) {
414 : buffer.insert(buffer.end(), data, data + sizeof(data));
415 : }
416 :
417 28 : ModuleResult result = DecodeModule(&buffer[0], &buffer[0] + buffer.size());
418 15 : EXPECT_OK(result);
419 : }
420 : }
421 :
422 15189 : TEST_F(WasmModuleVerifyTest, GlobalWithInvalidMemoryType) {
423 : static const byte data[] = {SECTION(Global, // --
424 : ENTRY_COUNT(1), // --
425 : 33, // memory type
426 : 0, // exported
427 1 : WASM_INIT_EXPR_I32V_1(1))};
428 :
429 5 : EXPECT_FAILURE(data);
430 1 : }
431 :
432 15189 : TEST_F(WasmModuleVerifyTest, TwoGlobals) {
433 : static const byte data[] = {SECTION(Global, // --
434 : ENTRY_COUNT(2), // --
435 : kLocalF32, // type
436 : 0, // immutable
437 : WASM_INIT_EXPR_F32(22.0), // --
438 : kLocalF64, // type
439 : 1, // mutable
440 1 : WASM_INIT_EXPR_F64(23.0))}; // --
441 :
442 : {
443 : // Should decode to exactly two globals.
444 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
445 3 : EXPECT_OK(result);
446 3 : EXPECT_EQ(2u, result.value()->globals.size());
447 3 : EXPECT_EQ(0u, result.value()->functions.size());
448 3 : EXPECT_EQ(0u, result.value()->data_segments.size());
449 :
450 1 : const WasmGlobal* g0 = &result.value()->globals[0];
451 :
452 2 : EXPECT_EQ(kWasmF32, g0->type);
453 2 : EXPECT_EQ(0u, g0->offset);
454 2 : EXPECT_FALSE(g0->mutability);
455 2 : EXPECT_EQ(WasmInitExpr::kF32Const, g0->init.kind);
456 :
457 1 : const WasmGlobal* g1 = &result.value()->globals[1];
458 :
459 2 : EXPECT_EQ(kWasmF64, g1->type);
460 2 : EXPECT_EQ(8u, g1->offset);
461 1 : EXPECT_TRUE(g1->mutability);
462 3 : EXPECT_EQ(WasmInitExpr::kF64Const, g1->init.kind);
463 : }
464 :
465 111 : EXPECT_OFF_END_FAILURE(data, 1);
466 : }
467 :
468 15189 : TEST_F(WasmModuleVerifyTest, ZeroExceptions) {
469 : static const byte data[] = {SECTION(Exception, ENTRY_COUNT(0))};
470 5 : FAIL_IF_NO_EXPERIMENTAL_EH(data);
471 :
472 1 : WASM_FEATURE_SCOPE(eh);
473 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
474 3 : EXPECT_OK(result);
475 3 : EXPECT_EQ(0u, result.value()->exceptions.size());
476 : }
477 :
478 15189 : TEST_F(WasmModuleVerifyTest, OneI32Exception) {
479 : static const byte data[] = {
480 : SECTION(Type, ENTRY_COUNT(1), SIG_ENTRY_v_x(kLocalI32)), // sig#0 (i32)
481 : SECTION(Exception, ENTRY_COUNT(1),
482 : EXCEPTION_ENTRY(SIG_INDEX(0)))}; // except[0] (sig#0)
483 5 : FAIL_IF_NO_EXPERIMENTAL_EH(data);
484 :
485 1 : WASM_FEATURE_SCOPE(eh);
486 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
487 3 : EXPECT_OK(result);
488 3 : EXPECT_EQ(1u, result.value()->exceptions.size());
489 :
490 1 : const WasmException& e0 = result.value()->exceptions.front();
491 3 : EXPECT_EQ(1u, e0.sig->parameter_count());
492 3 : EXPECT_EQ(kWasmI32, e0.sig->GetParam(0));
493 : }
494 :
495 15189 : TEST_F(WasmModuleVerifyTest, TwoExceptions) {
496 : static const byte data[] = {
497 : SECTION(Type, ENTRY_COUNT(2),
498 : SIG_ENTRY_v_x(kLocalI32), // sig#0 (i32)
499 : SIG_ENTRY_v_xx(kLocalF32, kLocalI64)), // sig#1 (f32, i64)
500 : SECTION(Exception, ENTRY_COUNT(2),
501 : EXCEPTION_ENTRY(SIG_INDEX(1)), // except[0] (sig#1)
502 : EXCEPTION_ENTRY(SIG_INDEX(0)))}; // except[1] (sig#0)
503 5 : FAIL_IF_NO_EXPERIMENTAL_EH(data);
504 :
505 1 : WASM_FEATURE_SCOPE(eh);
506 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
507 3 : EXPECT_OK(result);
508 3 : EXPECT_EQ(2u, result.value()->exceptions.size());
509 1 : const WasmException& e0 = result.value()->exceptions.front();
510 4 : EXPECT_EQ(2u, e0.sig->parameter_count());
511 3 : EXPECT_EQ(kWasmF32, e0.sig->GetParam(0));
512 3 : EXPECT_EQ(kWasmI64, e0.sig->GetParam(1));
513 1 : const WasmException& e1 = result.value()->exceptions.back();
514 3 : EXPECT_EQ(kWasmI32, e1.sig->GetParam(0));
515 : }
516 :
517 15189 : TEST_F(WasmModuleVerifyTest, Exception_invalid_sig_index) {
518 : static const byte data[] = {
519 : SIGNATURES_SECTION_VOID_VOID,
520 : SECTION(Exception, ENTRY_COUNT(1),
521 : EXCEPTION_ENTRY(
522 : SIG_INDEX(23)))}; // except[0] (sig#23 [out-of-bounds])
523 5 : FAIL_IF_NO_EXPERIMENTAL_EH(data);
524 :
525 : // Should fail decoding exception section.
526 1 : WASM_FEATURE_SCOPE(eh);
527 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
528 6 : EXPECT_NOT_OK(result, "signature index 23 out of bounds");
529 1 : }
530 :
531 15189 : TEST_F(WasmModuleVerifyTest, Exception_invalid_sig_return) {
532 : static const byte data[] = {
533 : SECTION(Type, ENTRY_COUNT(1), SIG_ENTRY_i_i),
534 : SECTION(Exception, ENTRY_COUNT(1),
535 : EXCEPTION_ENTRY(
536 : SIG_INDEX(0)))}; // except[0] (sig#0 [invalid-return-type])
537 5 : FAIL_IF_NO_EXPERIMENTAL_EH(data);
538 :
539 : // Should fail decoding exception section.
540 1 : WASM_FEATURE_SCOPE(eh);
541 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
542 6 : EXPECT_NOT_OK(result, "exception signature 0 has non-void return");
543 1 : }
544 :
545 15189 : TEST_F(WasmModuleVerifyTest, Exception_invalid_attribute) {
546 : static const byte data[] = {
547 : SECTION(Type, ENTRY_COUNT(1), SIG_ENTRY_i_i),
548 : SECTION(Exception, ENTRY_COUNT(1), 23,
549 : SIG_INDEX(0))}; // except[0] (sig#0) [invalid-attribute]
550 5 : FAIL_IF_NO_EXPERIMENTAL_EH(data);
551 :
552 : // Should fail decoding exception section.
553 1 : WASM_FEATURE_SCOPE(eh);
554 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
555 6 : EXPECT_NOT_OK(result, "exception attribute 23 not supported");
556 1 : }
557 :
558 15189 : TEST_F(WasmModuleVerifyTest, ExceptionSectionCorrectPlacement) {
559 : static const byte data[] = {SECTION(Import, ENTRY_COUNT(0)),
560 : SECTION(Exception, ENTRY_COUNT(0)),
561 : SECTION(Export, ENTRY_COUNT(0))};
562 5 : FAIL_IF_NO_EXPERIMENTAL_EH(data);
563 :
564 1 : WASM_FEATURE_SCOPE(eh);
565 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
566 3 : EXPECT_OK(result);
567 : }
568 :
569 15189 : TEST_F(WasmModuleVerifyTest, ExceptionSectionAfterExport) {
570 : static const byte data[] = {SECTION(Export, ENTRY_COUNT(0)),
571 : SECTION(Exception, ENTRY_COUNT(0))};
572 5 : FAIL_IF_NO_EXPERIMENTAL_EH(data);
573 :
574 1 : WASM_FEATURE_SCOPE(eh);
575 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
576 6 : EXPECT_NOT_OK(result,
577 : "The Exception section must appear before the Export section");
578 1 : }
579 :
580 15189 : TEST_F(WasmModuleVerifyTest, ExceptionSectionBeforeGlobal) {
581 : static const byte data[] = {SECTION(Exception, ENTRY_COUNT(0)),
582 : SECTION(Global, ENTRY_COUNT(0))};
583 5 : FAIL_IF_NO_EXPERIMENTAL_EH(data);
584 :
585 1 : WASM_FEATURE_SCOPE(eh);
586 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
587 6 : EXPECT_NOT_OK(result, "unexpected section <Global>");
588 1 : }
589 :
590 15189 : TEST_F(WasmModuleVerifyTest, ExceptionSectionAfterMemoryBeforeGlobal) {
591 : STATIC_ASSERT(kMemorySectionCode + 1 == kGlobalSectionCode);
592 : static const byte data[] = {SECTION(Memory, ENTRY_COUNT(0)),
593 : SECTION(Exception, ENTRY_COUNT(0)),
594 : SECTION(Global, ENTRY_COUNT(0))};
595 5 : FAIL_IF_NO_EXPERIMENTAL_EH(data);
596 :
597 1 : WASM_FEATURE_SCOPE(eh);
598 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
599 6 : EXPECT_NOT_OK(result, "unexpected section <Global>");
600 1 : }
601 :
602 15189 : TEST_F(WasmModuleVerifyTest, ExceptionImport) {
603 : static const byte data[] = {
604 : SIGNATURES_SECTION_VOID_VOID,
605 : SECTION(Import, // section header
606 : ENTRY_COUNT(1), // number of imports
607 : ADD_COUNT('m'), // module name
608 : ADD_COUNT('e', 'x'), // exception name
609 : kExternalException, // import kind
610 : EXCEPTION_ENTRY(SIG_INDEX(0)))}; // except[0] (sig#0)
611 5 : FAIL_IF_NO_EXPERIMENTAL_EH(data);
612 :
613 1 : WASM_FEATURE_SCOPE(eh);
614 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
615 3 : EXPECT_OK(result);
616 3 : EXPECT_EQ(1u, result.value()->exceptions.size());
617 3 : EXPECT_EQ(1u, result.value()->import_table.size());
618 : }
619 :
620 15189 : TEST_F(WasmModuleVerifyTest, ExceptionExport) {
621 : static const byte data[] = {
622 : SIGNATURES_SECTION_VOID_VOID,
623 : SECTION(Exception, ENTRY_COUNT(1),
624 : EXCEPTION_ENTRY(SIG_INDEX(0))), // except[0] (sig#0)
625 : SECTION(Export, ENTRY_COUNT(1), // --
626 : NO_NAME, // --
627 : kExternalException, // --
628 : EXCEPTION_INDEX(0))};
629 5 : FAIL_IF_NO_EXPERIMENTAL_EH(data);
630 :
631 1 : WASM_FEATURE_SCOPE(eh);
632 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
633 3 : EXPECT_OK(result);
634 3 : EXPECT_EQ(1u, result.value()->exceptions.size());
635 3 : EXPECT_EQ(1u, result.value()->export_table.size());
636 : }
637 :
638 15189 : TEST_F(WasmModuleVerifyTest, OneSignature) {
639 : {
640 : static const byte data[] = {SIGNATURES_SECTION_VOID_VOID};
641 4 : EXPECT_VERIFIES(data);
642 : }
643 :
644 : {
645 : static const byte data[] = {SECTION(Type, ENTRY_COUNT(1), SIG_ENTRY_i_i)};
646 4 : EXPECT_VERIFIES(data);
647 : }
648 1 : }
649 :
650 15189 : TEST_F(WasmModuleVerifyTest, MultipleSignatures) {
651 : static const byte data[] = {
652 : SECTION(
653 : Type, // --
654 : ENTRY_COUNT(3), // --
655 : SIG_ENTRY_v_v, // void -> void
656 : SIG_ENTRY_x_x(kLocalI32, kLocalF32), // f32 -> i32
657 : SIG_ENTRY_x_xx(kLocalI32, kLocalF64, kLocalF64)), // f64,f64 -> i32
658 : };
659 :
660 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
661 2 : EXPECT_OK(result);
662 3 : EXPECT_EQ(3u, result.value()->signatures.size());
663 2 : if (result.value()->signatures.size() == 3) {
664 2 : EXPECT_EQ(0u, result.value()->signatures[0]->return_count());
665 2 : EXPECT_EQ(1u, result.value()->signatures[1]->return_count());
666 2 : EXPECT_EQ(1u, result.value()->signatures[2]->return_count());
667 :
668 2 : EXPECT_EQ(0u, result.value()->signatures[0]->parameter_count());
669 2 : EXPECT_EQ(1u, result.value()->signatures[1]->parameter_count());
670 2 : EXPECT_EQ(2u, result.value()->signatures[2]->parameter_count());
671 : }
672 :
673 80 : EXPECT_OFF_END_FAILURE(data, 1);
674 : }
675 :
676 15189 : TEST_F(WasmModuleVerifyTest, DataSegmentWithImmutableImportedGlobal) {
677 : // Import 2 globals so that we can initialize data with a global index != 0.
678 : const byte data[] = {
679 : SECTION(Import, // section header
680 : ENTRY_COUNT(2), // number of imports
681 : ADD_COUNT('m'), // module name
682 : ADD_COUNT('f'), // global name
683 : kExternalGlobal, // import kind
684 : kLocalI32, // type
685 : 0, // mutability
686 : ADD_COUNT('n'), // module name
687 : ADD_COUNT('g'), // global name
688 : kExternalGlobal, // import kind
689 : kLocalI32, // type
690 : 0), // mutability
691 : SECTION(Memory, ENTRY_COUNT(1), kHasMaximumFlag, 28, 28),
692 : SECTION(Data, ENTRY_COUNT(1), LINEAR_MEMORY_INDEX_0,
693 : WASM_INIT_EXPR_GLOBAL(1), // dest addr
694 : U32V_1(3), // source size
695 : 'a', 'b', 'c') // data bytes
696 1 : };
697 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
698 2 : EXPECT_OK(result);
699 2 : WasmInitExpr expr = result.value()->data_segments.back().dest_addr;
700 2 : EXPECT_EQ(WasmInitExpr::kGlobalIndex, expr.kind);
701 3 : EXPECT_EQ(1u, expr.val.global_index);
702 : }
703 :
704 15189 : TEST_F(WasmModuleVerifyTest, DataSegmentWithMutableImportedGlobal) {
705 : // Only an immutable imported global can be used as an init_expr.
706 : const byte data[] = {
707 : SECTION(Import, // section header
708 : ENTRY_COUNT(1), // number of imports
709 : ADD_COUNT('m'), // module name
710 : ADD_COUNT('f'), // global name
711 : kExternalGlobal, // import kind
712 : kLocalI32, // type
713 : 1), // mutability
714 : SECTION(Memory, ENTRY_COUNT(1), kHasMaximumFlag, 28, 28),
715 : SECTION(Data, ENTRY_COUNT(1), LINEAR_MEMORY_INDEX_0,
716 : WASM_INIT_EXPR_GLOBAL(0), // dest addr
717 : U32V_1(3), // source size
718 : 'a', 'b', 'c') // data bytes
719 1 : };
720 5 : EXPECT_FAILURE(data);
721 1 : }
722 15189 : TEST_F(WasmModuleVerifyTest, DataSegmentWithImmutableGlobal) {
723 : // Only an immutable imported global can be used as an init_expr.
724 : const byte data[] = {
725 : SECTION(Memory, ENTRY_COUNT(1), kHasMaximumFlag, 28, 28),
726 : SECTION(Global, ENTRY_COUNT(1),
727 : kLocalI32, // local type
728 : 0, // immutable
729 : WASM_INIT_EXPR_I32V_3(0x9BBAA)), // init
730 : SECTION(Data, ENTRY_COUNT(1), LINEAR_MEMORY_INDEX_0,
731 : WASM_INIT_EXPR_GLOBAL(0), // dest addr
732 : U32V_1(3), // source size
733 : 'a', 'b', 'c') // data bytes
734 1 : };
735 5 : EXPECT_FAILURE(data);
736 1 : }
737 :
738 15189 : TEST_F(WasmModuleVerifyTest, OneDataSegment) {
739 1 : const byte kDataSegmentSourceOffset = 24;
740 : const byte data[] = {
741 : SECTION(Memory, ENTRY_COUNT(1), kHasMaximumFlag, 28, 28),
742 : SECTION(Data, ENTRY_COUNT(1), LINEAR_MEMORY_INDEX_0,
743 : WASM_INIT_EXPR_I32V_3(0x9BBAA), // dest addr
744 : U32V_1(3), // source size
745 : 'a', 'b', 'c') // data bytes
746 1 : };
747 :
748 : {
749 4 : EXPECT_VERIFIES(data);
750 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
751 3 : EXPECT_OK(result);
752 3 : EXPECT_EQ(0u, result.value()->globals.size());
753 3 : EXPECT_EQ(0u, result.value()->functions.size());
754 3 : EXPECT_EQ(1u, result.value()->data_segments.size());
755 :
756 1 : const WasmDataSegment* segment = &result.value()->data_segments.back();
757 :
758 2 : EXPECT_EQ(WasmInitExpr::kI32Const, segment->dest_addr.kind);
759 2 : EXPECT_EQ(0x9BBAA, segment->dest_addr.val.i32_const);
760 3 : EXPECT_EQ(kDataSegmentSourceOffset, segment->source.offset());
761 3 : EXPECT_EQ(3u, segment->source.length());
762 : }
763 :
764 26 : EXPECT_OFF_END_FAILURE(data, 14);
765 : }
766 :
767 15189 : TEST_F(WasmModuleVerifyTest, TwoDataSegments) {
768 1 : const byte kDataSegment0SourceOffset = 24;
769 1 : const byte kDataSegment1SourceOffset = kDataSegment0SourceOffset + 11;
770 :
771 : const byte data[] = {
772 : SECTION(Memory, ENTRY_COUNT(1), kHasMaximumFlag, 28, 28),
773 : SECTION(Data,
774 : ENTRY_COUNT(2), // segment count
775 : LINEAR_MEMORY_INDEX_0,
776 : WASM_INIT_EXPR_I32V_3(0x7FFEE), // #0: dest addr
777 : U32V_1(4), // source size
778 : 1, 2, 3, 4, // data bytes
779 : LINEAR_MEMORY_INDEX_0,
780 : WASM_INIT_EXPR_I32V_3(0x6DDCC), // #1: dest addr
781 : U32V_1(10), // source size
782 : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) // data bytes
783 1 : };
784 :
785 : {
786 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
787 3 : EXPECT_OK(result);
788 3 : EXPECT_EQ(0u, result.value()->globals.size());
789 3 : EXPECT_EQ(0u, result.value()->functions.size());
790 3 : EXPECT_EQ(2u, result.value()->data_segments.size());
791 :
792 1 : const WasmDataSegment* s0 = &result.value()->data_segments[0];
793 : const WasmDataSegment* s1 = &result.value()->data_segments[1];
794 :
795 2 : EXPECT_EQ(WasmInitExpr::kI32Const, s0->dest_addr.kind);
796 2 : EXPECT_EQ(0x7FFEE, s0->dest_addr.val.i32_const);
797 3 : EXPECT_EQ(kDataSegment0SourceOffset, s0->source.offset());
798 2 : EXPECT_EQ(4u, s0->source.length());
799 :
800 2 : EXPECT_EQ(WasmInitExpr::kI32Const, s1->dest_addr.kind);
801 2 : EXPECT_EQ(0x6DDCC, s1->dest_addr.val.i32_const);
802 3 : EXPECT_EQ(kDataSegment1SourceOffset, s1->source.offset());
803 3 : EXPECT_EQ(10u, s1->source.length());
804 : }
805 :
806 116 : EXPECT_OFF_END_FAILURE(data, 14);
807 : }
808 :
809 15189 : TEST_F(WasmModuleVerifyTest, DataWithoutMemory) {
810 : const byte data[] = {
811 : SECTION(Data, ENTRY_COUNT(1), LINEAR_MEMORY_INDEX_0,
812 : WASM_INIT_EXPR_I32V_3(0x9BBAA), // dest addr
813 : U32V_1(3), // source size
814 : 'a', 'b', 'c') // data bytes
815 1 : };
816 5 : EXPECT_FAILURE(data);
817 1 : }
818 :
819 15189 : TEST_F(WasmModuleVerifyTest, MaxMaximumMemorySize) {
820 : {
821 : const byte data[] = {
822 1 : SECTION(Memory, ENTRY_COUNT(1), kHasMaximumFlag, 0, U32V_3(65536))};
823 4 : EXPECT_VERIFIES(data);
824 : }
825 : {
826 : const byte data[] = {
827 1 : SECTION(Memory, ENTRY_COUNT(1), kHasMaximumFlag, 0, U32V_3(65537))};
828 5 : EXPECT_FAILURE(data);
829 : }
830 1 : }
831 :
832 15189 : TEST_F(WasmModuleVerifyTest, DataSegment_wrong_init_type) {
833 : const byte data[] = {
834 : SECTION(Memory, ENTRY_COUNT(1), kHasMaximumFlag, 28, 28),
835 : SECTION(Data, ENTRY_COUNT(1), LINEAR_MEMORY_INDEX_0,
836 : WASM_INIT_EXPR_F64(9.9), // dest addr
837 : U32V_1(3), // source size
838 : 'a', 'b', 'c') // data bytes
839 1 : };
840 :
841 5 : EXPECT_FAILURE(data);
842 1 : }
843 :
844 15189 : TEST_F(WasmModuleVerifyTest, DataSegmentEndOverflow) {
845 : const byte data[] = {
846 : SECTION(Memory, // memory section
847 : ENTRY_COUNT(1), kHasMaximumFlag, 28, 28),
848 : SECTION(Data, // data section
849 : ENTRY_COUNT(1), // one entry
850 : LINEAR_MEMORY_INDEX_0, // mem index
851 : WASM_INIT_EXPR_I32V_1(0), // offset
852 : U32V_5(0xFFFFFFFF)) // size
853 1 : };
854 :
855 5 : EXPECT_FAILURE(data);
856 1 : }
857 :
858 15189 : TEST_F(WasmModuleVerifyTest, OneIndirectFunction) {
859 : static const byte data[] = {
860 : // sig#0 ---------------------------------------------------------------
861 : SIGNATURES_SECTION_VOID_VOID,
862 : // funcs ---------------------------------------------------------------
863 : ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
864 : // table declaration ---------------------------------------------------
865 : SECTION(Table, ENTRY_COUNT(1), kLocalAnyFunc, 0, 1),
866 : // code ----------------------------------------------------------------
867 : ONE_EMPTY_BODY};
868 :
869 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
870 2 : EXPECT_OK(result);
871 1 : if (result.ok()) {
872 3 : EXPECT_EQ(1u, result.value()->signatures.size());
873 3 : EXPECT_EQ(1u, result.value()->functions.size());
874 3 : EXPECT_EQ(1u, result.value()->tables.size());
875 2 : EXPECT_EQ(1u, result.value()->tables[0].initial_size);
876 1 : }
877 : }
878 :
879 15189 : TEST_F(WasmModuleVerifyTest, ElementSectionWithInternalTable) {
880 : static const byte data[] = {
881 : // table ---------------------------------------------------------------
882 : SECTION(Table, ENTRY_COUNT(1), kLocalAnyFunc, 0, 1),
883 : // elements ------------------------------------------------------------
884 : SECTION(Element, ENTRY_COUNT(0))};
885 :
886 4 : EXPECT_VERIFIES(data);
887 1 : }
888 :
889 15189 : TEST_F(WasmModuleVerifyTest, ElementSectionWithImportedTable) {
890 : static const byte data[] = {
891 : // imports -------------------------------------------------------------
892 : SECTION(Import, ENTRY_COUNT(1),
893 : ADD_COUNT('m'), // module name
894 : ADD_COUNT('t'), // table name
895 : kExternalTable, // import kind
896 : kLocalAnyFunc, // elem_type
897 : 0, // no maximum field
898 : 1), // initial size
899 : // elements ------------------------------------------------------------
900 : SECTION(Element, ENTRY_COUNT(0))};
901 :
902 4 : EXPECT_VERIFIES(data);
903 1 : }
904 :
905 15189 : TEST_F(WasmModuleVerifyTest, ElementSectionWithoutTable) {
906 : // Test that an element section without a table causes a validation error.
907 : static const byte data[] = {
908 : // elements ------------------------------------------------------------
909 : SECTION(Element,
910 : ENTRY_COUNT(1), // entry count
911 : 0, // table index
912 : 0, // offset
913 : 0) // number of elements
914 : };
915 :
916 5 : EXPECT_FAILURE(data);
917 1 : }
918 :
919 15189 : TEST_F(WasmModuleVerifyTest, Regression_735887) {
920 : // Test with an invalid function index in the element section.
921 : static const byte data[] = {
922 : // sig#0 ---------------------------------------------------------------
923 : SIGNATURES_SECTION_VOID_VOID,
924 : // funcs ---------------------------------------------------------------
925 : ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
926 : // table declaration ---------------------------------------------------
927 : SECTION(Table, ENTRY_COUNT(1), kLocalAnyFunc, 0, 1),
928 : // elements ------------------------------------------------------------
929 : SECTION(Element,
930 : ENTRY_COUNT(1), // entry count
931 : TABLE_INDEX0, WASM_INIT_EXPR_I32V_1(0),
932 : 1, // elements count
933 : 0x9A) // invalid I32V as function index
934 1 : };
935 :
936 5 : EXPECT_FAILURE(data);
937 1 : }
938 :
939 15189 : TEST_F(WasmModuleVerifyTest, OneIndirectFunction_one_entry) {
940 : static const byte data[] = {
941 : // sig#0 ---------------------------------------------------------------
942 : SIGNATURES_SECTION_VOID_VOID,
943 : // funcs ---------------------------------------------------------------
944 : ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
945 : // table declaration ---------------------------------------------------
946 : SECTION(Table, ENTRY_COUNT(1), kLocalAnyFunc, 0, 1),
947 : // elements ------------------------------------------------------------
948 : SECTION(Element,
949 : ENTRY_COUNT(1), // entry count
950 : TABLE_INDEX0, WASM_INIT_EXPR_I32V_1(0),
951 : 1, // elements count
952 : FUNC_INDEX(0)),
953 : // code ----------------------------------------------------------------
954 1 : ONE_EMPTY_BODY};
955 :
956 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
957 2 : EXPECT_OK(result);
958 3 : EXPECT_EQ(1u, result.value()->signatures.size());
959 3 : EXPECT_EQ(1u, result.value()->functions.size());
960 3 : EXPECT_EQ(1u, result.value()->tables.size());
961 3 : EXPECT_EQ(1u, result.value()->tables[0].initial_size);
962 : }
963 :
964 15189 : TEST_F(WasmModuleVerifyTest, MultipleIndirectFunctions) {
965 : static const byte data[] = {
966 : // sig#0 -------------------------------------------------------
967 : SECTION(Type,
968 : ENTRY_COUNT(2), // --
969 : SIG_ENTRY_v_v, // void -> void
970 : SIG_ENTRY_v_x(kLocalI32)), // void -> i32
971 : // funcs ------------------------------------------------------
972 : FOUR_EMPTY_FUNCTIONS(SIG_INDEX(0)),
973 : // table declaration -------------------------------------------
974 : SECTION(Table, ENTRY_COUNT(1), kLocalAnyFunc, 0, 8),
975 : // table elements ----------------------------------------------
976 : SECTION(Element,
977 : ENTRY_COUNT(1), // entry count
978 : TABLE_INDEX0, WASM_INIT_EXPR_I32V_1(0),
979 : ADD_COUNT(FUNC_INDEX(0), FUNC_INDEX(1), FUNC_INDEX(2),
980 : FUNC_INDEX(3), FUNC_INDEX(0), FUNC_INDEX(1),
981 : FUNC_INDEX(2), FUNC_INDEX(3))),
982 1 : FOUR_EMPTY_BODIES};
983 :
984 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
985 2 : EXPECT_OK(result);
986 3 : EXPECT_EQ(2u, result.value()->signatures.size());
987 3 : EXPECT_EQ(4u, result.value()->functions.size());
988 3 : EXPECT_EQ(1u, result.value()->tables.size());
989 3 : EXPECT_EQ(8u, result.value()->tables[0].initial_size);
990 : }
991 :
992 15189 : TEST_F(WasmModuleVerifyTest, ElementSectionMultipleTables) {
993 : // Test that if we have multiple tables, in the element section we can target
994 : // and initialize all tables.
995 1 : WASM_FEATURE_SCOPE(anyref);
996 1 : WASM_FEATURE_SCOPE(bulk_memory);
997 : static const byte data[] = {
998 : // sig#0 ---------------------------------------------------------------
999 : SIGNATURES_SECTION_VOID_VOID,
1000 : // funcs ---------------------------------------------------------------
1001 : ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
1002 : // table declaration ---------------------------------------------------
1003 : SECTION(Table, ENTRY_COUNT(2), // section header
1004 : kLocalAnyFunc, 0, 5, // table 0
1005 : kLocalAnyFunc, 0, 9), // table 1
1006 : // elements ------------------------------------------------------------
1007 : SECTION(Element,
1008 : ENTRY_COUNT(2), // entry count
1009 : TABLE_INDEX0, // element for table 0
1010 : WASM_INIT_EXPR_I32V_1(0), // index
1011 : 1, // elements count
1012 : FUNC_INDEX(0), // function
1013 : TABLE_INDEX(1), // element for table 1
1014 : WASM_INIT_EXPR_I32V_1(7), // index
1015 : 2, // elements count
1016 : FUNC_INDEX(0), // entry 0
1017 : FUNC_INDEX(0)), // entry 1
1018 : // code ----------------------------------------------------------------
1019 1 : ONE_EMPTY_BODY};
1020 :
1021 4 : EXPECT_VERIFIES(data);
1022 1 : }
1023 :
1024 15189 : TEST_F(WasmModuleVerifyTest, ElementSectionMixedTables) {
1025 : // Test that if we have multiple tables, both imported and module-defined, in
1026 : // the element section we can target and initialize all tables.
1027 1 : WASM_FEATURE_SCOPE(anyref);
1028 1 : WASM_FEATURE_SCOPE(bulk_memory);
1029 : static const byte data[] = {
1030 : // sig#0 ---------------------------------------------------------------
1031 : SIGNATURES_SECTION_VOID_VOID,
1032 : // imports -------------------------------------------------------------
1033 : SECTION(Import, ENTRY_COUNT(2),
1034 : ADD_COUNT('m'), // module name
1035 : ADD_COUNT('t'), // table name
1036 : kExternalTable, // import kind
1037 : kLocalAnyFunc, // elem_type
1038 : 0, // no maximum field
1039 : 5, // initial size
1040 : ADD_COUNT('m'), // module name
1041 : ADD_COUNT('s'), // table name
1042 : kExternalTable, // import kind
1043 : kLocalAnyFunc, // elem_type
1044 : 0, // no maximum field
1045 : 10), // initial size
1046 : // funcs ---------------------------------------------------------------
1047 : ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
1048 : // table declaration ---------------------------------------------------
1049 : SECTION(Table, ENTRY_COUNT(2), // section header
1050 : kLocalAnyFunc, 0, 15, // table 0
1051 : kLocalAnyFunc, 0, 19), // table 1
1052 : // elements ------------------------------------------------------------
1053 : SECTION(Element,
1054 : 4, // entry count
1055 : TABLE_INDEX0, // element for table 0
1056 : WASM_INIT_EXPR_I32V_1(0), // index
1057 : 1, // elements count
1058 : FUNC_INDEX(0), // function
1059 : TABLE_INDEX(1), // element for table 1
1060 : WASM_INIT_EXPR_I32V_1(7), // index
1061 : 2, // elements count
1062 : FUNC_INDEX(0), // entry 0
1063 : FUNC_INDEX(0), // entry 1
1064 : TABLE_INDEX(2), // element for table 2
1065 : WASM_INIT_EXPR_I32V_1(12), // index
1066 : 1, // elements count
1067 : FUNC_INDEX(0), // function
1068 : TABLE_INDEX(3), // element for table 1
1069 : WASM_INIT_EXPR_I32V_1(17), // index
1070 : 2, // elements count
1071 : FUNC_INDEX(0), // entry 0
1072 : FUNC_INDEX(0)), // entry 1
1073 : // code ----------------------------------------------------------------
1074 1 : ONE_EMPTY_BODY};
1075 :
1076 4 : EXPECT_VERIFIES(data);
1077 1 : }
1078 :
1079 15189 : TEST_F(WasmModuleVerifyTest, ElementSectionMultipleTablesArbitraryOrder) {
1080 : // Test that the order in which tables are targeted in the element secion
1081 : // can be arbitrary.
1082 1 : WASM_FEATURE_SCOPE(anyref);
1083 1 : WASM_FEATURE_SCOPE(bulk_memory);
1084 : static const byte data[] = {
1085 : // sig#0 ---------------------------------------------------------------
1086 : SIGNATURES_SECTION_VOID_VOID,
1087 : // funcs ---------------------------------------------------------------
1088 : ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
1089 : // table declaration ---------------------------------------------------
1090 : SECTION(Table, ENTRY_COUNT(2), // section header
1091 : kLocalAnyFunc, 0, 5, // table 0
1092 : kLocalAnyFunc, 0, 9), // table 1
1093 : // elements ------------------------------------------------------------
1094 : SECTION(Element,
1095 : ENTRY_COUNT(3), // entry count
1096 : TABLE_INDEX0, // element for table 1
1097 : WASM_INIT_EXPR_I32V_1(0), // index
1098 : 1, // elements count
1099 : FUNC_INDEX(0), // function
1100 : TABLE_INDEX(1), // element for table 0
1101 : WASM_INIT_EXPR_I32V_1(7), // index
1102 : 2, // elements count
1103 : FUNC_INDEX(0), // entry 0
1104 : FUNC_INDEX(0), // entry 1
1105 : TABLE_INDEX0, // element for table 1
1106 : WASM_INIT_EXPR_I32V_1(3), // index
1107 : 1, // elements count
1108 : FUNC_INDEX(0)), // function
1109 : // code ----------------------------------------------------------------
1110 1 : ONE_EMPTY_BODY};
1111 :
1112 4 : EXPECT_VERIFIES(data);
1113 1 : }
1114 :
1115 15189 : TEST_F(WasmModuleVerifyTest, ElementSectionMixedTablesArbitraryOrder) {
1116 : // Test that the order in which tables are targeted in the element secion can
1117 : // be arbitrary. In this test, tables can be both imported and module-defined.
1118 1 : WASM_FEATURE_SCOPE(anyref);
1119 1 : WASM_FEATURE_SCOPE(bulk_memory);
1120 : static const byte data[] = {
1121 : // sig#0 ---------------------------------------------------------------
1122 : SIGNATURES_SECTION_VOID_VOID,
1123 : // imports -------------------------------------------------------------
1124 : SECTION(Import, ENTRY_COUNT(2),
1125 : ADD_COUNT('m'), // module name
1126 : ADD_COUNT('t'), // table name
1127 : kExternalTable, // import kind
1128 : kLocalAnyFunc, // elem_type
1129 : 0, // no maximum field
1130 : 5, // initial size
1131 : ADD_COUNT('m'), // module name
1132 : ADD_COUNT('s'), // table name
1133 : kExternalTable, // import kind
1134 : kLocalAnyFunc, // elem_type
1135 : 0, // no maximum field
1136 : 10), // initial size
1137 : // funcs ---------------------------------------------------------------
1138 : ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
1139 : // table declaration ---------------------------------------------------
1140 : SECTION(Table, ENTRY_COUNT(2), // section header
1141 : kLocalAnyFunc, 0, 15, // table 0
1142 : kLocalAnyFunc, 0, 19), // table 1
1143 : // elements ------------------------------------------------------------
1144 : SECTION(Element,
1145 : 4, // entry count
1146 : TABLE_INDEX(2), // element for table 0
1147 : WASM_INIT_EXPR_I32V_1(10), // index
1148 : 1, // elements count
1149 : FUNC_INDEX(0), // function
1150 : TABLE_INDEX(3), // element for table 1
1151 : WASM_INIT_EXPR_I32V_1(17), // index
1152 : 2, // elements count
1153 : FUNC_INDEX(0), // entry 0
1154 : FUNC_INDEX(0), // entry 1
1155 : TABLE_INDEX0, // element for table 2
1156 : WASM_INIT_EXPR_I32V_1(2), // index
1157 : 1, // elements count
1158 : FUNC_INDEX(0), // function
1159 : TABLE_INDEX(1), // element for table 1
1160 : WASM_INIT_EXPR_I32V_1(7), // index
1161 : 2, // elements count
1162 : FUNC_INDEX(0), // entry 0
1163 : FUNC_INDEX(0)), // entry 1
1164 : // code ----------------------------------------------------------------
1165 1 : ONE_EMPTY_BODY};
1166 :
1167 4 : EXPECT_VERIFIES(data);
1168 1 : }
1169 :
1170 15189 : TEST_F(WasmModuleVerifyTest, ElementSectionDontInitAnyRefTable) {
1171 : // Test that tables of type 'AnyRef' cannot be initialized by the element
1172 : // section.
1173 1 : WASM_FEATURE_SCOPE(anyref);
1174 1 : WASM_FEATURE_SCOPE(bulk_memory);
1175 : static const byte data[] = {
1176 : // sig#0 ---------------------------------------------------------------
1177 : SIGNATURES_SECTION_VOID_VOID,
1178 : // funcs ---------------------------------------------------------------
1179 : ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
1180 : // table declaration ---------------------------------------------------
1181 : SECTION(Table, ENTRY_COUNT(2), // section header
1182 : kLocalAnyRef, 0, 5, // table 0
1183 : kLocalAnyFunc, 0, 9), // table 1
1184 : // elements ------------------------------------------------------------
1185 : SECTION(Element,
1186 : ENTRY_COUNT(2), // entry count
1187 : TABLE_INDEX0, // element for table 0
1188 : WASM_INIT_EXPR_I32V_1(0), // index
1189 : 1, // elements count
1190 : FUNC_INDEX(0), // function
1191 : TABLE_INDEX(1), // element for table 1
1192 : WASM_INIT_EXPR_I32V_1(7), // index
1193 : 2, // elements count
1194 : FUNC_INDEX(0), // entry 0
1195 : FUNC_INDEX(0)), // entry 1
1196 1 : };
1197 :
1198 5 : EXPECT_FAILURE(data);
1199 1 : }
1200 :
1201 15189 : TEST_F(WasmModuleVerifyTest, ElementSectionDontInitAnyRefImportedTable) {
1202 : // Test that imported tables of type AnyRef cannot be initialized in the
1203 : // elements section.
1204 1 : WASM_FEATURE_SCOPE(anyref);
1205 1 : WASM_FEATURE_SCOPE(bulk_memory);
1206 : static const byte data[] = {
1207 : // sig#0 ---------------------------------------------------------------
1208 : SIGNATURES_SECTION_VOID_VOID,
1209 : // imports -------------------------------------------------------------
1210 : SECTION(Import, ENTRY_COUNT(2),
1211 : ADD_COUNT('m'), // module name
1212 : ADD_COUNT('t'), // table name
1213 : kExternalTable, // import kind
1214 : kLocalAnyFunc, // elem_type
1215 : 0, // no maximum field
1216 : 5, // initial size
1217 : ADD_COUNT('m'), // module name
1218 : ADD_COUNT('s'), // table name
1219 : kExternalTable, // import kind
1220 : kLocalAnyRef, // elem_type
1221 : 0, // no maximum field
1222 : 10), // initial size
1223 : // funcs ---------------------------------------------------------------
1224 : ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
1225 : // table declaration ---------------------------------------------------
1226 : SECTION(Table, ENTRY_COUNT(2), // section header
1227 : kLocalAnyFunc, 0, 15, // table 0
1228 : kLocalAnyFunc, 0, 19), // table 1
1229 : // elements ------------------------------------------------------------
1230 : SECTION(Element,
1231 : ENTRY_COUNT(4), // entry count
1232 : TABLE_INDEX0, // element for table 0
1233 : WASM_INIT_EXPR_I32V_1(10), // index
1234 : 1, // elements count
1235 : FUNC_INDEX(0), // function
1236 : TABLE_INDEX(1), // element for table 1
1237 : WASM_INIT_EXPR_I32V_1(17), // index
1238 : 2, // elements count
1239 : FUNC_INDEX(0), // entry 0
1240 : FUNC_INDEX(0)), // entry 1
1241 1 : };
1242 :
1243 5 : EXPECT_FAILURE(data);
1244 1 : }
1245 :
1246 15189 : TEST_F(WasmModuleVerifyTest, IndirectFunctionNoFunctions) {
1247 : static const byte data[] = {
1248 : // sig#0 -------------------------------------------------------
1249 : SIGNATURES_SECTION_VOID_VOID,
1250 : // indirect table ----------------------------------------------
1251 : SECTION(Table, ENTRY_COUNT(1), 1, 0, 0)};
1252 :
1253 5 : EXPECT_FAILURE(data);
1254 1 : }
1255 :
1256 15189 : TEST_F(WasmModuleVerifyTest, IndirectFunctionInvalidIndex) {
1257 : static const byte data[] = {
1258 : // sig#0 -------------------------------------------------------
1259 : SIGNATURES_SECTION_VOID_VOID,
1260 : // functions ---------------------------------------------------
1261 : ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
1262 : // indirect table ----------------------------------------------
1263 : SECTION(Table, ENTRY_COUNT(1), 1, 1, 0)};
1264 :
1265 5 : EXPECT_FAILURE(data);
1266 1 : }
1267 :
1268 15189 : TEST_F(WasmModuleVerifyTest, MultipleTablesWithoutFlag) {
1269 : static const byte data[] = {
1270 : SECTION(Table, // table section
1271 : ENTRY_COUNT(2), // 2 tables
1272 : kLocalAnyFunc, // table 1: type
1273 : 0, // table 1: no maximum
1274 : 10, // table 1: minimum size
1275 : kLocalAnyFunc, // table 2: type
1276 : 0, // table 2: no maximum
1277 : 10), // table 2: minimum size
1278 : };
1279 5 : EXPECT_FAILURE(data);
1280 1 : }
1281 :
1282 15189 : TEST_F(WasmModuleVerifyTest, MultipleTablesWithFlag) {
1283 1 : WASM_FEATURE_SCOPE(anyref);
1284 : static const byte data[] = {
1285 : SECTION(Table, // table section
1286 : ENTRY_COUNT(2), // 2 tables
1287 : kLocalAnyFunc, // table 1: type
1288 : 0, // table 1: no maximum
1289 : 10, // table 1: minimum size
1290 : kLocalAnyRef, // table 2: type
1291 : 0, // table 2: no maximum
1292 : 11), // table 2: minimum size
1293 : };
1294 :
1295 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
1296 3 : EXPECT_OK(result);
1297 :
1298 3 : EXPECT_EQ(2u, result.value()->tables.size());
1299 :
1300 2 : EXPECT_EQ(10u, result.value()->tables[0].initial_size);
1301 2 : EXPECT_EQ(kWasmAnyFunc, result.value()->tables[0].type);
1302 :
1303 2 : EXPECT_EQ(11u, result.value()->tables[1].initial_size);
1304 2 : EXPECT_EQ(kWasmAnyRef, result.value()->tables[1].type);
1305 : }
1306 :
1307 28 : class WasmSignatureDecodeTest : public TestWithZone {
1308 : public:
1309 : WasmFeatures enabled_features_;
1310 :
1311 : FunctionSig* DecodeSig(const byte* start, const byte* end) {
1312 262 : return DecodeWasmSignatureForTesting(enabled_features_, zone(), start, end);
1313 : }
1314 : };
1315 :
1316 15189 : TEST_F(WasmSignatureDecodeTest, Ok_v_v) {
1317 : static const byte data[] = {SIG_ENTRY_v_v};
1318 1 : v8::internal::AccountingAllocator allocator;
1319 2 : Zone zone(&allocator, ZONE_NAME);
1320 2 : FunctionSig* sig = DecodeSig(data, data + sizeof(data));
1321 :
1322 2 : EXPECT_TRUE(sig != nullptr);
1323 2 : EXPECT_EQ(0u, sig->parameter_count());
1324 3 : EXPECT_EQ(0u, sig->return_count());
1325 1 : }
1326 :
1327 15189 : TEST_F(WasmSignatureDecodeTest, Ok_t_v) {
1328 1 : WASM_FEATURE_SCOPE(anyref);
1329 7 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
1330 6 : ValueTypePair ret_type = kValueTypes[i];
1331 6 : const byte data[] = {SIG_ENTRY_x(ret_type.code)};
1332 18 : FunctionSig* sig = DecodeSig(data, data + sizeof(data));
1333 :
1334 12 : EXPECT_TRUE(sig != nullptr);
1335 12 : EXPECT_EQ(0u, sig->parameter_count());
1336 12 : EXPECT_EQ(1u, sig->return_count());
1337 12 : EXPECT_EQ(ret_type.type, sig->GetReturn());
1338 : }
1339 1 : }
1340 :
1341 15189 : TEST_F(WasmSignatureDecodeTest, Ok_v_t) {
1342 1 : WASM_FEATURE_SCOPE(anyref);
1343 7 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
1344 6 : ValueTypePair param_type = kValueTypes[i];
1345 6 : const byte data[] = {SIG_ENTRY_v_x(param_type.code)};
1346 18 : FunctionSig* sig = DecodeSig(data, data + sizeof(data));
1347 :
1348 12 : EXPECT_TRUE(sig != nullptr);
1349 12 : EXPECT_EQ(1u, sig->parameter_count());
1350 12 : EXPECT_EQ(0u, sig->return_count());
1351 12 : EXPECT_EQ(param_type.type, sig->GetParam(0));
1352 : }
1353 1 : }
1354 :
1355 15189 : TEST_F(WasmSignatureDecodeTest, Ok_t_t) {
1356 1 : WASM_FEATURE_SCOPE(anyref);
1357 7 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
1358 6 : ValueTypePair ret_type = kValueTypes[i];
1359 42 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
1360 36 : ValueTypePair param_type = kValueTypes[j];
1361 36 : const byte data[] = {SIG_ENTRY_x_x(ret_type.code, param_type.code)};
1362 144 : FunctionSig* sig = DecodeSig(data, data + sizeof(data));
1363 :
1364 72 : EXPECT_TRUE(sig != nullptr);
1365 72 : EXPECT_EQ(1u, sig->parameter_count());
1366 72 : EXPECT_EQ(1u, sig->return_count());
1367 72 : EXPECT_EQ(param_type.type, sig->GetParam(0));
1368 72 : EXPECT_EQ(ret_type.type, sig->GetReturn());
1369 : }
1370 : }
1371 1 : }
1372 :
1373 15189 : TEST_F(WasmSignatureDecodeTest, Ok_i_tt) {
1374 1 : WASM_FEATURE_SCOPE(anyref);
1375 1 : WASM_FEATURE_SCOPE(mv);
1376 7 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
1377 6 : ValueTypePair p0_type = kValueTypes[i];
1378 42 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
1379 36 : ValueTypePair p1_type = kValueTypes[j];
1380 : const byte data[] = {
1381 36 : SIG_ENTRY_x_xx(kLocalI32, p0_type.code, p1_type.code)};
1382 144 : FunctionSig* sig = DecodeSig(data, data + sizeof(data));
1383 :
1384 72 : EXPECT_TRUE(sig != nullptr);
1385 72 : EXPECT_EQ(2u, sig->parameter_count());
1386 72 : EXPECT_EQ(1u, sig->return_count());
1387 72 : EXPECT_EQ(p0_type.type, sig->GetParam(0));
1388 72 : EXPECT_EQ(p1_type.type, sig->GetParam(1));
1389 : }
1390 : }
1391 1 : }
1392 :
1393 15189 : TEST_F(WasmSignatureDecodeTest, Ok_tt_tt) {
1394 1 : WASM_FEATURE_SCOPE(anyref);
1395 1 : WASM_FEATURE_SCOPE(mv);
1396 7 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
1397 6 : ValueTypePair p0_type = kValueTypes[i];
1398 42 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
1399 36 : ValueTypePair p1_type = kValueTypes[j];
1400 : const byte data[] = {SIG_ENTRY_xx_xx(p0_type.code, p1_type.code,
1401 36 : p0_type.code, p1_type.code)};
1402 216 : FunctionSig* sig = DecodeSig(data, data + sizeof(data));
1403 :
1404 72 : EXPECT_TRUE(sig != nullptr);
1405 72 : EXPECT_EQ(2u, sig->parameter_count());
1406 72 : EXPECT_EQ(2u, sig->return_count());
1407 72 : EXPECT_EQ(p0_type.type, sig->GetParam(0));
1408 72 : EXPECT_EQ(p1_type.type, sig->GetParam(1));
1409 72 : EXPECT_EQ(p0_type.type, sig->GetReturn(0));
1410 72 : EXPECT_EQ(p1_type.type, sig->GetReturn(1));
1411 : }
1412 : }
1413 1 : }
1414 :
1415 15189 : TEST_F(WasmSignatureDecodeTest, TooManyParams) {
1416 : static const byte data[] = {kWasmFunctionTypeCode,
1417 : WASM_I32V_3(kV8MaxWasmFunctionParams + 1),
1418 1 : kLocalI32, 0};
1419 : FunctionSig* sig = DecodeSig(data, data + sizeof(data));
1420 2 : EXPECT_FALSE(sig != nullptr);
1421 1 : }
1422 :
1423 15189 : TEST_F(WasmSignatureDecodeTest, TooManyReturns) {
1424 3 : for (int i = 0; i < 2; i++) {
1425 2 : bool enable_mv = i != 0;
1426 2 : WASM_FEATURE_SCOPE_VAL(mv, enable_mv);
1427 : const int max_return_count = static_cast<int>(
1428 2 : enable_mv ? kV8MaxWasmFunctionMultiReturns : kV8MaxWasmFunctionReturns);
1429 2 : byte data[] = {kWasmFunctionTypeCode, 0, WASM_I32V_3(max_return_count + 1),
1430 4 : kLocalI32};
1431 : FunctionSig* sig = DecodeSig(data, data + sizeof(data));
1432 2 : EXPECT_EQ(nullptr, sig);
1433 : }
1434 1 : }
1435 :
1436 15189 : TEST_F(WasmSignatureDecodeTest, Fail_off_end) {
1437 : byte data[256];
1438 6 : for (int p = 0; p <= 255; p = p + 1 + p * 3) {
1439 117 : for (int i = 0; i <= p; i++) data[i] = kLocalI32;
1440 5 : data[0] = static_cast<byte>(p);
1441 :
1442 122 : for (int i = 0; i < p + 1; i++) {
1443 : // Should fall off the end for all signatures.
1444 117 : FunctionSig* sig = DecodeSig(data, data + i);
1445 117 : EXPECT_EQ(nullptr, sig);
1446 : }
1447 : }
1448 1 : }
1449 :
1450 15189 : TEST_F(WasmSignatureDecodeTest, Fail_anyref_without_flag) {
1451 : // Disable AnyRef support and check that decoding fails.
1452 1 : WASM_FEATURE_SCOPE_VAL(anyref, false);
1453 1 : byte ref_types[] = {kLocalAnyFunc, kLocalAnyRef};
1454 3 : for (byte invalid_type : ref_types) {
1455 12 : for (size_t i = 0;; i++) {
1456 14 : byte data[] = {SIG_ENTRY_x_xx(kLocalI32, kLocalI32, kLocalI32)};
1457 14 : if (i >= arraysize(data)) break;
1458 12 : data[i] = invalid_type;
1459 : FunctionSig* sig = DecodeSig(data, data + sizeof(data));
1460 12 : EXPECT_EQ(nullptr, sig);
1461 12 : }
1462 : }
1463 1 : }
1464 :
1465 15189 : TEST_F(WasmSignatureDecodeTest, Fail_invalid_type) {
1466 : byte kInvalidType = 76;
1467 6 : for (size_t i = 0;; i++) {
1468 7 : byte data[] = {SIG_ENTRY_x_xx(kLocalI32, kLocalI32, kLocalI32)};
1469 7 : if (i >= arraysize(data)) break;
1470 6 : data[i] = kInvalidType;
1471 : FunctionSig* sig = DecodeSig(data, data + sizeof(data));
1472 6 : EXPECT_EQ(nullptr, sig);
1473 6 : }
1474 1 : }
1475 :
1476 15189 : TEST_F(WasmSignatureDecodeTest, Fail_invalid_ret_type1) {
1477 : static const byte data[] = {SIG_ENTRY_x_x(kLocalVoid, kLocalI32)};
1478 : FunctionSig* sig = DecodeSig(data, data + sizeof(data));
1479 1 : EXPECT_EQ(nullptr, sig);
1480 1 : }
1481 :
1482 15189 : TEST_F(WasmSignatureDecodeTest, Fail_invalid_param_type1) {
1483 : static const byte data[] = {SIG_ENTRY_x_x(kLocalI32, kLocalVoid)};
1484 : FunctionSig* sig = DecodeSig(data, data + sizeof(data));
1485 1 : EXPECT_EQ(nullptr, sig);
1486 1 : }
1487 :
1488 15189 : TEST_F(WasmSignatureDecodeTest, Fail_invalid_param_type2) {
1489 : static const byte data[] = {SIG_ENTRY_x_xx(kLocalI32, kLocalI32, kLocalVoid)};
1490 : FunctionSig* sig = DecodeSig(data, data + sizeof(data));
1491 1 : EXPECT_EQ(nullptr, sig);
1492 1 : }
1493 :
1494 2 : class WasmFunctionVerifyTest : public TestWithIsolateAndZone {
1495 : public:
1496 1 : FunctionResult DecodeWasmFunction(const ModuleWireBytes& wire_bytes,
1497 : const WasmModule* module,
1498 : const byte* function_start,
1499 : const byte* function_end) {
1500 1 : WasmFeatures enabled_features;
1501 : return DecodeWasmFunctionForTesting(enabled_features, zone(), wire_bytes,
1502 : module, function_start, function_end,
1503 2 : isolate()->counters());
1504 : }
1505 : };
1506 :
1507 15189 : TEST_F(WasmFunctionVerifyTest, Ok_v_v_empty) {
1508 : static const byte data[] = {
1509 : SIG_ENTRY_v_v, // signature entry
1510 : 4, // locals
1511 : 3,
1512 : kLocalI32, // --
1513 : 4,
1514 : kLocalI64, // --
1515 : 5,
1516 : kLocalF32, // --
1517 : 6,
1518 : kLocalF64, // --
1519 : kExprEnd // body
1520 : };
1521 :
1522 2 : WasmModule module;
1523 : FunctionResult result = DecodeWasmFunction(ModuleWireBytes({}), &module, data,
1524 3 : data + sizeof(data));
1525 2 : EXPECT_OK(result);
1526 :
1527 1 : if (result.value() && result.ok()) {
1528 : WasmFunction* function = result.value().get();
1529 3 : EXPECT_EQ(0u, function->sig->parameter_count());
1530 3 : EXPECT_EQ(0u, function->sig->return_count());
1531 2 : EXPECT_EQ(COUNT_ARGS(SIG_ENTRY_v_v), function->code.offset());
1532 2 : EXPECT_EQ(sizeof(data), function->code.end_offset());
1533 : // TODO(titzer): verify encoding of local declarations
1534 1 : }
1535 : }
1536 :
1537 15189 : TEST_F(WasmModuleVerifyTest, SectionWithoutNameLength) {
1538 1 : const byte data[] = {1};
1539 5 : EXPECT_FAILURE(data);
1540 1 : }
1541 :
1542 15189 : TEST_F(WasmModuleVerifyTest, TheLoneliestOfValidModulesTheTrulyEmptyOne) {
1543 : const byte data[] = {
1544 : 0, // unknown section code.
1545 : 0, // Empty section name.
1546 : // No section name, no content, nothing but sadness.
1547 : 0, // No section content.
1548 1 : };
1549 4 : EXPECT_VERIFIES(data);
1550 1 : }
1551 :
1552 15189 : TEST_F(WasmModuleVerifyTest, OnlyUnknownSectionEmpty) {
1553 : const byte data[] = {
1554 : UNKNOWN_SECTION(0),
1555 1 : };
1556 4 : EXPECT_VERIFIES(data);
1557 1 : }
1558 :
1559 15189 : TEST_F(WasmModuleVerifyTest, OnlyUnknownSectionNonEmpty) {
1560 : const byte data[] = {
1561 : UNKNOWN_SECTION(5),
1562 : 0xFF,
1563 : 0xFF,
1564 : 0xFF,
1565 : 0xFF,
1566 : 0xFF, // section data
1567 1 : };
1568 4 : EXPECT_VERIFIES(data);
1569 1 : }
1570 :
1571 15189 : TEST_F(WasmModuleVerifyTest, SignatureFollowedByEmptyUnknownSection) {
1572 : const byte data[] = {
1573 : // signatures
1574 : SIGNATURES_SECTION_VOID_VOID,
1575 : // -----------------------------------------------------------
1576 1 : UNKNOWN_SECTION(0)};
1577 4 : EXPECT_VERIFIES(data);
1578 1 : }
1579 :
1580 15189 : TEST_F(WasmModuleVerifyTest, SignatureFollowedByUnknownSection) {
1581 : const byte data[] = {
1582 : // signatures
1583 : SIGNATURES_SECTION_VOID_VOID,
1584 : // -----------------------------------------------------------
1585 : UNKNOWN_SECTION(5), 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1586 1 : };
1587 4 : EXPECT_VERIFIES(data);
1588 1 : }
1589 :
1590 15189 : TEST_F(WasmModuleVerifyTest, UnknownSectionOverflow) {
1591 : static const byte data[] = {
1592 : UNKNOWN_SECTION(9),
1593 : 1,
1594 : 2,
1595 : 3,
1596 : 4,
1597 : 5,
1598 : 6,
1599 : 7,
1600 : 8,
1601 : 9,
1602 : 10, // 10 byte section
1603 : };
1604 5 : EXPECT_FAILURE(data);
1605 1 : }
1606 :
1607 15189 : TEST_F(WasmModuleVerifyTest, UnknownSectionUnderflow) {
1608 : static const byte data[] = {
1609 : UNKNOWN_SECTION(333),
1610 : 1,
1611 : 2,
1612 : 3,
1613 : 4, // 4 byte section
1614 : };
1615 5 : EXPECT_FAILURE(data);
1616 1 : }
1617 :
1618 15189 : TEST_F(WasmModuleVerifyTest, UnknownSectionSkipped) {
1619 : static const byte data[] = {
1620 : UNKNOWN_SECTION(1),
1621 : 0, // one byte section
1622 : SECTION(Global, ENTRY_COUNT(1),
1623 : kLocalI32, // memory type
1624 : 0, // exported
1625 : WASM_INIT_EXPR_I32V_1(33)), // init
1626 1 : };
1627 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
1628 2 : EXPECT_OK(result);
1629 :
1630 3 : EXPECT_EQ(1u, result.value()->globals.size());
1631 3 : EXPECT_EQ(0u, result.value()->functions.size());
1632 3 : EXPECT_EQ(0u, result.value()->data_segments.size());
1633 :
1634 1 : const WasmGlobal* global = &result.value()->globals.back();
1635 :
1636 2 : EXPECT_EQ(kWasmI32, global->type);
1637 3 : EXPECT_EQ(0u, global->offset);
1638 : }
1639 :
1640 15189 : TEST_F(WasmModuleVerifyTest, ImportTable_empty) {
1641 : static const byte data[] = {SECTION(Type, ENTRY_COUNT(0)),
1642 : SECTION(Import, ENTRY_COUNT(0))};
1643 4 : EXPECT_VERIFIES(data);
1644 1 : }
1645 :
1646 15189 : TEST_F(WasmModuleVerifyTest, ImportTable_nosigs1) {
1647 : static const byte data[] = {SECTION(Import, ENTRY_COUNT(0))};
1648 4 : EXPECT_VERIFIES(data);
1649 1 : }
1650 :
1651 15189 : TEST_F(WasmModuleVerifyTest, ImportTable_mutable_global) {
1652 : {
1653 : static const byte data[] = {
1654 : SECTION(Import, // section header
1655 : ENTRY_COUNT(1), // number of imports
1656 : ADD_COUNT('m'), // module name
1657 : ADD_COUNT('f'), // global name
1658 : kExternalGlobal, // import kind
1659 : kLocalI32, // type
1660 : 0), // mutability
1661 : };
1662 4 : EXPECT_VERIFIES(data);
1663 : }
1664 : {
1665 : static const byte data[] = {
1666 : SECTION(Import, // section header
1667 : ENTRY_COUNT(1), // sig table
1668 : ADD_COUNT('m'), // module name
1669 : ADD_COUNT('f'), // global name
1670 : kExternalGlobal, // import kind
1671 : kLocalI32, // type
1672 : 1), // mutability
1673 : };
1674 4 : EXPECT_VERIFIES(data);
1675 : }
1676 1 : }
1677 :
1678 15189 : TEST_F(WasmModuleVerifyTest, ImportTable_mutability_malformed) {
1679 : static const byte data[] = {
1680 : SECTION(Import,
1681 : ENTRY_COUNT(1), // --
1682 : ADD_COUNT('m'), // module name
1683 : ADD_COUNT('g'), // global name
1684 : kExternalGlobal, // import kind
1685 : kLocalI32, // type
1686 : 2), // invalid mutability
1687 : };
1688 5 : EXPECT_FAILURE(data);
1689 1 : }
1690 :
1691 15189 : TEST_F(WasmModuleVerifyTest, ImportTable_nosigs2) {
1692 : static const byte data[] = {
1693 : SECTION(Import, ENTRY_COUNT(1), // sig table
1694 : ADD_COUNT('m'), // module name
1695 : ADD_COUNT('f'), // function name
1696 : kExternalFunction, // import kind
1697 : SIG_INDEX(0)), // sig index
1698 : };
1699 5 : EXPECT_FAILURE(data);
1700 1 : }
1701 :
1702 15189 : TEST_F(WasmModuleVerifyTest, ImportTable_invalid_sig) {
1703 : static const byte data[] = {
1704 : SECTION(Type, ENTRY_COUNT(0)), // --
1705 : SECTION(Import, ENTRY_COUNT(1), // --
1706 : ADD_COUNT('m'), // module name
1707 : ADD_COUNT('f'), // function name
1708 : kExternalFunction, // import kind
1709 : SIG_INDEX(0)), // sig index
1710 : };
1711 5 : EXPECT_FAILURE(data);
1712 1 : }
1713 :
1714 15189 : TEST_F(WasmModuleVerifyTest, ImportTable_one_sig) {
1715 : static const byte data[] = {
1716 : // signatures
1717 : SIGNATURES_SECTION_VOID_VOID,
1718 : SECTION(Import,
1719 : ENTRY_COUNT(1), // --
1720 : ADD_COUNT('m'), // module name
1721 : ADD_COUNT('f'), // function name
1722 : kExternalFunction, // import kind
1723 : SIG_INDEX(0)), // sig index
1724 : };
1725 4 : EXPECT_VERIFIES(data);
1726 1 : }
1727 :
1728 15189 : TEST_F(WasmModuleVerifyTest, ImportTable_invalid_module) {
1729 : static const byte data[] = {
1730 : // signatures
1731 : SIGNATURES_SECTION_VOID_VOID, // --
1732 : SECTION(Import, // --
1733 : ENTRY_COUNT(1), // --
1734 : NO_NAME, // module name
1735 : ADD_COUNT('f'), // function name
1736 : kExternalFunction, // import kind
1737 : SIG_INDEX(0), // sig index
1738 : 0), // auxiliary data
1739 : };
1740 5 : EXPECT_FAILURE(data);
1741 1 : }
1742 :
1743 15189 : TEST_F(WasmModuleVerifyTest, ImportTable_off_end) {
1744 : static const byte data[] = {
1745 : // signatures
1746 : SIGNATURES_SECTION_VOID_VOID,
1747 : SECTION(Import, ENTRY_COUNT(1),
1748 : ADD_COUNT('m'), // module name
1749 : ADD_COUNT('f'), // function name
1750 : kExternalFunction), // import kind
1751 : SIG_INDEX(0), // sig index (outside import section!)
1752 : };
1753 :
1754 13 : EXPECT_OFF_END_FAILURE(data, arraysize(data) - 3);
1755 1 : }
1756 :
1757 15189 : TEST_F(WasmModuleVerifyTest, ExportTable_empty1) {
1758 : static const byte data[] = { // signatures
1759 : SIGNATURES_SECTION_VOID_VOID, // --
1760 : ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
1761 : SECTION(Export, ENTRY_COUNT(0)), // --
1762 : ONE_EMPTY_BODY};
1763 :
1764 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
1765 2 : EXPECT_OK(result);
1766 :
1767 3 : EXPECT_EQ(1u, result.value()->functions.size());
1768 4 : EXPECT_EQ(0u, result.value()->export_table.size());
1769 : }
1770 :
1771 15189 : TEST_F(WasmModuleVerifyTest, ExportTable_empty2) {
1772 : static const byte data[] = {SECTION(Type, ENTRY_COUNT(0)),
1773 : SECTION(Export, ENTRY_COUNT(0))};
1774 4 : EXPECT_VERIFIES(data);
1775 1 : }
1776 :
1777 15189 : TEST_F(WasmModuleVerifyTest, ExportTable_NoFunctions2) {
1778 : static const byte data[] = {SECTION(Export, ENTRY_COUNT(0))};
1779 4 : EXPECT_VERIFIES(data);
1780 1 : }
1781 :
1782 15189 : TEST_F(WasmModuleVerifyTest, ExportTableOne) {
1783 : static const byte data[] = {
1784 : // signatures
1785 : SIGNATURES_SECTION_VOID_VOID, ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
1786 : SECTION(Export,
1787 : ENTRY_COUNT(1), // exports
1788 : NO_NAME, // --
1789 : kExternalFunction, // --
1790 : FUNC_INDEX(0)), // --
1791 : ONE_EMPTY_BODY};
1792 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
1793 2 : EXPECT_OK(result);
1794 :
1795 3 : EXPECT_EQ(1u, result.value()->functions.size());
1796 4 : EXPECT_EQ(1u, result.value()->export_table.size());
1797 : }
1798 :
1799 15189 : TEST_F(WasmModuleVerifyTest, ExportNameWithInvalidStringLength) {
1800 : static const byte data[] = {
1801 : // signatures
1802 : SIGNATURES_SECTION_VOID_VOID, ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
1803 : SECTION(Export,
1804 : ENTRY_COUNT(1), // exports
1805 : U32V_1(84), // invalid string length
1806 : 'e', // --
1807 : kExternalFunction, // --
1808 : FUNC_INDEX(0), // --
1809 : 0, 0, 0) // auxiliary data
1810 : };
1811 :
1812 5 : EXPECT_FAILURE(data);
1813 1 : }
1814 :
1815 15189 : TEST_F(WasmModuleVerifyTest, ExportTableTwo) {
1816 : static const byte data[] = {
1817 : // signatures
1818 : SIGNATURES_SECTION_VOID_VOID, ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
1819 : SECTION(Export,
1820 : ENTRY_COUNT(2), // exports
1821 : ADD_COUNT('n', 'a', 'm', 'e'), // --
1822 : kExternalFunction, // --
1823 : FUNC_INDEX(0), // --
1824 : ADD_COUNT('n', 'o', 'm'), // --
1825 : kExternalFunction, // --
1826 : FUNC_INDEX(0)), // --
1827 : ONE_EMPTY_BODY};
1828 :
1829 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
1830 2 : EXPECT_OK(result);
1831 :
1832 3 : EXPECT_EQ(1u, result.value()->functions.size());
1833 4 : EXPECT_EQ(2u, result.value()->export_table.size());
1834 : }
1835 :
1836 15189 : TEST_F(WasmModuleVerifyTest, ExportTableThree) {
1837 : static const byte data[] = {
1838 : // signatures
1839 : SIGNATURES_SECTION_VOID_VOID, THREE_EMPTY_FUNCTIONS(SIG_INDEX(0)),
1840 : SECTION(Export,
1841 : ENTRY_COUNT(3), // exports
1842 : ADD_COUNT('a'), // --
1843 : kExternalFunction,
1844 : FUNC_INDEX(0), // --
1845 : ADD_COUNT('b'), // --
1846 : kExternalFunction,
1847 : FUNC_INDEX(1), // --
1848 : ADD_COUNT('c'), // --
1849 : kExternalFunction,
1850 : FUNC_INDEX(2)), // --
1851 : THREE_EMPTY_BODIES};
1852 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
1853 2 : EXPECT_OK(result);
1854 :
1855 3 : EXPECT_EQ(3u, result.value()->functions.size());
1856 4 : EXPECT_EQ(3u, result.value()->export_table.size());
1857 : }
1858 :
1859 15189 : TEST_F(WasmModuleVerifyTest, ExportTableThreeOne) {
1860 7 : for (int i = 0; i < 6; i++) {
1861 : const byte data[] = {
1862 : // signatures
1863 : SIGNATURES_SECTION_VOID_VOID, THREE_EMPTY_FUNCTIONS(SIG_INDEX(0)),
1864 : SECTION(Export,
1865 : ENTRY_COUNT(1), // exports
1866 : ADD_COUNT('e', 'x'), // --
1867 : kExternalFunction,
1868 : FUNC_INDEX(i)), // --
1869 6 : THREE_EMPTY_BODIES};
1870 :
1871 6 : if (i < 3) {
1872 12 : EXPECT_VERIFIES(data);
1873 : } else {
1874 15 : EXPECT_FAILURE(data);
1875 : }
1876 : }
1877 1 : }
1878 :
1879 15189 : TEST_F(WasmModuleVerifyTest, ExportTableOne_off_end) {
1880 : static const byte data[] = {
1881 : // signatures
1882 : SIGNATURES_SECTION_VOID_VOID, ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
1883 : SECTION(Export,
1884 : ENTRY_COUNT(1), // exports
1885 : NO_NAME, // --
1886 : kExternalFunction,
1887 : FUNC_INDEX(0), // --
1888 : 0, 0, 0) // auxiliary data
1889 : };
1890 :
1891 13 : EXPECT_OFF_END_FAILURE(data, arraysize(data) - 3);
1892 1 : }
1893 :
1894 15189 : TEST_F(WasmModuleVerifyTest, Regression_648070) {
1895 : static const byte data[] = {
1896 : SECTION(Type, ENTRY_COUNT(0)), // --
1897 : SECTION(Function, U32V_5(3500228624)) // function count = 3500228624
1898 : }; // --
1899 5 : EXPECT_FAILURE(data);
1900 1 : }
1901 :
1902 15189 : TEST_F(WasmModuleVerifyTest, Regression_738097) {
1903 : // The function body size caused an integer overflow in the module decoder.
1904 : static const byte data[] = {
1905 : SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
1906 : FUNCTION_SIGNATURES_SECTION(1, 0), // --
1907 : SECTION(Code, // --
1908 : ENTRY_COUNT(1), // --
1909 : U32V_5(0xFFFFFFFF), // function size,
1910 : 0) // No real body
1911 : };
1912 5 : EXPECT_FAILURE(data);
1913 1 : }
1914 :
1915 15189 : TEST_F(WasmModuleVerifyTest, FunctionBodySizeLimit) {
1916 : const uint32_t delta = 3;
1917 7 : for (uint32_t body_size = kV8MaxWasmFunctionSize - delta;
1918 : body_size < kV8MaxWasmFunctionSize + delta; body_size++) {
1919 : byte data[] = {
1920 : SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
1921 : FUNCTION_SIGNATURES_SECTION(1, 0), // --
1922 : kCodeSectionCode, // code section
1923 24 : U32V_5(1 + body_size + 5), // section size
1924 : 1, // # functions
1925 24 : U32V_5(body_size) // body size
1926 54 : };
1927 6 : size_t total = sizeof(data) + body_size;
1928 6 : byte* buffer = reinterpret_cast<byte*>(calloc(1, total));
1929 : memcpy(buffer, data, sizeof(data));
1930 12 : ModuleResult result = DecodeModule(buffer, buffer + total);
1931 6 : if (body_size <= kV8MaxWasmFunctionSize) {
1932 4 : EXPECT_TRUE(result.ok());
1933 : } else {
1934 4 : EXPECT_FALSE(result.ok());
1935 : }
1936 6 : free(buffer);
1937 6 : }
1938 1 : }
1939 :
1940 15189 : TEST_F(WasmModuleVerifyTest, FunctionBodies_empty) {
1941 : static const byte data[] = {
1942 : EMPTY_SIGNATURES_SECTION, // --
1943 : EMPTY_FUNCTION_SIGNATURES_SECTION, // --
1944 : EMPTY_FUNCTION_BODIES_SECTION // --
1945 : };
1946 4 : EXPECT_VERIFIES(data);
1947 1 : }
1948 :
1949 15189 : TEST_F(WasmModuleVerifyTest, FunctionBodies_one_empty) {
1950 : static const byte data[] = {
1951 : SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
1952 : FUNCTION_SIGNATURES_SECTION(1, 0), // --
1953 : ONE_EMPTY_BODY // --
1954 : };
1955 4 : EXPECT_VERIFIES(data);
1956 1 : }
1957 :
1958 15189 : TEST_F(WasmModuleVerifyTest, FunctionBodies_one_nop) {
1959 : static const byte data[] = {
1960 : SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
1961 : FUNCTION_SIGNATURES_SECTION(1, 0), // --
1962 : SECTION(Code, ENTRY_COUNT(1), NOP_BODY) // --
1963 : };
1964 4 : EXPECT_VERIFIES(data);
1965 1 : }
1966 :
1967 15189 : TEST_F(WasmModuleVerifyTest, FunctionBodies_count_mismatch1) {
1968 : static const byte data[] = {
1969 : SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
1970 : FUNCTION_SIGNATURES_SECTION(2, 0, 0), // --
1971 : ONE_EMPTY_BODY // --
1972 : };
1973 5 : EXPECT_FAILURE(data);
1974 1 : }
1975 :
1976 15189 : TEST_F(WasmModuleVerifyTest, FunctionBodies_count_mismatch2) {
1977 : static const byte data[] = {
1978 : SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
1979 : FUNCTION_SIGNATURES_SECTION(1, 0), // --
1980 : SECTION(Code, ENTRY_COUNT(2), NOP_BODY, NOP_BODY) // --
1981 : };
1982 5 : EXPECT_FAILURE(data);
1983 1 : }
1984 :
1985 15189 : TEST_F(WasmModuleVerifyTest, Names_empty) {
1986 : static const byte data[] = {
1987 : EMPTY_SIGNATURES_SECTION, EMPTY_FUNCTION_SIGNATURES_SECTION,
1988 : EMPTY_FUNCTION_BODIES_SECTION, EMPTY_NAMES_SECTION};
1989 4 : EXPECT_VERIFIES(data);
1990 1 : }
1991 :
1992 15189 : TEST_F(WasmModuleVerifyTest, Names_one_empty) {
1993 : // TODO(wasm): This test does not test anything (corrupt name section does not
1994 : // fail validation).
1995 : static const byte data[] = {
1996 : SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
1997 : FUNCTION_SIGNATURES_SECTION(1, 0), // --
1998 : ONE_EMPTY_BODY, // --
1999 : SECTION_NAMES(ENTRY_COUNT(1), FOO_STRING, NO_LOCAL_NAMES) // --
2000 : };
2001 4 : EXPECT_VERIFIES(data);
2002 1 : }
2003 :
2004 15189 : TEST_F(WasmModuleVerifyTest, Names_two_empty) {
2005 : // TODO(wasm): This test does not test anything (corrupt name section does not
2006 : // fail validation).
2007 : static const byte data[] = {
2008 : SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
2009 : FUNCTION_SIGNATURES_SECTION(2, 0, 0), // --
2010 : TWO_EMPTY_BODIES, // --
2011 : SECTION_NAMES(ENTRY_COUNT(2), // --
2012 : FOO_STRING, NO_LOCAL_NAMES, // --
2013 : FOO_STRING, NO_LOCAL_NAMES), // --
2014 : };
2015 4 : EXPECT_VERIFIES(data);
2016 1 : }
2017 :
2018 15189 : TEST_F(WasmModuleVerifyTest, Regression684855) {
2019 : static const byte data[] = {
2020 : SECTION_NAMES(0xFB, // functions count
2021 : 0x27, // |
2022 : 0x00, // function name length
2023 : 0xFF, // local names count
2024 : 0xFF, // |
2025 : 0xFF, // |
2026 : 0xFF, // |
2027 : 0xFF, // |
2028 : 0xFF, // error: "varint too large"
2029 : 0xFF, // |
2030 : 0x00, // --
2031 : 0x00) // --
2032 : };
2033 4 : EXPECT_VERIFIES(data);
2034 1 : }
2035 :
2036 15189 : TEST_F(WasmModuleVerifyTest, FunctionSectionWithoutCodeSection) {
2037 : static const byte data[] = {
2038 : SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // Type section.
2039 : FUNCTION_SIGNATURES_SECTION(1, 0), // Function section.
2040 : };
2041 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
2042 7 : EXPECT_NOT_OK(result, "function count is 1, but code section is absent");
2043 1 : }
2044 :
2045 15189 : TEST_F(WasmModuleVerifyTest, CodeSectionWithoutFunctionSection) {
2046 : static const byte data[] = {ONE_EMPTY_BODY};
2047 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
2048 7 : EXPECT_NOT_OK(result, "function body count 1 mismatch (0 expected)");
2049 1 : }
2050 :
2051 15189 : TEST_F(WasmModuleVerifyTest, EmptyFunctionSectionWithoutCodeSection) {
2052 : static const byte data[] = {SECTION(Function, ENTRY_COUNT(0))};
2053 4 : EXPECT_VERIFIES(data);
2054 1 : }
2055 :
2056 15189 : TEST_F(WasmModuleVerifyTest, EmptyCodeSectionWithoutFunctionSection) {
2057 : static const byte data[] = {SECTION(Code, ENTRY_COUNT(0))};
2058 4 : EXPECT_VERIFIES(data);
2059 1 : }
2060 :
2061 6 : class WasmInitExprDecodeTest : public TestWithZone {
2062 : public:
2063 6 : WasmInitExprDecodeTest() = default;
2064 :
2065 : WasmFeatures enabled_features_;
2066 :
2067 : WasmInitExpr DecodeInitExpr(const byte* start, const byte* end) {
2068 22 : return DecodeWasmInitExprForTesting(enabled_features_, start, end);
2069 : }
2070 : };
2071 :
2072 : #define EXPECT_INIT_EXPR(Type, type, value, ...) \
2073 : { \
2074 : static const byte data[] = {__VA_ARGS__, kExprEnd}; \
2075 : WasmInitExpr expr = DecodeInitExpr(data, data + sizeof(data)); \
2076 : EXPECT_EQ(WasmInitExpr::k##Type##Const, expr.kind); \
2077 : EXPECT_EQ(value, expr.val.type##_const); \
2078 : }
2079 :
2080 : #define EXPECT_INIT_EXPR_FAIL(...) \
2081 : { \
2082 : static const byte data[] = {__VA_ARGS__, kExprEnd}; \
2083 : WasmInitExpr expr = DecodeInitExpr(data, data + sizeof(data)); \
2084 : EXPECT_EQ(WasmInitExpr::kNone, expr.kind); \
2085 : }
2086 :
2087 15189 : TEST_F(WasmInitExprDecodeTest, InitExpr_i32) {
2088 5 : EXPECT_INIT_EXPR(I32, i32, 33, WASM_I32V_1(33));
2089 5 : EXPECT_INIT_EXPR(I32, i32, -21, WASM_I32V_1(-21));
2090 5 : EXPECT_INIT_EXPR(I32, i32, 437, WASM_I32V_2(437));
2091 5 : EXPECT_INIT_EXPR(I32, i32, 77777, WASM_I32V_3(77777));
2092 1 : }
2093 :
2094 15189 : TEST_F(WasmInitExprDecodeTest, InitExpr_f32) {
2095 5 : EXPECT_INIT_EXPR(F32, f32, static_cast<float>(13.1), WASM_F32(13.1));
2096 5 : EXPECT_INIT_EXPR(F32, f32, static_cast<float>(-21.1), WASM_F32(-21.1));
2097 5 : EXPECT_INIT_EXPR(F32, f32, static_cast<float>(437.2), WASM_F32(437.2));
2098 5 : EXPECT_INIT_EXPR(F32, f32, static_cast<float>(77777.3), WASM_F32(77777.3));
2099 1 : }
2100 :
2101 15189 : TEST_F(WasmInitExprDecodeTest, InitExpr_i64) {
2102 5 : EXPECT_INIT_EXPR(I64, i64, 33, WASM_I64V_1(33));
2103 5 : EXPECT_INIT_EXPR(I64, i64, -21, WASM_I64V_2(-21));
2104 5 : EXPECT_INIT_EXPR(I64, i64, 437, WASM_I64V_5(437));
2105 5 : EXPECT_INIT_EXPR(I64, i64, 77777, WASM_I64V_7(77777));
2106 1 : }
2107 :
2108 15189 : TEST_F(WasmInitExprDecodeTest, InitExpr_f64) {
2109 5 : EXPECT_INIT_EXPR(F64, f64, 83.22, WASM_F64(83.22));
2110 5 : EXPECT_INIT_EXPR(F64, f64, -771.3, WASM_F64(-771.3));
2111 5 : EXPECT_INIT_EXPR(F64, f64, 43703.0, WASM_F64(43703.0));
2112 5 : EXPECT_INIT_EXPR(F64, f64, 77999.1, WASM_F64(77999.1));
2113 1 : }
2114 :
2115 15189 : TEST_F(WasmInitExprDecodeTest, InitExpr_AnyRef) {
2116 1 : WASM_FEATURE_SCOPE(anyref);
2117 : static const byte data[] = {kExprRefNull, kExprEnd};
2118 1 : WasmInitExpr expr = DecodeInitExpr(data, data + sizeof(data));
2119 2 : EXPECT_EQ(WasmInitExpr::kAnyRefConst, expr.kind);
2120 1 : }
2121 :
2122 15189 : TEST_F(WasmInitExprDecodeTest, InitExpr_illegal) {
2123 3 : EXPECT_INIT_EXPR_FAIL(WASM_I32V_1(0), WASM_I32V_1(0));
2124 2 : EXPECT_INIT_EXPR_FAIL(WASM_GET_LOCAL(0));
2125 3 : EXPECT_INIT_EXPR_FAIL(WASM_SET_LOCAL(0, WASM_I32V_1(0)));
2126 3 : EXPECT_INIT_EXPR_FAIL(WASM_I32_ADD(WASM_I32V_1(0), WASM_I32V_1(0)));
2127 2 : EXPECT_INIT_EXPR_FAIL(WASM_IF_ELSE(WASM_ZERO, WASM_ZERO, WASM_ZERO));
2128 1 : }
2129 :
2130 15189 : TEST_F(WasmModuleVerifyTest, Multiple_Named_Sections) {
2131 : static const byte data[] = {
2132 : SECTION(Unknown, ADD_COUNT('X'), 17, 18), // --
2133 : SECTION(Unknown, ADD_COUNT('f', 'o', 'o'), 5, 6, 7, 8, 9), // --
2134 : SECTION(Unknown, ADD_COUNT('o', 't', 'h', 'e', 'r'), 7, 8), // --
2135 : };
2136 4 : EXPECT_VERIFIES(data);
2137 1 : }
2138 :
2139 15189 : TEST_F(WasmModuleVerifyTest, Section_Name_No_UTF8) {
2140 : static const byte data[] = {SECTION(Unknown, 1, 0xFF, 17, 18)};
2141 5 : EXPECT_FAILURE(data);
2142 1 : }
2143 :
2144 4 : class WasmModuleCustomSectionTest : public TestWithIsolateAndZone {
2145 : public:
2146 2 : void CheckSections(const byte* module_start, const byte* module_end,
2147 : const CustomSectionOffset* expected, size_t num_expected) {
2148 : std::vector<CustomSectionOffset> custom_sections =
2149 2 : DecodeCustomSections(module_start, module_end);
2150 :
2151 4 : CHECK_EQ(num_expected, custom_sections.size());
2152 :
2153 5 : for (size_t i = 0; i < num_expected; i++) {
2154 20 : EXPECT_EQ(expected[i].section.offset(),
2155 0 : custom_sections[i].section.offset());
2156 20 : EXPECT_EQ(expected[i].section.length(),
2157 0 : custom_sections[i].section.length());
2158 20 : EXPECT_EQ(expected[i].name.offset(), custom_sections[i].name.offset());
2159 20 : EXPECT_EQ(expected[i].name.length(), custom_sections[i].name.length());
2160 20 : EXPECT_EQ(expected[i].payload.offset(),
2161 0 : custom_sections[i].payload.offset());
2162 20 : EXPECT_EQ(expected[i].payload.length(),
2163 0 : custom_sections[i].payload.length());
2164 : }
2165 2 : }
2166 : };
2167 :
2168 15189 : TEST_F(WasmModuleCustomSectionTest, ThreeUnknownSections) {
2169 : static constexpr byte data[] = {
2170 : U32_LE(kWasmMagic), // --
2171 : U32_LE(kWasmVersion), // --
2172 : SECTION(Unknown, 1, 'X', 17, 18), // --
2173 : SECTION(Unknown, 3, 'f', 'o', 'o', 5, 6, 7, 8, 9), // --
2174 : SECTION(Unknown, 5, 'o', 't', 'h', 'e', 'r', 7, 8), // --
2175 : };
2176 :
2177 : static const CustomSectionOffset expected[] = {
2178 : // section, name, payload
2179 : {{10, 4}, {11, 1}, {12, 2}}, // --
2180 : {{16, 9}, {17, 3}, {20, 5}}, // --
2181 : {{27, 8}, {28, 5}, {33, 2}}, // --
2182 2 : };
2183 :
2184 1 : CheckSections(data, data + sizeof(data), expected, arraysize(expected));
2185 1 : }
2186 :
2187 15189 : TEST_F(WasmModuleCustomSectionTest, TwoKnownTwoUnknownSections) {
2188 : static const byte data[] = {
2189 : U32_LE(kWasmMagic), // --
2190 : U32_LE(kWasmVersion), // --
2191 : SIGNATURES_SECTION(2, SIG_ENTRY_v_v, SIG_ENTRY_v_v), // --
2192 : SECTION(Unknown, ADD_COUNT('X'), 17, 18), // --
2193 : ONE_EMPTY_FUNCTION(SIG_INDEX(0)), // --
2194 : SECTION(Unknown, ADD_COUNT('o', 't', 'h', 'e', 'r'), 7, 8), // --
2195 : };
2196 :
2197 : static const CustomSectionOffset expected[] = {
2198 : // section, name, payload
2199 : {{19, 4}, {20, 1}, {21, 2}}, // --
2200 : {{29, 8}, {30, 5}, {35, 2}}, // --
2201 2 : };
2202 :
2203 1 : CheckSections(data, data + sizeof(data), expected, arraysize(expected));
2204 1 : }
2205 :
2206 15189 : TEST_F(WasmModuleVerifyTest, SourceMappingURLSection) {
2207 : static const byte data[] = {
2208 : SECTION_SRC_MAP('s', 'r', 'c', '/', 'x', 'y', 'z', '.', 'c')};
2209 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
2210 1 : EXPECT_TRUE(result.ok());
2211 3 : EXPECT_EQ("src/xyz.c", result.value()->source_map_url);
2212 1 : }
2213 :
2214 15189 : TEST_F(WasmModuleVerifyTest, BadSourceMappingURLSection) {
2215 : static const byte data[] = {
2216 : SECTION_SRC_MAP('s', 'r', 'c', '/', 'x', 0xff, 'z', '.', 'c')};
2217 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
2218 1 : EXPECT_TRUE(result.ok());
2219 4 : EXPECT_EQ(0u, result.value()->source_map_url.size());
2220 1 : }
2221 :
2222 15189 : TEST_F(WasmModuleVerifyTest, MultipleSourceMappingURLSections) {
2223 : static const byte data[] = {SECTION_SRC_MAP('a', 'b', 'c'),
2224 : SECTION_SRC_MAP('p', 'q', 'r')};
2225 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
2226 1 : EXPECT_TRUE(result.ok());
2227 3 : EXPECT_EQ("abc", result.value()->source_map_url);
2228 1 : }
2229 :
2230 15189 : TEST_F(WasmModuleVerifyTest, MultipleNameSections) {
2231 : static const byte data[] = {
2232 : SECTION_NAMES(0, ADD_COUNT(ADD_COUNT('a', 'b', 'c'))),
2233 : SECTION_NAMES(0, ADD_COUNT(ADD_COUNT('p', 'q', 'r', 's')))};
2234 2 : ModuleResult result = DecodeModule(data, data + sizeof(data));
2235 1 : EXPECT_TRUE(result.ok());
2236 3 : EXPECT_EQ(3u, result.value()->name.length());
2237 1 : }
2238 :
2239 15189 : TEST_F(WasmModuleVerifyTest, PassiveDataSegment) {
2240 : static const byte data[] = {
2241 : // memory declaration ----------------------------------------------------
2242 : SECTION(Memory, ENTRY_COUNT(1), 0, 1),
2243 : // data segments --------------------------------------------------------
2244 : SECTION(Data, ENTRY_COUNT(1), PASSIVE, ADD_COUNT('h', 'i')),
2245 : };
2246 5 : EXPECT_FAILURE(data);
2247 1 : WASM_FEATURE_SCOPE(bulk_memory);
2248 4 : EXPECT_VERIFIES(data);
2249 21 : EXPECT_OFF_END_FAILURE(data, arraysize(data) - 5);
2250 1 : }
2251 :
2252 15189 : TEST_F(WasmModuleVerifyTest, PassiveElementSegment) {
2253 : static const byte data[] = {
2254 : // sig#0 -----------------------------------------------------------------
2255 : SIGNATURES_SECTION_VOID_VOID,
2256 : // funcs -----------------------------------------------------------------
2257 : ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
2258 : // table declaration -----------------------------------------------------
2259 : SECTION(Table, ENTRY_COUNT(1), kLocalAnyFunc, 0, 1),
2260 : // element segments -----------------------------------------------------
2261 : SECTION(Element, ENTRY_COUNT(1), PASSIVE,
2262 : ADD_COUNT(FUNC_INDEX(0), FUNC_INDEX(0))),
2263 : // code ------------------------------------------------------------------
2264 : ONE_EMPTY_BODY};
2265 5 : EXPECT_FAILURE(data);
2266 1 : WASM_FEATURE_SCOPE(bulk_memory);
2267 4 : EXPECT_VERIFIES(data);
2268 21 : EXPECT_OFF_END_FAILURE(data, arraysize(data) - 5);
2269 1 : }
2270 :
2271 15189 : TEST_F(WasmModuleVerifyTest, DataCountSectionCorrectPlacement) {
2272 : static const byte data[] = {SECTION(Element, ENTRY_COUNT(0)),
2273 : SECTION(DataCount, ENTRY_COUNT(0)),
2274 : SECTION(Code, ENTRY_COUNT(0))};
2275 5 : EXPECT_FAILURE(data);
2276 1 : WASM_FEATURE_SCOPE(bulk_memory);
2277 4 : EXPECT_VERIFIES(data);
2278 1 : }
2279 :
2280 15189 : TEST_F(WasmModuleVerifyTest, DataCountSectionAfterCode) {
2281 : static const byte data[] = {SECTION(Code, ENTRY_COUNT(0)),
2282 : SECTION(DataCount, ENTRY_COUNT(0))};
2283 1 : WASM_FEATURE_SCOPE(bulk_memory);
2284 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
2285 6 : EXPECT_NOT_OK(result,
2286 : "The DataCount section must appear before the Code section");
2287 1 : }
2288 :
2289 15189 : TEST_F(WasmModuleVerifyTest, DataCountSectionBeforeElement) {
2290 : static const byte data[] = {SECTION(DataCount, ENTRY_COUNT(0)),
2291 : SECTION(Element, ENTRY_COUNT(0))};
2292 1 : WASM_FEATURE_SCOPE(bulk_memory);
2293 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
2294 6 : EXPECT_NOT_OK(result, "unexpected section <Element>");
2295 1 : }
2296 :
2297 15189 : TEST_F(WasmModuleVerifyTest, DataCountSectionAfterStartBeforeElement) {
2298 : STATIC_ASSERT(kStartSectionCode + 1 == kElementSectionCode);
2299 : static const byte data[] = {
2300 : // We need the start section for this test, but the start section must
2301 : // reference a valid function, which requires the type and function
2302 : // sections too.
2303 : SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // Type section.
2304 : FUNCTION_SIGNATURES_SECTION(1, 0), // Function section.
2305 :
2306 : SECTION(Start, U32V_1(0)), // Start section.
2307 : SECTION(DataCount, ENTRY_COUNT(0)), // DataCount section.
2308 : SECTION(Element, ENTRY_COUNT(0)) // Element section.
2309 : };
2310 1 : WASM_FEATURE_SCOPE(bulk_memory);
2311 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
2312 6 : EXPECT_NOT_OK(result, "unexpected section <Element>");
2313 1 : }
2314 :
2315 15189 : TEST_F(WasmModuleVerifyTest, MultipleDataCountSections) {
2316 : static const byte data[] = {SECTION(DataCount, ENTRY_COUNT(0)),
2317 : SECTION(DataCount, ENTRY_COUNT(0))};
2318 1 : WASM_FEATURE_SCOPE(bulk_memory);
2319 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
2320 6 : EXPECT_NOT_OK(result, "Multiple DataCount sections not allowed");
2321 1 : }
2322 :
2323 15189 : TEST_F(WasmModuleVerifyTest, DataCountSegmentCountMatch) {
2324 : static const byte data[] = {
2325 : SECTION(Memory, ENTRY_COUNT(1), 0, 1), // Memory section.
2326 : SECTION(DataCount, ENTRY_COUNT(1)), // DataCount section.
2327 : SECTION(Data, ENTRY_COUNT(1), LINEAR_MEMORY_INDEX_0, // Data section.
2328 1 : WASM_INIT_EXPR_I32V_1(12), ADD_COUNT('h', 'i'))};
2329 :
2330 5 : EXPECT_FAILURE(data);
2331 1 : WASM_FEATURE_SCOPE(bulk_memory);
2332 4 : EXPECT_VERIFIES(data);
2333 1 : }
2334 :
2335 15189 : TEST_F(WasmModuleVerifyTest, DataCountSegmentCount_greater) {
2336 : static const byte data[] = {
2337 : SECTION(Memory, ENTRY_COUNT(1), 0, 1), // Memory section.
2338 : SECTION(DataCount, ENTRY_COUNT(3)), // DataCount section.
2339 : SECTION(Data, ENTRY_COUNT(0))}; // Data section.
2340 1 : WASM_FEATURE_SCOPE(bulk_memory);
2341 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
2342 6 : EXPECT_NOT_OK(result, "data segments count 0 mismatch (3 expected)");
2343 1 : }
2344 :
2345 15189 : TEST_F(WasmModuleVerifyTest, DataCountSegmentCount_less) {
2346 : static const byte data[] = {
2347 : SECTION(Memory, ENTRY_COUNT(1), 0, 1), // Memory section.
2348 : SECTION(DataCount, ENTRY_COUNT(0)), // DataCount section.
2349 : SECTION(Data, ENTRY_COUNT(1), LINEAR_MEMORY_INDEX_0, // Data section.
2350 1 : WASM_INIT_EXPR_I32V_1(12), ADD_COUNT('a', 'b', 'c'))};
2351 1 : WASM_FEATURE_SCOPE(bulk_memory);
2352 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
2353 6 : EXPECT_NOT_OK(result, "data segments count 1 mismatch (0 expected)");
2354 1 : }
2355 :
2356 15189 : TEST_F(WasmModuleVerifyTest, DataCountSegmentCount_omitted) {
2357 : static const byte data[] = {SECTION(Memory, ENTRY_COUNT(1), 0, 1),
2358 : SECTION(DataCount, ENTRY_COUNT(1))};
2359 1 : WASM_FEATURE_SCOPE(bulk_memory);
2360 3 : ModuleResult result = DecodeModule(data, data + sizeof(data));
2361 6 : EXPECT_NOT_OK(result, "data segments count 0 mismatch (1 expected)");
2362 1 : }
2363 :
2364 : #undef WASM_FEATURE_SCOPE
2365 : #undef WASM_FEATURE_SCOPE_VAL
2366 : #undef EXPECT_INIT_EXPR
2367 : #undef EXPECT_INIT_EXPR_FAIL
2368 : #undef WASM_INIT_EXPR_I32V_1
2369 : #undef WASM_INIT_EXPR_I32V_2
2370 : #undef WASM_INIT_EXPR_I32V_3
2371 : #undef WASM_INIT_EXPR_I32V_4
2372 : #undef WASM_INIT_EXPR_I32V_5
2373 : #undef WASM_INIT_EXPR_F32
2374 : #undef WASM_INIT_EXPR_I64
2375 : #undef WASM_INIT_EXPR_F64
2376 : #undef WASM_INIT_EXPR_ANYREF
2377 : #undef WASM_INIT_EXPR_GLOBAL
2378 : #undef EMPTY_BODY
2379 : #undef NOP_BODY
2380 : #undef SIG_ENTRY_i_i
2381 : #undef UNKNOWN_SECTION
2382 : #undef COUNT_ARGS
2383 : #undef CHECK_LEB1
2384 : #undef ADD_COUNT
2385 : #undef SECTION
2386 : #undef SIGNATURES_SECTION
2387 : #undef FUNCTION_SIGNATURES_SECTION
2388 : #undef FOO_STRING
2389 : #undef NO_LOCAL_NAMES
2390 : #undef EMPTY_SIGNATURES_SECTION
2391 : #undef EMPTY_FUNCTION_SIGNATURES_SECTION
2392 : #undef EMPTY_FUNCTION_BODIES_SECTION
2393 : #undef SECTION_NAMES
2394 : #undef EMPTY_NAMES_SECTION
2395 : #undef SECTION_SRC_MAP
2396 : #undef FAIL_IF_NO_EXPERIMENTAL_EH
2397 : #undef X1
2398 : #undef X2
2399 : #undef X3
2400 : #undef X4
2401 : #undef ONE_EMPTY_FUNCTION
2402 : #undef TWO_EMPTY_FUNCTIONS
2403 : #undef THREE_EMPTY_FUNCTIONS
2404 : #undef FOUR_EMPTY_FUNCTIONS
2405 : #undef ONE_EMPTY_BODY
2406 : #undef TWO_EMPTY_BODIES
2407 : #undef THREE_EMPTY_BODIES
2408 : #undef FOUR_EMPTY_BODIES
2409 : #undef SIGNATURES_SECTION_VOID_VOID
2410 : #undef LINEAR_MEMORY_INDEX_0
2411 : #undef EXCEPTION_ENTRY
2412 : #undef EXPECT_VERIFIES
2413 : #undef EXPECT_FAILURE_LEN
2414 : #undef EXPECT_FAILURE
2415 : #undef EXPECT_OFF_END_FAILURE
2416 : #undef EXPECT_OK
2417 : #undef EXPECT_NOT_OK
2418 :
2419 : } // namespace module_decoder_unittest
2420 : } // namespace wasm
2421 : } // namespace internal
2422 9111 : } // namespace v8
|