OLD | NEW |
| (Empty) |
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/v8.h" | |
8 | |
9 #include "test/common/wasm/test-signatures.h" | |
10 | |
11 #include "src/objects.h" | |
12 | |
13 #include "src/wasm/ast-decoder.h" | |
14 #include "src/wasm/signature-map.h" | |
15 #include "src/wasm/wasm-macro-gen.h" | |
16 #include "src/wasm/wasm-module.h" | |
17 #include "src/wasm/wasm-opcodes.h" | |
18 | |
19 namespace v8 { | |
20 namespace internal { | |
21 namespace wasm { | |
22 | |
23 #define B1(a) WASM_BLOCK(a) | |
24 #define B2(a, b) WASM_BLOCK(a, b) | |
25 #define B3(a, b, c) WASM_BLOCK(a, b, c) | |
26 | |
27 #define WASM_IF_OP kExprIf, kLocalVoid | |
28 #define WASM_LOOP_OP kExprLoop, kLocalVoid | |
29 | |
30 static const byte kCodeGetLocal0[] = {kExprGetLocal, 0}; | |
31 static const byte kCodeGetLocal1[] = {kExprGetLocal, 1}; | |
32 static const byte kCodeSetLocal0[] = {WASM_SET_LOCAL(0, WASM_ZERO)}; | |
33 static const byte kCodeTeeLocal0[] = {WASM_TEE_LOCAL(0, WASM_ZERO)}; | |
34 | |
35 static const LocalType kLocalTypes[] = {kAstI32, kAstI64, kAstF32, kAstF64}; | |
36 static const MachineType machineTypes[] = { | |
37 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(), | |
38 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(), | |
39 MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(), | |
40 MachineType::Float64()}; | |
41 | |
42 static const WasmOpcode kInt32BinopOpcodes[] = { | |
43 kExprI32Add, kExprI32Sub, kExprI32Mul, kExprI32DivS, kExprI32DivU, | |
44 kExprI32RemS, kExprI32RemU, kExprI32And, kExprI32Ior, kExprI32Xor, | |
45 kExprI32Shl, kExprI32ShrU, kExprI32ShrS, kExprI32Eq, kExprI32LtS, | |
46 kExprI32LeS, kExprI32LtU, kExprI32LeU}; | |
47 | |
48 #define WASM_BRV_IF_ZERO(depth, val) \ | |
49 val, WASM_ZERO, kExprBrIf, static_cast<byte>(depth) | |
50 | |
51 #define EXPECT_VERIFIES_C(sig, x) \ | |
52 Verify(kSuccess, sigs.sig(), x, x + arraysize(x)) | |
53 | |
54 #define EXPECT_FAILURE_C(sig, x) Verify(kError, sigs.sig(), x, x + arraysize(x)) | |
55 | |
56 #define EXPECT_VERIFIES_SC(sig, x) Verify(kSuccess, sig, x, x + arraysize(x)) | |
57 | |
58 #define EXPECT_FAILURE_SC(sig, x) Verify(kError, sig, x, x + arraysize(x)) | |
59 | |
60 #define EXPECT_VERIFIES_S(env, ...) \ | |
61 do { \ | |
62 static byte code[] = {__VA_ARGS__}; \ | |
63 Verify(kSuccess, env, code, code + arraysize(code)); \ | |
64 } while (false) | |
65 | |
66 #define EXPECT_FAILURE_S(env, ...) \ | |
67 do { \ | |
68 static byte code[] = {__VA_ARGS__}; \ | |
69 Verify(kError, env, code, code + arraysize(code)); \ | |
70 } while (false) | |
71 | |
72 #define EXPECT_VERIFIES(sig, ...) \ | |
73 do { \ | |
74 static const byte code[] = {__VA_ARGS__}; \ | |
75 Verify(kSuccess, sigs.sig(), code, code + sizeof(code)); \ | |
76 } while (false) | |
77 | |
78 #define EXPECT_FAILURE(sig, ...) \ | |
79 do { \ | |
80 static const byte code[] = {__VA_ARGS__}; \ | |
81 Verify(kError, sigs.sig(), code, code + sizeof(code)); \ | |
82 } while (false) | |
83 | |
84 static bool old_eh_flag; | |
85 | |
86 class AstDecoderTest : public TestWithZone { | |
87 public: | |
88 typedef std::pair<uint32_t, LocalType> LocalsDecl; | |
89 | |
90 AstDecoderTest() : module(nullptr), local_decls(zone()) {} | |
91 | |
92 static void SetUpTestCase() { old_eh_flag = FLAG_wasm_eh_prototype; } | |
93 | |
94 static void TearDownTestCase() { | |
95 // Reset the wasm_eh_prototype flag | |
96 FLAG_wasm_eh_prototype = old_eh_flag; | |
97 } | |
98 | |
99 TestSignatures sigs; | |
100 ModuleEnv* module; | |
101 LocalDeclEncoder local_decls; | |
102 | |
103 void AddLocals(LocalType type, uint32_t count) { | |
104 local_decls.AddLocals(count, type); | |
105 } | |
106 | |
107 // Prepends local variable declarations and renders nice error messages for | |
108 // verification failures. | |
109 void Verify(ErrorCode expected, FunctionSig* sig, const byte* start, | |
110 const byte* end) { | |
111 local_decls.Prepend(zone(), &start, &end); | |
112 // Verify the code. | |
113 DecodeResult result = | |
114 VerifyWasmCode(zone()->allocator(), module, sig, start, end); | |
115 | |
116 if (result.error_code != expected) { | |
117 ptrdiff_t pc = result.error_pc - result.start; | |
118 ptrdiff_t pt = result.error_pt - result.start; | |
119 std::ostringstream str; | |
120 if (expected == kSuccess) { | |
121 str << "Verification failed: " << result.error_code << " pc = +" << pc; | |
122 if (result.error_pt) str << ", pt = +" << pt; | |
123 str << ", msg = " << result.error_msg.get(); | |
124 } else { | |
125 str << "Verification expected: " << expected << ", but got " | |
126 << result.error_code; | |
127 if (result.error_code != kSuccess) { | |
128 str << " pc = +" << pc; | |
129 if (result.error_pt) str << ", pt = +" << pt; | |
130 } | |
131 } | |
132 EXPECT_TRUE(false) << str.str().c_str(); | |
133 } | |
134 } | |
135 | |
136 void TestBinop(WasmOpcode opcode, FunctionSig* success) { | |
137 // op(local[0], local[1]) | |
138 byte code[] = {WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}; | |
139 EXPECT_VERIFIES_SC(success, code); | |
140 | |
141 // Try all combinations of return and parameter types. | |
142 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
143 for (size_t j = 0; j < arraysize(kLocalTypes); j++) { | |
144 for (size_t k = 0; k < arraysize(kLocalTypes); k++) { | |
145 LocalType types[] = {kLocalTypes[i], kLocalTypes[j], kLocalTypes[k]}; | |
146 if (types[0] != success->GetReturn(0) || | |
147 types[1] != success->GetParam(0) || | |
148 types[2] != success->GetParam(1)) { | |
149 // Test signature mismatch. | |
150 FunctionSig sig(1, 2, types); | |
151 EXPECT_FAILURE_SC(&sig, code); | |
152 } | |
153 } | |
154 } | |
155 } | |
156 } | |
157 | |
158 void TestUnop(WasmOpcode opcode, FunctionSig* success) { | |
159 TestUnop(opcode, success->GetReturn(), success->GetParam(0)); | |
160 } | |
161 | |
162 void TestUnop(WasmOpcode opcode, LocalType ret_type, LocalType param_type) { | |
163 // Return(op(local[0])) | |
164 byte code[] = {WASM_UNOP(opcode, WASM_GET_LOCAL(0))}; | |
165 { | |
166 LocalType types[] = {ret_type, param_type}; | |
167 FunctionSig sig(1, 1, types); | |
168 EXPECT_VERIFIES_SC(&sig, code); | |
169 } | |
170 | |
171 // Try all combinations of return and parameter types. | |
172 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
173 for (size_t j = 0; j < arraysize(kLocalTypes); j++) { | |
174 LocalType types[] = {kLocalTypes[i], kLocalTypes[j]}; | |
175 if (types[0] != ret_type || types[1] != param_type) { | |
176 // Test signature mismatch. | |
177 FunctionSig sig(1, 1, types); | |
178 EXPECT_FAILURE_SC(&sig, code); | |
179 } | |
180 } | |
181 } | |
182 } | |
183 }; | |
184 | |
185 TEST_F(AstDecoderTest, Int8Const) { | |
186 byte code[] = {kExprI8Const, 0}; | |
187 for (int i = -128; i < 128; i++) { | |
188 code[1] = static_cast<byte>(i); | |
189 EXPECT_VERIFIES_C(i_i, code); | |
190 } | |
191 } | |
192 | |
193 TEST_F(AstDecoderTest, EmptyFunction) { | |
194 byte code[] = {0}; | |
195 Verify(kSuccess, sigs.v_v(), code, code); | |
196 Verify(kError, sigs.i_i(), code, code); | |
197 } | |
198 | |
199 TEST_F(AstDecoderTest, IncompleteIf1) { | |
200 byte code[] = {kExprIf}; | |
201 EXPECT_FAILURE_C(v_v, code); | |
202 EXPECT_FAILURE_C(i_i, code); | |
203 } | |
204 | |
205 TEST_F(AstDecoderTest, Int8Const_fallthru) { | |
206 EXPECT_VERIFIES(i_i, WASM_I32V_1(0)); | |
207 } | |
208 | |
209 TEST_F(AstDecoderTest, Int8Const_fallthru2) { | |
210 EXPECT_FAILURE(i_i, WASM_I32V_1(0), WASM_I32V_1(1)); | |
211 } | |
212 | |
213 TEST_F(AstDecoderTest, Int32Const) { | |
214 const int kInc = 4498211; | |
215 for (int32_t i = kMinInt; i < kMaxInt - kInc; i = i + kInc) { | |
216 // TODO(binji): expand test for other sized int32s; 1 through 5 bytes. | |
217 byte code[] = {WASM_I32V(i)}; | |
218 EXPECT_VERIFIES_C(i_i, code); | |
219 } | |
220 } | |
221 | |
222 TEST_F(AstDecoderTest, Int64Const) { | |
223 const int kInc = 4498211; | |
224 for (int32_t i = kMinInt; i < kMaxInt - kInc; i = i + kInc) { | |
225 byte code[] = {WASM_I64V((static_cast<int64_t>(i) << 32) | i)}; | |
226 EXPECT_VERIFIES_C(l_l, code); | |
227 } | |
228 } | |
229 | |
230 TEST_F(AstDecoderTest, Float32Const) { | |
231 byte code[] = {kExprF32Const, 0, 0, 0, 0}; | |
232 float* ptr = reinterpret_cast<float*>(code + 1); | |
233 for (int i = 0; i < 30; i++) { | |
234 WriteLittleEndianValue<float>(ptr, i * -7.75f); | |
235 EXPECT_VERIFIES_C(f_ff, code); | |
236 } | |
237 } | |
238 | |
239 TEST_F(AstDecoderTest, Float64Const) { | |
240 byte code[] = {kExprF64Const, 0, 0, 0, 0, 0, 0, 0, 0}; | |
241 double* ptr = reinterpret_cast<double*>(code + 1); | |
242 for (int i = 0; i < 30; i++) { | |
243 WriteLittleEndianValue<double>(ptr, i * 33.45); | |
244 EXPECT_VERIFIES_C(d_dd, code); | |
245 } | |
246 } | |
247 | |
248 TEST_F(AstDecoderTest, Int32Const_off_end) { | |
249 byte code[] = {kExprI32Const, 0xaa, 0xbb, 0xcc, 0x44}; | |
250 | |
251 for (int size = 1; size <= 4; size++) { | |
252 Verify(kError, sigs.i_i(), code, code + size); | |
253 } | |
254 } | |
255 | |
256 TEST_F(AstDecoderTest, GetLocal0_param) { | |
257 EXPECT_VERIFIES_C(i_i, kCodeGetLocal0); | |
258 } | |
259 | |
260 TEST_F(AstDecoderTest, GetLocal0_local) { | |
261 AddLocals(kAstI32, 1); | |
262 EXPECT_VERIFIES_C(i_v, kCodeGetLocal0); | |
263 } | |
264 | |
265 TEST_F(AstDecoderTest, TooManyLocals) { | |
266 AddLocals(kAstI32, 4034986500); | |
267 EXPECT_FAILURE_C(i_v, kCodeGetLocal0); | |
268 } | |
269 | |
270 TEST_F(AstDecoderTest, GetLocal0_param_n) { | |
271 FunctionSig* array[] = {sigs.i_i(), sigs.i_ii(), sigs.i_iii()}; | |
272 | |
273 for (size_t i = 0; i < arraysize(array); i++) { | |
274 EXPECT_VERIFIES_SC(array[i], kCodeGetLocal0); | |
275 } | |
276 } | |
277 | |
278 TEST_F(AstDecoderTest, GetLocalN_local) { | |
279 for (byte i = 1; i < 8; i++) { | |
280 AddLocals(kAstI32, 1); | |
281 for (byte j = 0; j < i; j++) { | |
282 byte code[] = {kExprGetLocal, j}; | |
283 EXPECT_VERIFIES_C(i_v, code); | |
284 } | |
285 } | |
286 } | |
287 | |
288 TEST_F(AstDecoderTest, GetLocal0_fail_no_params) { | |
289 EXPECT_FAILURE_C(i_v, kCodeGetLocal0); | |
290 } | |
291 | |
292 TEST_F(AstDecoderTest, GetLocal1_fail_no_locals) { | |
293 EXPECT_FAILURE_C(i_i, kCodeGetLocal1); | |
294 } | |
295 | |
296 TEST_F(AstDecoderTest, GetLocal_off_end) { | |
297 static const byte code[] = {kExprGetLocal}; | |
298 EXPECT_FAILURE_C(i_i, code); | |
299 } | |
300 | |
301 TEST_F(AstDecoderTest, NumLocalBelowLimit) { | |
302 AddLocals(kAstI32, kMaxNumWasmLocals - 1); | |
303 EXPECT_VERIFIES(v_v, WASM_NOP); | |
304 } | |
305 | |
306 TEST_F(AstDecoderTest, NumLocalAtLimit) { | |
307 AddLocals(kAstI32, kMaxNumWasmLocals); | |
308 EXPECT_VERIFIES(v_v, WASM_NOP); | |
309 } | |
310 | |
311 TEST_F(AstDecoderTest, NumLocalAboveLimit) { | |
312 AddLocals(kAstI32, kMaxNumWasmLocals + 1); | |
313 EXPECT_FAILURE(v_v, WASM_NOP); | |
314 } | |
315 | |
316 TEST_F(AstDecoderTest, GetLocal_varint) { | |
317 const int kMaxLocals = kMaxNumWasmLocals - 1; | |
318 AddLocals(kAstI32, kMaxLocals); | |
319 | |
320 EXPECT_VERIFIES(i_i, kExprGetLocal, U32V_1(66)); | |
321 EXPECT_VERIFIES(i_i, kExprGetLocal, U32V_2(7777)); | |
322 EXPECT_VERIFIES(i_i, kExprGetLocal, U32V_3(8888)); | |
323 EXPECT_VERIFIES(i_i, kExprGetLocal, U32V_4(9999)); | |
324 | |
325 EXPECT_VERIFIES(i_i, kExprGetLocal, U32V_5(kMaxLocals - 1)); | |
326 | |
327 EXPECT_FAILURE(i_i, kExprGetLocal, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); | |
328 | |
329 EXPECT_VERIFIES(i_i, kExprGetLocal, U32V_4(kMaxLocals - 1)); | |
330 EXPECT_VERIFIES(i_i, kExprGetLocal, U32V_4(kMaxLocals)); | |
331 EXPECT_FAILURE(i_i, kExprGetLocal, U32V_4(kMaxLocals + 1)); | |
332 | |
333 EXPECT_FAILURE(i_v, kExprGetLocal, U32V_4(kMaxLocals)); | |
334 EXPECT_FAILURE(i_v, kExprGetLocal, U32V_4(kMaxLocals + 1)); | |
335 } | |
336 | |
337 TEST_F(AstDecoderTest, GetLocal_toomany) { | |
338 AddLocals(kAstI32, kMaxNumWasmLocals - 100); | |
339 AddLocals(kAstI32, 100); | |
340 | |
341 EXPECT_VERIFIES(i_v, kExprGetLocal, U32V_1(66)); | |
342 EXPECT_FAILURE(i_i, kExprGetLocal, U32V_1(66)); | |
343 } | |
344 | |
345 TEST_F(AstDecoderTest, Binops_off_end) { | |
346 byte code1[] = {0}; // [opcode] | |
347 for (size_t i = 0; i < arraysize(kInt32BinopOpcodes); i++) { | |
348 code1[0] = kInt32BinopOpcodes[i]; | |
349 EXPECT_FAILURE_C(i_i, code1); | |
350 } | |
351 | |
352 byte code3[] = {kExprGetLocal, 0, 0}; // [expr] [opcode] | |
353 for (size_t i = 0; i < arraysize(kInt32BinopOpcodes); i++) { | |
354 code3[2] = kInt32BinopOpcodes[i]; | |
355 EXPECT_FAILURE_C(i_i, code3); | |
356 } | |
357 | |
358 byte code4[] = {kExprGetLocal, 0, 0, 0}; // [expr] [opcode] [opcode] | |
359 for (size_t i = 0; i < arraysize(kInt32BinopOpcodes); i++) { | |
360 code4[2] = kInt32BinopOpcodes[i]; | |
361 code4[3] = kInt32BinopOpcodes[i]; | |
362 EXPECT_FAILURE_C(i_i, code4); | |
363 } | |
364 } | |
365 | |
366 TEST_F(AstDecoderTest, BinopsAcrossBlock1) { | |
367 static const byte code[] = {WASM_ZERO, kExprBlock, WASM_ZERO, kExprI32Add, | |
368 kExprEnd}; | |
369 EXPECT_FAILURE_C(i_i, code); | |
370 } | |
371 | |
372 TEST_F(AstDecoderTest, BinopsAcrossBlock2) { | |
373 static const byte code[] = {WASM_ZERO, WASM_ZERO, kExprBlock, kExprI32Add, | |
374 kExprEnd}; | |
375 EXPECT_FAILURE_C(i_i, code); | |
376 } | |
377 | |
378 TEST_F(AstDecoderTest, BinopsAcrossBlock3) { | |
379 static const byte code[] = {WASM_ZERO, WASM_ZERO, kExprIf, kExprI32Add, | |
380 kExprElse, kExprI32Add, kExprEnd}; | |
381 EXPECT_FAILURE_C(i_i, code); | |
382 } | |
383 | |
384 TEST_F(AstDecoderTest, Nop) { | |
385 static const byte code[] = {kExprNop}; | |
386 EXPECT_VERIFIES_C(v_v, code); | |
387 } | |
388 | |
389 TEST_F(AstDecoderTest, SetLocal0_void) { | |
390 EXPECT_FAILURE(i_i, WASM_SET_LOCAL(0, WASM_ZERO)); | |
391 } | |
392 | |
393 TEST_F(AstDecoderTest, SetLocal0_param) { | |
394 EXPECT_FAILURE_C(i_i, kCodeSetLocal0); | |
395 EXPECT_FAILURE_C(f_ff, kCodeSetLocal0); | |
396 EXPECT_FAILURE_C(d_dd, kCodeSetLocal0); | |
397 } | |
398 | |
399 TEST_F(AstDecoderTest, TeeLocal0_param) { | |
400 EXPECT_VERIFIES_C(i_i, kCodeTeeLocal0); | |
401 EXPECT_FAILURE_C(f_ff, kCodeTeeLocal0); | |
402 EXPECT_FAILURE_C(d_dd, kCodeTeeLocal0); | |
403 } | |
404 | |
405 TEST_F(AstDecoderTest, SetLocal0_local) { | |
406 EXPECT_FAILURE_C(i_v, kCodeSetLocal0); | |
407 EXPECT_FAILURE_C(v_v, kCodeSetLocal0); | |
408 AddLocals(kAstI32, 1); | |
409 EXPECT_FAILURE_C(i_v, kCodeSetLocal0); | |
410 EXPECT_VERIFIES_C(v_v, kCodeSetLocal0); | |
411 } | |
412 | |
413 TEST_F(AstDecoderTest, TeeLocal0_local) { | |
414 EXPECT_FAILURE_C(i_v, kCodeTeeLocal0); | |
415 AddLocals(kAstI32, 1); | |
416 EXPECT_VERIFIES_C(i_v, kCodeTeeLocal0); | |
417 } | |
418 | |
419 TEST_F(AstDecoderTest, TeeLocalN_local) { | |
420 for (byte i = 1; i < 8; i++) { | |
421 AddLocals(kAstI32, 1); | |
422 for (byte j = 0; j < i; j++) { | |
423 EXPECT_FAILURE(v_v, WASM_TEE_LOCAL(j, WASM_I8(i))); | |
424 EXPECT_VERIFIES(i_i, WASM_TEE_LOCAL(j, WASM_I8(i))); | |
425 } | |
426 } | |
427 } | |
428 | |
429 TEST_F(AstDecoderTest, BlockN) { | |
430 const int kMaxSize = 200; | |
431 byte buffer[kMaxSize + 3]; | |
432 | |
433 for (int i = 0; i <= kMaxSize; i++) { | |
434 memset(buffer, kExprNop, sizeof(buffer)); | |
435 buffer[0] = kExprBlock; | |
436 buffer[1] = kLocalVoid; | |
437 buffer[i + 2] = kExprEnd; | |
438 Verify(kSuccess, sigs.v_i(), buffer, buffer + i + 3); | |
439 } | |
440 } | |
441 | |
442 #define WASM_EMPTY_BLOCK kExprBlock, kLocalVoid, kExprEnd | |
443 | |
444 TEST_F(AstDecoderTest, Block0) { | |
445 static const byte code[] = {WASM_EMPTY_BLOCK}; | |
446 EXPECT_VERIFIES_C(v_v, code); | |
447 EXPECT_FAILURE_C(i_i, code); | |
448 } | |
449 | |
450 TEST_F(AstDecoderTest, Block0_fallthru1) { | |
451 static const byte code[] = {WASM_BLOCK(WASM_EMPTY_BLOCK)}; | |
452 EXPECT_VERIFIES_C(v_v, code); | |
453 EXPECT_FAILURE_C(i_i, code); | |
454 } | |
455 | |
456 TEST_F(AstDecoderTest, Block0Block0) { | |
457 static const byte code[] = {WASM_EMPTY_BLOCK, WASM_EMPTY_BLOCK}; | |
458 EXPECT_VERIFIES_C(v_v, code); | |
459 EXPECT_FAILURE_C(i_i, code); | |
460 } | |
461 | |
462 TEST_F(AstDecoderTest, Block0_end) { | |
463 EXPECT_VERIFIES(v_v, WASM_EMPTY_BLOCK, kExprEnd); | |
464 } | |
465 | |
466 TEST_F(AstDecoderTest, Block0_end_end) { | |
467 EXPECT_FAILURE(v_v, WASM_EMPTY_BLOCK, kExprEnd, kExprEnd); | |
468 } | |
469 | |
470 TEST_F(AstDecoderTest, Block1) { | |
471 byte code[] = {WASM_BLOCK_I(WASM_GET_LOCAL(0))}; | |
472 EXPECT_VERIFIES_C(i_i, code); | |
473 EXPECT_FAILURE_C(v_i, code); | |
474 EXPECT_FAILURE_C(d_dd, code); | |
475 EXPECT_FAILURE_C(i_f, code); | |
476 EXPECT_FAILURE_C(i_d, code); | |
477 } | |
478 | |
479 TEST_F(AstDecoderTest, Block1_i) { | |
480 byte code[] = {WASM_BLOCK_I(WASM_ZERO)}; | |
481 EXPECT_VERIFIES_C(i_i, code); | |
482 EXPECT_FAILURE_C(f_ff, code); | |
483 EXPECT_FAILURE_C(d_dd, code); | |
484 EXPECT_FAILURE_C(l_ll, code); | |
485 } | |
486 | |
487 TEST_F(AstDecoderTest, Block1_f) { | |
488 byte code[] = {WASM_BLOCK_F(WASM_F32(0))}; | |
489 EXPECT_FAILURE_C(i_i, code); | |
490 EXPECT_VERIFIES_C(f_ff, code); | |
491 EXPECT_FAILURE_C(d_dd, code); | |
492 EXPECT_FAILURE_C(l_ll, code); | |
493 } | |
494 | |
495 TEST_F(AstDecoderTest, Block1_continue) { | |
496 EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_BR(0))); | |
497 } | |
498 | |
499 TEST_F(AstDecoderTest, Block1_br) { | |
500 EXPECT_VERIFIES(v_v, B1(WASM_BR(0))); | |
501 EXPECT_VERIFIES(v_v, B1(WASM_BR(1))); | |
502 EXPECT_FAILURE(v_v, B1(WASM_BR(2))); | |
503 } | |
504 | |
505 TEST_F(AstDecoderTest, Block2_br) { | |
506 EXPECT_VERIFIES(v_v, B2(WASM_NOP, WASM_BR(0))); | |
507 EXPECT_VERIFIES(v_v, B2(WASM_BR(0), WASM_NOP)); | |
508 EXPECT_VERIFIES(v_v, B2(WASM_BR(0), WASM_BR(0))); | |
509 } | |
510 | |
511 TEST_F(AstDecoderTest, Block2) { | |
512 EXPECT_FAILURE(i_i, WASM_BLOCK(WASM_NOP, WASM_NOP)); | |
513 EXPECT_FAILURE(i_i, WASM_BLOCK_I(WASM_NOP, WASM_NOP)); | |
514 EXPECT_VERIFIES(i_i, WASM_BLOCK_I(WASM_NOP, WASM_ZERO)); | |
515 EXPECT_VERIFIES(i_i, WASM_BLOCK_I(WASM_ZERO, WASM_NOP)); | |
516 EXPECT_FAILURE(i_i, WASM_BLOCK_I(WASM_ZERO, WASM_ZERO)); | |
517 } | |
518 | |
519 TEST_F(AstDecoderTest, Block2b) { | |
520 byte code[] = {WASM_BLOCK_I(WASM_SET_LOCAL(0, WASM_ZERO), WASM_ZERO)}; | |
521 EXPECT_VERIFIES_C(i_i, code); | |
522 EXPECT_FAILURE_C(v_v, code); | |
523 EXPECT_FAILURE_C(f_ff, code); | |
524 } | |
525 | |
526 TEST_F(AstDecoderTest, Block2_fallthru) { | |
527 EXPECT_VERIFIES( | |
528 i_i, B2(WASM_SET_LOCAL(0, WASM_ZERO), WASM_SET_LOCAL(0, WASM_ZERO)), | |
529 WASM_I8(23)); | |
530 } | |
531 | |
532 TEST_F(AstDecoderTest, Block3) { | |
533 EXPECT_VERIFIES(i_i, WASM_BLOCK_I(WASM_SET_LOCAL(0, WASM_ZERO), | |
534 WASM_SET_LOCAL(0, WASM_ZERO), WASM_I8(11))); | |
535 } | |
536 | |
537 TEST_F(AstDecoderTest, Block5) { | |
538 EXPECT_FAILURE(v_i, WASM_BLOCK(WASM_ZERO)); | |
539 | |
540 EXPECT_FAILURE(v_i, WASM_BLOCK(WASM_ZERO, WASM_ZERO)); | |
541 | |
542 EXPECT_FAILURE(v_i, WASM_BLOCK(WASM_ZERO, WASM_ZERO, WASM_ZERO)); | |
543 | |
544 EXPECT_FAILURE(v_i, WASM_BLOCK(WASM_ZERO, WASM_ZERO, WASM_ZERO, WASM_ZERO)); | |
545 | |
546 EXPECT_FAILURE( | |
547 v_i, WASM_BLOCK(WASM_ZERO, WASM_ZERO, WASM_ZERO, WASM_ZERO, WASM_ZERO)); | |
548 } | |
549 | |
550 TEST_F(AstDecoderTest, BlockType) { | |
551 EXPECT_VERIFIES(i_i, WASM_BLOCK_I(WASM_GET_LOCAL(0))); | |
552 EXPECT_VERIFIES(l_l, WASM_BLOCK_L(WASM_GET_LOCAL(0))); | |
553 EXPECT_VERIFIES(f_f, WASM_BLOCK_F(WASM_GET_LOCAL(0))); | |
554 EXPECT_VERIFIES(d_d, WASM_BLOCK_D(WASM_GET_LOCAL(0))); | |
555 } | |
556 | |
557 TEST_F(AstDecoderTest, BlockType_fail) { | |
558 EXPECT_FAILURE(i_i, WASM_BLOCK_L(WASM_I64V_1(0))); | |
559 EXPECT_FAILURE(i_i, WASM_BLOCK_F(WASM_F32(0.0))); | |
560 EXPECT_FAILURE(i_i, WASM_BLOCK_D(WASM_F64(1.1))); | |
561 | |
562 EXPECT_FAILURE(l_l, WASM_BLOCK_I(WASM_ZERO)); | |
563 EXPECT_FAILURE(l_l, WASM_BLOCK_F(WASM_F32(0.0))); | |
564 EXPECT_FAILURE(l_l, WASM_BLOCK_D(WASM_F64(1.1))); | |
565 | |
566 EXPECT_FAILURE(f_ff, WASM_BLOCK_I(WASM_ZERO)); | |
567 EXPECT_FAILURE(f_ff, WASM_BLOCK_L(WASM_I64V_1(0))); | |
568 EXPECT_FAILURE(f_ff, WASM_BLOCK_D(WASM_F64(1.1))); | |
569 | |
570 EXPECT_FAILURE(d_dd, WASM_BLOCK_I(WASM_ZERO)); | |
571 EXPECT_FAILURE(d_dd, WASM_BLOCK_L(WASM_I64V_1(0))); | |
572 EXPECT_FAILURE(d_dd, WASM_BLOCK_F(WASM_F32(0.0))); | |
573 } | |
574 | |
575 TEST_F(AstDecoderTest, BlockF32) { | |
576 static const byte code[] = {WASM_BLOCK_F(kExprF32Const, 0, 0, 0, 0)}; | |
577 EXPECT_VERIFIES_C(f_ff, code); | |
578 EXPECT_FAILURE_C(i_i, code); | |
579 EXPECT_FAILURE_C(d_dd, code); | |
580 } | |
581 | |
582 TEST_F(AstDecoderTest, BlockN_off_end) { | |
583 byte code[] = {WASM_BLOCK(kExprNop, kExprNop, kExprNop, kExprNop)}; | |
584 EXPECT_VERIFIES_C(v_v, code); | |
585 for (size_t i = 1; i < arraysize(code); i++) { | |
586 Verify(kError, sigs.v_v(), code, code + i); | |
587 } | |
588 } | |
589 | |
590 TEST_F(AstDecoderTest, Block2_continue) { | |
591 EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_NOP, WASM_BR(0))); | |
592 EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_NOP, WASM_BR(1))); | |
593 EXPECT_FAILURE(v_v, WASM_LOOP(WASM_NOP, WASM_BR(2))); | |
594 } | |
595 | |
596 TEST_F(AstDecoderTest, Block3_continue) { | |
597 EXPECT_VERIFIES(v_v, B1(WASM_LOOP(WASM_NOP, WASM_BR(0)))); | |
598 EXPECT_VERIFIES(v_v, B1(WASM_LOOP(WASM_NOP, WASM_BR(1)))); | |
599 EXPECT_VERIFIES(v_v, B1(WASM_LOOP(WASM_NOP, WASM_BR(2)))); | |
600 EXPECT_FAILURE(v_v, B1(WASM_LOOP(WASM_NOP, WASM_BR(3)))); | |
601 } | |
602 | |
603 TEST_F(AstDecoderTest, NestedBlock_return) { | |
604 EXPECT_VERIFIES(i_i, B1(B1(WASM_RETURN1(WASM_ZERO)))); | |
605 } | |
606 | |
607 TEST_F(AstDecoderTest, BlockBrBinop) { | |
608 EXPECT_VERIFIES( | |
609 i_i, WASM_I32_AND(WASM_BLOCK_I(WASM_BRV(0, WASM_I8(1))), WASM_I8(2))); | |
610 } | |
611 | |
612 TEST_F(AstDecoderTest, If_empty1) { | |
613 EXPECT_VERIFIES(v_v, WASM_ZERO, WASM_IF_OP, kExprEnd); | |
614 } | |
615 | |
616 TEST_F(AstDecoderTest, If_empty2) { | |
617 EXPECT_VERIFIES(v_v, WASM_ZERO, WASM_IF_OP, kExprElse, kExprEnd); | |
618 } | |
619 | |
620 TEST_F(AstDecoderTest, If_empty3) { | |
621 EXPECT_VERIFIES(v_v, WASM_ZERO, WASM_IF_OP, WASM_NOP, kExprElse, kExprEnd); | |
622 EXPECT_FAILURE(v_v, WASM_ZERO, WASM_IF_OP, WASM_ZERO, kExprElse, kExprEnd); | |
623 } | |
624 | |
625 TEST_F(AstDecoderTest, If_empty4) { | |
626 EXPECT_VERIFIES(v_v, WASM_ZERO, WASM_IF_OP, kExprElse, WASM_NOP, kExprEnd); | |
627 EXPECT_FAILURE(v_v, WASM_ZERO, WASM_IF_OP, kExprElse, WASM_ZERO, kExprEnd); | |
628 } | |
629 | |
630 TEST_F(AstDecoderTest, If_empty_stack) { | |
631 byte code[] = {kExprIf}; | |
632 EXPECT_FAILURE_C(v_v, code); | |
633 EXPECT_FAILURE_C(i_i, code); | |
634 } | |
635 | |
636 TEST_F(AstDecoderTest, If_incomplete1) { | |
637 byte code[] = {kExprI8Const, 0, kExprIf}; | |
638 EXPECT_FAILURE_C(v_v, code); | |
639 EXPECT_FAILURE_C(i_i, code); | |
640 } | |
641 | |
642 TEST_F(AstDecoderTest, If_incomplete2) { | |
643 byte code[] = {kExprI8Const, 0, kExprIf, kExprNop}; | |
644 EXPECT_FAILURE_C(v_v, code); | |
645 EXPECT_FAILURE_C(i_i, code); | |
646 } | |
647 | |
648 TEST_F(AstDecoderTest, If_else_else) { | |
649 byte code[] = {kExprI8Const, 0, WASM_IF_OP, kExprElse, kExprElse, kExprEnd}; | |
650 EXPECT_FAILURE_C(v_v, code); | |
651 EXPECT_FAILURE_C(i_i, code); | |
652 } | |
653 | |
654 TEST_F(AstDecoderTest, IfEmpty) { | |
655 EXPECT_VERIFIES(v_i, kExprGetLocal, 0, WASM_IF_OP, kExprEnd); | |
656 } | |
657 | |
658 TEST_F(AstDecoderTest, IfSet) { | |
659 EXPECT_VERIFIES(v_i, | |
660 WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_ZERO))); | |
661 EXPECT_VERIFIES(v_i, WASM_IF_ELSE(WASM_GET_LOCAL(0), | |
662 WASM_SET_LOCAL(0, WASM_ZERO), WASM_NOP)); | |
663 } | |
664 | |
665 TEST_F(AstDecoderTest, IfElseEmpty) { | |
666 EXPECT_VERIFIES(v_i, WASM_GET_LOCAL(0), WASM_IF_OP, kExprElse, kExprEnd); | |
667 EXPECT_VERIFIES(v_i, WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_NOP)); | |
668 } | |
669 | |
670 TEST_F(AstDecoderTest, IfElseUnreachable1) { | |
671 EXPECT_VERIFIES(i_i, WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_UNREACHABLE, | |
672 WASM_GET_LOCAL(0))); | |
673 EXPECT_VERIFIES(i_i, WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), | |
674 WASM_UNREACHABLE)); | |
675 } | |
676 | |
677 TEST_F(AstDecoderTest, IfElseUnreachable2) { | |
678 static const byte code[] = { | |
679 WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_UNREACHABLE, WASM_GET_LOCAL(0))}; | |
680 | |
681 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
682 LocalType types[] = {kAstI32, kLocalTypes[i]}; | |
683 FunctionSig sig(1, 1, types); | |
684 | |
685 if (kLocalTypes[i] == kAstI32) { | |
686 EXPECT_VERIFIES_SC(&sig, code); | |
687 } else { | |
688 EXPECT_FAILURE_SC(&sig, code); | |
689 } | |
690 } | |
691 } | |
692 | |
693 TEST_F(AstDecoderTest, IfBreak) { | |
694 EXPECT_VERIFIES(v_i, WASM_IF(WASM_GET_LOCAL(0), WASM_BR(0))); | |
695 EXPECT_VERIFIES(v_i, WASM_IF(WASM_GET_LOCAL(0), WASM_BR(1))); | |
696 EXPECT_FAILURE(v_i, WASM_IF(WASM_GET_LOCAL(0), WASM_BR(2))); | |
697 } | |
698 | |
699 TEST_F(AstDecoderTest, IfElseBreak) { | |
700 EXPECT_VERIFIES(v_i, WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_BR(0))); | |
701 EXPECT_VERIFIES(v_i, WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_BR(1))); | |
702 EXPECT_FAILURE(v_i, WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_BR(2))); | |
703 } | |
704 | |
705 TEST_F(AstDecoderTest, Block_else) { | |
706 byte code[] = {kExprI8Const, 0, kExprBlock, kExprElse, kExprEnd}; | |
707 EXPECT_FAILURE_C(v_v, code); | |
708 EXPECT_FAILURE_C(i_i, code); | |
709 } | |
710 | |
711 TEST_F(AstDecoderTest, IfNop) { | |
712 EXPECT_VERIFIES(v_i, WASM_IF(WASM_GET_LOCAL(0), WASM_NOP)); | |
713 } | |
714 | |
715 TEST_F(AstDecoderTest, IfNopElseNop) { | |
716 EXPECT_VERIFIES(v_i, WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_NOP)); | |
717 } | |
718 | |
719 TEST_F(AstDecoderTest, If_end_end) { | |
720 static const byte code[] = {kExprGetLocal, 0, WASM_IF_OP, kExprEnd, kExprEnd}; | |
721 EXPECT_VERIFIES_C(v_i, code); | |
722 } | |
723 | |
724 TEST_F(AstDecoderTest, If_end_end_end) { | |
725 static const byte code[] = {kExprGetLocal, 0, WASM_IF_OP, | |
726 kExprEnd, kExprEnd, kExprEnd}; | |
727 EXPECT_FAILURE_C(v_i, code); | |
728 } | |
729 | |
730 TEST_F(AstDecoderTest, If_falloff1) { | |
731 static const byte code[] = {kExprGetLocal, 0, kExprIf}; | |
732 EXPECT_FAILURE_C(v_i, code); | |
733 } | |
734 | |
735 TEST_F(AstDecoderTest, If_falloff2) { | |
736 static const byte code[] = {kExprGetLocal, 0, WASM_IF_OP}; | |
737 EXPECT_FAILURE_C(v_i, code); | |
738 } | |
739 | |
740 TEST_F(AstDecoderTest, IfElse_falloff) { | |
741 static const byte code[] = {kExprGetLocal, 0, WASM_IF_OP, kExprNop, | |
742 kExprElse}; | |
743 EXPECT_FAILURE_C(v_i, code); | |
744 } | |
745 | |
746 TEST_F(AstDecoderTest, IfElseNop) { | |
747 EXPECT_VERIFIES(v_i, WASM_IF_ELSE(WASM_GET_LOCAL(0), | |
748 WASM_SET_LOCAL(0, WASM_ZERO), WASM_NOP)); | |
749 } | |
750 | |
751 TEST_F(AstDecoderTest, IfBlock1) { | |
752 EXPECT_VERIFIES( | |
753 v_i, WASM_IF_ELSE(WASM_GET_LOCAL(0), B1(WASM_SET_LOCAL(0, WASM_ZERO)), | |
754 WASM_NOP)); | |
755 } | |
756 | |
757 TEST_F(AstDecoderTest, IfBlock1b) { | |
758 EXPECT_VERIFIES(v_i, | |
759 WASM_IF(WASM_GET_LOCAL(0), B1(WASM_SET_LOCAL(0, WASM_ZERO)))); | |
760 } | |
761 | |
762 TEST_F(AstDecoderTest, IfBlock2a) { | |
763 EXPECT_VERIFIES(v_i, | |
764 WASM_IF(WASM_GET_LOCAL(0), B2(WASM_SET_LOCAL(0, WASM_ZERO), | |
765 WASM_SET_LOCAL(0, WASM_ZERO)))); | |
766 } | |
767 | |
768 TEST_F(AstDecoderTest, IfBlock2b) { | |
769 EXPECT_VERIFIES( | |
770 v_i, WASM_IF_ELSE(WASM_GET_LOCAL(0), B2(WASM_SET_LOCAL(0, WASM_ZERO), | |
771 WASM_SET_LOCAL(0, WASM_ZERO)), | |
772 WASM_NOP)); | |
773 } | |
774 | |
775 TEST_F(AstDecoderTest, IfElseSet) { | |
776 EXPECT_VERIFIES(v_i, | |
777 WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_ZERO), | |
778 WASM_SET_LOCAL(0, WASM_I8(1)))); | |
779 } | |
780 | |
781 TEST_F(AstDecoderTest, Loop0) { EXPECT_VERIFIES(v_v, WASM_LOOP_OP, kExprEnd); } | |
782 | |
783 TEST_F(AstDecoderTest, Loop1) { | |
784 static const byte code[] = {WASM_LOOP(WASM_SET_LOCAL(0, WASM_ZERO))}; | |
785 EXPECT_VERIFIES_C(v_i, code); | |
786 EXPECT_FAILURE_C(v_v, code); | |
787 EXPECT_FAILURE_C(f_ff, code); | |
788 } | |
789 | |
790 TEST_F(AstDecoderTest, Loop2) { | |
791 EXPECT_VERIFIES(v_i, WASM_LOOP(WASM_SET_LOCAL(0, WASM_ZERO), | |
792 WASM_SET_LOCAL(0, WASM_ZERO))); | |
793 } | |
794 | |
795 TEST_F(AstDecoderTest, Loop1_continue) { | |
796 EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_BR(0))); | |
797 } | |
798 | |
799 TEST_F(AstDecoderTest, Loop1_break) { | |
800 EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_BR(1))); | |
801 } | |
802 | |
803 TEST_F(AstDecoderTest, Loop2_continue) { | |
804 EXPECT_VERIFIES(v_i, WASM_LOOP(WASM_SET_LOCAL(0, WASM_ZERO), WASM_BR(0))); | |
805 } | |
806 | |
807 TEST_F(AstDecoderTest, Loop2_break) { | |
808 EXPECT_VERIFIES(v_i, WASM_LOOP(WASM_SET_LOCAL(0, WASM_ZERO), WASM_BR(1))); | |
809 } | |
810 | |
811 TEST_F(AstDecoderTest, InfiniteLoop) { | |
812 EXPECT_VERIFIES(i_i, WASM_LOOP(WASM_BR(0))); | |
813 EXPECT_VERIFIES(i_i, WASM_LOOP(WASM_BRV(1, WASM_ZERO))); | |
814 } | |
815 | |
816 TEST_F(AstDecoderTest, Loop2_unreachable) { | |
817 EXPECT_VERIFIES(i_i, WASM_LOOP(WASM_BR(0), WASM_NOP)); | |
818 } | |
819 | |
820 TEST_F(AstDecoderTest, LoopType) { | |
821 EXPECT_VERIFIES(i_i, WASM_LOOP_I(WASM_GET_LOCAL(0))); | |
822 EXPECT_VERIFIES(l_l, WASM_LOOP_L(WASM_GET_LOCAL(0))); | |
823 EXPECT_VERIFIES(f_f, WASM_LOOP_F(WASM_GET_LOCAL(0))); | |
824 EXPECT_VERIFIES(d_d, WASM_LOOP_D(WASM_GET_LOCAL(0))); | |
825 } | |
826 | |
827 TEST_F(AstDecoderTest, LoopType_void) { | |
828 EXPECT_FAILURE(v_v, WASM_LOOP_I(WASM_ZERO)); | |
829 EXPECT_FAILURE(v_v, WASM_LOOP_L(WASM_I64V_1(0))); | |
830 EXPECT_FAILURE(v_v, WASM_LOOP_F(WASM_F32(0.0))); | |
831 EXPECT_FAILURE(v_v, WASM_LOOP_D(WASM_F64(1.1))); | |
832 } | |
833 | |
834 TEST_F(AstDecoderTest, LoopType_fail) { | |
835 EXPECT_FAILURE(i_i, WASM_LOOP_L(WASM_I64V_1(0))); | |
836 EXPECT_FAILURE(i_i, WASM_LOOP_F(WASM_F32(0.0))); | |
837 EXPECT_FAILURE(i_i, WASM_LOOP_D(WASM_F64(1.1))); | |
838 | |
839 EXPECT_FAILURE(l_l, WASM_LOOP_I(WASM_ZERO)); | |
840 EXPECT_FAILURE(l_l, WASM_LOOP_F(WASM_F32(0.0))); | |
841 EXPECT_FAILURE(l_l, WASM_LOOP_D(WASM_F64(1.1))); | |
842 | |
843 EXPECT_FAILURE(f_ff, WASM_LOOP_I(WASM_ZERO)); | |
844 EXPECT_FAILURE(f_ff, WASM_LOOP_L(WASM_I64V_1(0))); | |
845 EXPECT_FAILURE(f_ff, WASM_LOOP_D(WASM_F64(1.1))); | |
846 | |
847 EXPECT_FAILURE(d_dd, WASM_LOOP_I(WASM_ZERO)); | |
848 EXPECT_FAILURE(d_dd, WASM_LOOP_L(WASM_I64V_1(0))); | |
849 EXPECT_FAILURE(d_dd, WASM_LOOP_F(WASM_F32(0.0))); | |
850 } | |
851 | |
852 TEST_F(AstDecoderTest, ReturnVoid1) { | |
853 static const byte code[] = {kExprNop}; | |
854 EXPECT_VERIFIES_C(v_v, code); | |
855 EXPECT_FAILURE_C(i_i, code); | |
856 EXPECT_FAILURE_C(i_f, code); | |
857 } | |
858 | |
859 TEST_F(AstDecoderTest, ReturnVoid2) { | |
860 static const byte code[] = {WASM_BLOCK(WASM_BR(0))}; | |
861 EXPECT_VERIFIES_C(v_v, code); | |
862 EXPECT_FAILURE_C(i_i, code); | |
863 EXPECT_FAILURE_C(i_f, code); | |
864 } | |
865 | |
866 TEST_F(AstDecoderTest, ReturnVoid3) { | |
867 EXPECT_FAILURE(v_v, kExprI8Const, 0); | |
868 EXPECT_FAILURE(v_v, kExprI32Const, 0); | |
869 EXPECT_FAILURE(v_v, kExprI64Const, 0); | |
870 EXPECT_FAILURE(v_v, kExprF32Const, 0, 0, 0, 0); | |
871 EXPECT_FAILURE(v_v, kExprF64Const, 0, 0, 0, 0, 0, 0, 0, 0); | |
872 | |
873 EXPECT_FAILURE(v_i, kExprGetLocal, 0); | |
874 } | |
875 | |
876 TEST_F(AstDecoderTest, Unreachable1) { | |
877 EXPECT_VERIFIES(v_v, kExprUnreachable); | |
878 EXPECT_VERIFIES(v_v, kExprUnreachable, kExprUnreachable); | |
879 EXPECT_VERIFIES(v_v, B2(WASM_UNREACHABLE, WASM_ZERO)); | |
880 EXPECT_VERIFIES(v_v, B2(WASM_BR(0), WASM_ZERO)); | |
881 EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_UNREACHABLE, WASM_ZERO)); | |
882 EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_BR(0), WASM_ZERO)); | |
883 } | |
884 | |
885 TEST_F(AstDecoderTest, Unreachable_binop) { | |
886 EXPECT_VERIFIES(i_i, WASM_I32_AND(WASM_ZERO, WASM_UNREACHABLE)); | |
887 EXPECT_VERIFIES(i_i, WASM_I32_AND(WASM_UNREACHABLE, WASM_ZERO)); | |
888 } | |
889 | |
890 TEST_F(AstDecoderTest, Unreachable_select) { | |
891 EXPECT_VERIFIES(i_i, WASM_SELECT(WASM_UNREACHABLE, WASM_ZERO, WASM_ZERO)); | |
892 EXPECT_VERIFIES(i_i, WASM_SELECT(WASM_ZERO, WASM_UNREACHABLE, WASM_ZERO)); | |
893 EXPECT_VERIFIES(i_i, WASM_SELECT(WASM_ZERO, WASM_ZERO, WASM_UNREACHABLE)); | |
894 } | |
895 | |
896 TEST_F(AstDecoderTest, If1) { | |
897 EXPECT_VERIFIES(i_i, | |
898 WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_I8(9), WASM_I8(8))); | |
899 EXPECT_VERIFIES( | |
900 i_i, WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_I8(9), WASM_GET_LOCAL(0))); | |
901 EXPECT_VERIFIES( | |
902 i_i, WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_I8(8))); | |
903 } | |
904 | |
905 TEST_F(AstDecoderTest, If_off_end) { | |
906 static const byte kCode[] = { | |
907 WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_GET_LOCAL(0))}; | |
908 for (size_t len = 3; len < arraysize(kCode); len++) { | |
909 Verify(kError, sigs.i_i(), kCode, kCode + len); | |
910 } | |
911 } | |
912 | |
913 TEST_F(AstDecoderTest, If_type1) { | |
914 // float|double ? 1 : 2 | |
915 static const byte kCode[] = { | |
916 WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_I8(0), WASM_I8(2))}; | |
917 EXPECT_VERIFIES_C(i_i, kCode); | |
918 EXPECT_FAILURE_C(i_f, kCode); | |
919 EXPECT_FAILURE_C(i_d, kCode); | |
920 } | |
921 | |
922 TEST_F(AstDecoderTest, If_type2) { | |
923 // 1 ? float|double : 2 | |
924 static const byte kCode[] = { | |
925 WASM_IF_ELSE_I(WASM_I8(1), WASM_GET_LOCAL(0), WASM_I8(1))}; | |
926 EXPECT_VERIFIES_C(i_i, kCode); | |
927 EXPECT_FAILURE_C(i_f, kCode); | |
928 EXPECT_FAILURE_C(i_d, kCode); | |
929 } | |
930 | |
931 TEST_F(AstDecoderTest, If_type3) { | |
932 // stmt ? 0 : 1 | |
933 static const byte kCode[] = { | |
934 WASM_IF_ELSE_I(WASM_NOP, WASM_I8(0), WASM_I8(1))}; | |
935 EXPECT_FAILURE_C(i_i, kCode); | |
936 EXPECT_FAILURE_C(i_f, kCode); | |
937 EXPECT_FAILURE_C(i_d, kCode); | |
938 } | |
939 | |
940 TEST_F(AstDecoderTest, If_type4) { | |
941 // 0 ? stmt : 1 | |
942 static const byte kCode[] = { | |
943 WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_NOP, WASM_I8(1))}; | |
944 EXPECT_FAILURE_C(i_i, kCode); | |
945 EXPECT_FAILURE_C(i_f, kCode); | |
946 EXPECT_FAILURE_C(i_d, kCode); | |
947 } | |
948 | |
949 TEST_F(AstDecoderTest, If_type5) { | |
950 // 0 ? 1 : stmt | |
951 static const byte kCode[] = {WASM_IF_ELSE_I(WASM_ZERO, WASM_I8(1), WASM_NOP)}; | |
952 EXPECT_FAILURE_C(i_i, kCode); | |
953 EXPECT_FAILURE_C(i_f, kCode); | |
954 EXPECT_FAILURE_C(i_d, kCode); | |
955 } | |
956 | |
957 TEST_F(AstDecoderTest, Int64Local_param) { | |
958 EXPECT_VERIFIES_C(l_l, kCodeGetLocal0); | |
959 } | |
960 | |
961 TEST_F(AstDecoderTest, Int64Locals) { | |
962 for (byte i = 1; i < 8; i++) { | |
963 AddLocals(kAstI64, 1); | |
964 for (byte j = 0; j < i; j++) { | |
965 EXPECT_VERIFIES(l_v, WASM_GET_LOCAL(j)); | |
966 } | |
967 } | |
968 } | |
969 | |
970 TEST_F(AstDecoderTest, Int32Binops) { | |
971 TestBinop(kExprI32Add, sigs.i_ii()); | |
972 TestBinop(kExprI32Sub, sigs.i_ii()); | |
973 TestBinop(kExprI32Mul, sigs.i_ii()); | |
974 TestBinop(kExprI32DivS, sigs.i_ii()); | |
975 TestBinop(kExprI32DivU, sigs.i_ii()); | |
976 TestBinop(kExprI32RemS, sigs.i_ii()); | |
977 TestBinop(kExprI32RemU, sigs.i_ii()); | |
978 TestBinop(kExprI32And, sigs.i_ii()); | |
979 TestBinop(kExprI32Ior, sigs.i_ii()); | |
980 TestBinop(kExprI32Xor, sigs.i_ii()); | |
981 TestBinop(kExprI32Shl, sigs.i_ii()); | |
982 TestBinop(kExprI32ShrU, sigs.i_ii()); | |
983 TestBinop(kExprI32ShrS, sigs.i_ii()); | |
984 TestBinop(kExprI32Eq, sigs.i_ii()); | |
985 TestBinop(kExprI32LtS, sigs.i_ii()); | |
986 TestBinop(kExprI32LeS, sigs.i_ii()); | |
987 TestBinop(kExprI32LtU, sigs.i_ii()); | |
988 TestBinop(kExprI32LeU, sigs.i_ii()); | |
989 } | |
990 | |
991 TEST_F(AstDecoderTest, DoubleBinops) { | |
992 TestBinop(kExprF64Add, sigs.d_dd()); | |
993 TestBinop(kExprF64Sub, sigs.d_dd()); | |
994 TestBinop(kExprF64Mul, sigs.d_dd()); | |
995 TestBinop(kExprF64Div, sigs.d_dd()); | |
996 | |
997 TestBinop(kExprF64Eq, sigs.i_dd()); | |
998 TestBinop(kExprF64Lt, sigs.i_dd()); | |
999 TestBinop(kExprF64Le, sigs.i_dd()); | |
1000 } | |
1001 | |
1002 TEST_F(AstDecoderTest, FloatBinops) { | |
1003 TestBinop(kExprF32Add, sigs.f_ff()); | |
1004 TestBinop(kExprF32Sub, sigs.f_ff()); | |
1005 TestBinop(kExprF32Mul, sigs.f_ff()); | |
1006 TestBinop(kExprF32Div, sigs.f_ff()); | |
1007 | |
1008 TestBinop(kExprF32Eq, sigs.i_ff()); | |
1009 TestBinop(kExprF32Lt, sigs.i_ff()); | |
1010 TestBinop(kExprF32Le, sigs.i_ff()); | |
1011 } | |
1012 | |
1013 TEST_F(AstDecoderTest, TypeConversions) { | |
1014 TestUnop(kExprI32SConvertF32, kAstI32, kAstF32); | |
1015 TestUnop(kExprI32SConvertF64, kAstI32, kAstF64); | |
1016 TestUnop(kExprI32UConvertF32, kAstI32, kAstF32); | |
1017 TestUnop(kExprI32UConvertF64, kAstI32, kAstF64); | |
1018 TestUnop(kExprF64SConvertI32, kAstF64, kAstI32); | |
1019 TestUnop(kExprF64UConvertI32, kAstF64, kAstI32); | |
1020 TestUnop(kExprF64ConvertF32, kAstF64, kAstF32); | |
1021 TestUnop(kExprF32SConvertI32, kAstF32, kAstI32); | |
1022 TestUnop(kExprF32UConvertI32, kAstF32, kAstI32); | |
1023 TestUnop(kExprF32ConvertF64, kAstF32, kAstF64); | |
1024 } | |
1025 | |
1026 TEST_F(AstDecoderTest, MacrosStmt) { | |
1027 EXPECT_VERIFIES(v_i, WASM_SET_LOCAL(0, WASM_I32V_3(87348))); | |
1028 EXPECT_VERIFIES( | |
1029 v_i, WASM_STORE_MEM(MachineType::Int32(), WASM_I8(24), WASM_I8(40))); | |
1030 EXPECT_VERIFIES(v_i, WASM_IF(WASM_GET_LOCAL(0), WASM_NOP)); | |
1031 EXPECT_VERIFIES(v_i, WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_NOP)); | |
1032 EXPECT_VERIFIES(v_v, WASM_NOP); | |
1033 EXPECT_VERIFIES(v_v, B1(WASM_NOP)); | |
1034 EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_NOP)); | |
1035 EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_BR(0))); | |
1036 } | |
1037 | |
1038 TEST_F(AstDecoderTest, MacrosContinue) { | |
1039 EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_CONTINUE(0))); | |
1040 } | |
1041 | |
1042 TEST_F(AstDecoderTest, MacrosVariadic) { | |
1043 EXPECT_VERIFIES(v_v, B2(WASM_NOP, WASM_NOP)); | |
1044 EXPECT_VERIFIES(v_v, B3(WASM_NOP, WASM_NOP, WASM_NOP)); | |
1045 EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_NOP, WASM_NOP)); | |
1046 EXPECT_VERIFIES(v_v, WASM_LOOP(WASM_NOP, WASM_NOP, WASM_NOP)); | |
1047 } | |
1048 | |
1049 TEST_F(AstDecoderTest, MacrosNestedBlocks) { | |
1050 EXPECT_VERIFIES(v_v, B2(WASM_NOP, B2(WASM_NOP, WASM_NOP))); | |
1051 EXPECT_VERIFIES(v_v, B3(WASM_NOP, // -- | |
1052 B2(WASM_NOP, WASM_NOP), // -- | |
1053 B2(WASM_NOP, WASM_NOP))); // -- | |
1054 EXPECT_VERIFIES(v_v, B1(B1(B2(WASM_NOP, WASM_NOP)))); | |
1055 } | |
1056 | |
1057 TEST_F(AstDecoderTest, MultipleReturn) { | |
1058 static LocalType kIntTypes5[] = {kAstI32, kAstI32, kAstI32, kAstI32, kAstI32}; | |
1059 FunctionSig sig_ii_v(2, 0, kIntTypes5); | |
1060 EXPECT_VERIFIES_S(&sig_ii_v, WASM_RETURNN(2, WASM_ZERO, WASM_ONE)); | |
1061 EXPECT_FAILURE_S(&sig_ii_v, WASM_RETURNN(1, WASM_ZERO)); | |
1062 | |
1063 FunctionSig sig_iii_v(3, 0, kIntTypes5); | |
1064 EXPECT_VERIFIES_S(&sig_iii_v, | |
1065 WASM_RETURNN(3, WASM_ZERO, WASM_ONE, WASM_I8(44))); | |
1066 EXPECT_FAILURE_S(&sig_iii_v, WASM_RETURNN(2, WASM_ZERO, WASM_ONE)); | |
1067 } | |
1068 | |
1069 TEST_F(AstDecoderTest, MultipleReturn_fallthru) { | |
1070 static LocalType kIntTypes5[] = {kAstI32, kAstI32, kAstI32, kAstI32, kAstI32}; | |
1071 FunctionSig sig_ii_v(2, 0, kIntTypes5); | |
1072 | |
1073 EXPECT_VERIFIES_S(&sig_ii_v, WASM_ZERO, WASM_ONE); | |
1074 EXPECT_FAILURE_S(&sig_ii_v, WASM_ZERO); | |
1075 | |
1076 FunctionSig sig_iii_v(3, 0, kIntTypes5); | |
1077 EXPECT_VERIFIES_S(&sig_iii_v, WASM_ZERO, WASM_ONE, WASM_I8(44)); | |
1078 EXPECT_FAILURE_S(&sig_iii_v, WASM_ZERO, WASM_ONE); | |
1079 } | |
1080 | |
1081 TEST_F(AstDecoderTest, MacrosInt32) { | |
1082 EXPECT_VERIFIES(i_i, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_I8(12))); | |
1083 EXPECT_VERIFIES(i_i, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(13))); | |
1084 EXPECT_VERIFIES(i_i, WASM_I32_MUL(WASM_GET_LOCAL(0), WASM_I8(14))); | |
1085 EXPECT_VERIFIES(i_i, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I8(15))); | |
1086 EXPECT_VERIFIES(i_i, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_I8(16))); | |
1087 EXPECT_VERIFIES(i_i, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_I8(17))); | |
1088 EXPECT_VERIFIES(i_i, WASM_I32_REMU(WASM_GET_LOCAL(0), WASM_I8(18))); | |
1089 EXPECT_VERIFIES(i_i, WASM_I32_AND(WASM_GET_LOCAL(0), WASM_I8(19))); | |
1090 EXPECT_VERIFIES(i_i, WASM_I32_IOR(WASM_GET_LOCAL(0), WASM_I8(20))); | |
1091 EXPECT_VERIFIES(i_i, WASM_I32_XOR(WASM_GET_LOCAL(0), WASM_I8(21))); | |
1092 EXPECT_VERIFIES(i_i, WASM_I32_SHL(WASM_GET_LOCAL(0), WASM_I8(22))); | |
1093 EXPECT_VERIFIES(i_i, WASM_I32_SHR(WASM_GET_LOCAL(0), WASM_I8(23))); | |
1094 EXPECT_VERIFIES(i_i, WASM_I32_SAR(WASM_GET_LOCAL(0), WASM_I8(24))); | |
1095 EXPECT_VERIFIES(i_i, WASM_I32_ROR(WASM_GET_LOCAL(0), WASM_I8(24))); | |
1096 EXPECT_VERIFIES(i_i, WASM_I32_ROL(WASM_GET_LOCAL(0), WASM_I8(24))); | |
1097 EXPECT_VERIFIES(i_i, WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(25))); | |
1098 EXPECT_VERIFIES(i_i, WASM_I32_NE(WASM_GET_LOCAL(0), WASM_I8(25))); | |
1099 | |
1100 EXPECT_VERIFIES(i_i, WASM_I32_LTS(WASM_GET_LOCAL(0), WASM_I8(26))); | |
1101 EXPECT_VERIFIES(i_i, WASM_I32_LES(WASM_GET_LOCAL(0), WASM_I8(27))); | |
1102 EXPECT_VERIFIES(i_i, WASM_I32_LTU(WASM_GET_LOCAL(0), WASM_I8(28))); | |
1103 EXPECT_VERIFIES(i_i, WASM_I32_LEU(WASM_GET_LOCAL(0), WASM_I8(29))); | |
1104 | |
1105 EXPECT_VERIFIES(i_i, WASM_I32_GTS(WASM_GET_LOCAL(0), WASM_I8(26))); | |
1106 EXPECT_VERIFIES(i_i, WASM_I32_GES(WASM_GET_LOCAL(0), WASM_I8(27))); | |
1107 EXPECT_VERIFIES(i_i, WASM_I32_GTU(WASM_GET_LOCAL(0), WASM_I8(28))); | |
1108 EXPECT_VERIFIES(i_i, WASM_I32_GEU(WASM_GET_LOCAL(0), WASM_I8(29))); | |
1109 } | |
1110 | |
1111 TEST_F(AstDecoderTest, MacrosInt64) { | |
1112 EXPECT_VERIFIES(l_ll, WASM_I64_ADD(WASM_GET_LOCAL(0), WASM_I64V_1(12))); | |
1113 EXPECT_VERIFIES(l_ll, WASM_I64_SUB(WASM_GET_LOCAL(0), WASM_I64V_1(13))); | |
1114 EXPECT_VERIFIES(l_ll, WASM_I64_MUL(WASM_GET_LOCAL(0), WASM_I64V_1(14))); | |
1115 EXPECT_VERIFIES(l_ll, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_I64V_1(15))); | |
1116 EXPECT_VERIFIES(l_ll, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_I64V_1(16))); | |
1117 EXPECT_VERIFIES(l_ll, WASM_I64_REMS(WASM_GET_LOCAL(0), WASM_I64V_1(17))); | |
1118 EXPECT_VERIFIES(l_ll, WASM_I64_REMU(WASM_GET_LOCAL(0), WASM_I64V_1(18))); | |
1119 EXPECT_VERIFIES(l_ll, WASM_I64_AND(WASM_GET_LOCAL(0), WASM_I64V_1(19))); | |
1120 EXPECT_VERIFIES(l_ll, WASM_I64_IOR(WASM_GET_LOCAL(0), WASM_I64V_1(20))); | |
1121 EXPECT_VERIFIES(l_ll, WASM_I64_XOR(WASM_GET_LOCAL(0), WASM_I64V_1(21))); | |
1122 | |
1123 EXPECT_VERIFIES(l_ll, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(22))); | |
1124 EXPECT_VERIFIES(l_ll, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(23))); | |
1125 EXPECT_VERIFIES(l_ll, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(24))); | |
1126 EXPECT_VERIFIES(l_ll, WASM_I64_ROR(WASM_GET_LOCAL(0), WASM_I64V_1(24))); | |
1127 EXPECT_VERIFIES(l_ll, WASM_I64_ROL(WASM_GET_LOCAL(0), WASM_I64V_1(24))); | |
1128 | |
1129 EXPECT_VERIFIES(i_ll, WASM_I64_LTS(WASM_GET_LOCAL(0), WASM_I64V_1(26))); | |
1130 EXPECT_VERIFIES(i_ll, WASM_I64_LES(WASM_GET_LOCAL(0), WASM_I64V_1(27))); | |
1131 EXPECT_VERIFIES(i_ll, WASM_I64_LTU(WASM_GET_LOCAL(0), WASM_I64V_1(28))); | |
1132 EXPECT_VERIFIES(i_ll, WASM_I64_LEU(WASM_GET_LOCAL(0), WASM_I64V_1(29))); | |
1133 | |
1134 EXPECT_VERIFIES(i_ll, WASM_I64_GTS(WASM_GET_LOCAL(0), WASM_I64V_1(26))); | |
1135 EXPECT_VERIFIES(i_ll, WASM_I64_GES(WASM_GET_LOCAL(0), WASM_I64V_1(27))); | |
1136 EXPECT_VERIFIES(i_ll, WASM_I64_GTU(WASM_GET_LOCAL(0), WASM_I64V_1(28))); | |
1137 EXPECT_VERIFIES(i_ll, WASM_I64_GEU(WASM_GET_LOCAL(0), WASM_I64V_1(29))); | |
1138 | |
1139 EXPECT_VERIFIES(i_ll, WASM_I64_EQ(WASM_GET_LOCAL(0), WASM_I64V_1(25))); | |
1140 EXPECT_VERIFIES(i_ll, WASM_I64_NE(WASM_GET_LOCAL(0), WASM_I64V_1(25))); | |
1141 } | |
1142 | |
1143 TEST_F(AstDecoderTest, AllSimpleExpressions) { | |
1144 // Test all simple expressions which are described by a signature. | |
1145 #define DECODE_TEST(name, opcode, sig) \ | |
1146 { \ | |
1147 FunctionSig* sig = WasmOpcodes::Signature(kExpr##name); \ | |
1148 if (sig->parameter_count() == 1) { \ | |
1149 TestUnop(kExpr##name, sig); \ | |
1150 } else { \ | |
1151 TestBinop(kExpr##name, sig); \ | |
1152 } \ | |
1153 } | |
1154 | |
1155 FOREACH_SIMPLE_OPCODE(DECODE_TEST); | |
1156 | |
1157 #undef DECODE_TEST | |
1158 } | |
1159 | |
1160 TEST_F(AstDecoderTest, MemorySize) { | |
1161 byte code[] = {kExprMemorySize, 0}; | |
1162 EXPECT_VERIFIES_C(i_i, code); | |
1163 EXPECT_FAILURE_C(f_ff, code); | |
1164 } | |
1165 | |
1166 TEST_F(AstDecoderTest, LoadMemOffset) { | |
1167 for (int offset = 0; offset < 128; offset += 7) { | |
1168 byte code[] = {kExprI8Const, 0, kExprI32LoadMem, ZERO_ALIGNMENT, | |
1169 static_cast<byte>(offset)}; | |
1170 EXPECT_VERIFIES_C(i_i, code); | |
1171 } | |
1172 } | |
1173 | |
1174 TEST_F(AstDecoderTest, LoadMemAlignment) { | |
1175 struct { | |
1176 WasmOpcode instruction; | |
1177 uint32_t maximum_aligment; | |
1178 } values[] = { | |
1179 {kExprI32LoadMem8U, 0}, // -- | |
1180 {kExprI32LoadMem8S, 0}, // -- | |
1181 {kExprI32LoadMem16U, 1}, // -- | |
1182 {kExprI32LoadMem16S, 1}, // -- | |
1183 {kExprI64LoadMem8U, 0}, // -- | |
1184 {kExprI64LoadMem8S, 0}, // -- | |
1185 {kExprI64LoadMem16U, 1}, // -- | |
1186 {kExprI64LoadMem16S, 1}, // -- | |
1187 {kExprI64LoadMem32U, 2}, // -- | |
1188 {kExprI64LoadMem32S, 2}, // -- | |
1189 {kExprI32LoadMem, 2}, // -- | |
1190 {kExprI64LoadMem, 3}, // -- | |
1191 {kExprF32LoadMem, 2}, // -- | |
1192 {kExprF64LoadMem, 3}, // -- | |
1193 }; | |
1194 | |
1195 for (size_t i = 0; i < arraysize(values); i++) { | |
1196 for (byte alignment = 0; alignment <= 4; alignment++) { | |
1197 byte code[] = {WASM_ZERO, static_cast<byte>(values[i].instruction), | |
1198 alignment, ZERO_OFFSET, WASM_DROP}; | |
1199 if (static_cast<uint32_t>(alignment) <= values[i].maximum_aligment) { | |
1200 EXPECT_VERIFIES_C(v_i, code); | |
1201 } else { | |
1202 EXPECT_FAILURE_C(v_i, code); | |
1203 } | |
1204 } | |
1205 } | |
1206 } | |
1207 | |
1208 TEST_F(AstDecoderTest, StoreMemOffset) { | |
1209 for (int offset = 0; offset < 128; offset += 7) { | |
1210 byte code[] = {WASM_STORE_MEM_OFFSET(MachineType::Int32(), offset, | |
1211 WASM_ZERO, WASM_ZERO)}; | |
1212 EXPECT_VERIFIES_C(v_i, code); | |
1213 } | |
1214 } | |
1215 | |
1216 TEST_F(AstDecoderTest, StoreMemOffset_void) { | |
1217 EXPECT_FAILURE(i_i, WASM_STORE_MEM_OFFSET(MachineType::Int32(), 0, WASM_ZERO, | |
1218 WASM_ZERO)); | |
1219 } | |
1220 | |
1221 #define BYTE0(x) ((x)&0x7F) | |
1222 #define BYTE1(x) ((x >> 7) & 0x7F) | |
1223 #define BYTE2(x) ((x >> 14) & 0x7F) | |
1224 #define BYTE3(x) ((x >> 21) & 0x7F) | |
1225 | |
1226 #define VARINT1(x) BYTE0(x) | |
1227 #define VARINT2(x) BYTE0(x) | 0x80, BYTE1(x) | |
1228 #define VARINT3(x) BYTE0(x) | 0x80, BYTE1(x) | 0x80, BYTE2(x) | |
1229 #define VARINT4(x) BYTE0(x) | 0x80, BYTE1(x) | 0x80, BYTE2(x) | 0x80, BYTE3(x) | |
1230 | |
1231 TEST_F(AstDecoderTest, LoadMemOffset_varint) { | |
1232 EXPECT_VERIFIES(i_i, WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT, | |
1233 VARINT1(0x45)); | |
1234 EXPECT_VERIFIES(i_i, WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT, | |
1235 VARINT2(0x3999)); | |
1236 EXPECT_VERIFIES(i_i, WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT, | |
1237 VARINT3(0x344445)); | |
1238 EXPECT_VERIFIES(i_i, WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT, | |
1239 VARINT4(0x36666667)); | |
1240 } | |
1241 | |
1242 TEST_F(AstDecoderTest, StoreMemOffset_varint) { | |
1243 EXPECT_VERIFIES(v_i, WASM_ZERO, WASM_ZERO, kExprI32StoreMem, ZERO_ALIGNMENT, | |
1244 VARINT1(0x33)); | |
1245 EXPECT_VERIFIES(v_i, WASM_ZERO, WASM_ZERO, kExprI32StoreMem, ZERO_ALIGNMENT, | |
1246 VARINT2(0x1111)); | |
1247 EXPECT_VERIFIES(v_i, WASM_ZERO, WASM_ZERO, kExprI32StoreMem, ZERO_ALIGNMENT, | |
1248 VARINT3(0x222222)); | |
1249 EXPECT_VERIFIES(v_i, WASM_ZERO, WASM_ZERO, kExprI32StoreMem, ZERO_ALIGNMENT, | |
1250 VARINT4(0x44444444)); | |
1251 } | |
1252 | |
1253 TEST_F(AstDecoderTest, AllLoadMemCombinations) { | |
1254 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
1255 LocalType local_type = kLocalTypes[i]; | |
1256 for (size_t j = 0; j < arraysize(machineTypes); j++) { | |
1257 MachineType mem_type = machineTypes[j]; | |
1258 byte code[] = {WASM_LOAD_MEM(mem_type, WASM_ZERO)}; | |
1259 FunctionSig sig(1, 0, &local_type); | |
1260 if (local_type == WasmOpcodes::LocalTypeFor(mem_type)) { | |
1261 EXPECT_VERIFIES_SC(&sig, code); | |
1262 } else { | |
1263 EXPECT_FAILURE_SC(&sig, code); | |
1264 } | |
1265 } | |
1266 } | |
1267 } | |
1268 | |
1269 TEST_F(AstDecoderTest, AllStoreMemCombinations) { | |
1270 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
1271 LocalType local_type = kLocalTypes[i]; | |
1272 for (size_t j = 0; j < arraysize(machineTypes); j++) { | |
1273 MachineType mem_type = machineTypes[j]; | |
1274 byte code[] = {WASM_STORE_MEM(mem_type, WASM_ZERO, WASM_GET_LOCAL(0))}; | |
1275 FunctionSig sig(0, 1, &local_type); | |
1276 if (local_type == WasmOpcodes::LocalTypeFor(mem_type)) { | |
1277 EXPECT_VERIFIES_SC(&sig, code); | |
1278 } else { | |
1279 EXPECT_FAILURE_SC(&sig, code); | |
1280 } | |
1281 } | |
1282 } | |
1283 } | |
1284 | |
1285 namespace { | |
1286 // A helper for tests that require a module environment for functions and | |
1287 // globals. | |
1288 class TestModuleEnv : public ModuleEnv { | |
1289 public: | |
1290 explicit TestModuleEnv(ModuleOrigin origin = kWasmOrigin) | |
1291 : ModuleEnv(&mod, nullptr) { | |
1292 mod.origin = origin; | |
1293 } | |
1294 byte AddGlobal(LocalType type, bool mutability = true) { | |
1295 mod.globals.push_back({type, mutability, WasmInitExpr(), 0, false, false}); | |
1296 CHECK(mod.globals.size() <= 127); | |
1297 return static_cast<byte>(mod.globals.size() - 1); | |
1298 } | |
1299 byte AddSignature(FunctionSig* sig) { | |
1300 mod.signatures.push_back(sig); | |
1301 CHECK(mod.signatures.size() <= 127); | |
1302 return static_cast<byte>(mod.signatures.size() - 1); | |
1303 } | |
1304 byte AddFunction(FunctionSig* sig) { | |
1305 mod.functions.push_back({sig, // sig | |
1306 0, // func_index | |
1307 0, // sig_index | |
1308 0, // name_offset | |
1309 0, // name_length | |
1310 0, // code_start_offset | |
1311 0, // code_end_offset | |
1312 false, // import | |
1313 false}); // export | |
1314 CHECK(mod.functions.size() <= 127); | |
1315 return static_cast<byte>(mod.functions.size() - 1); | |
1316 } | |
1317 byte AddImport(FunctionSig* sig) { | |
1318 byte result = AddFunction(sig); | |
1319 mod.functions[result].imported = true; | |
1320 return result; | |
1321 } | |
1322 | |
1323 void InitializeFunctionTable() { | |
1324 mod.function_tables.push_back( | |
1325 {0, 0, true, std::vector<int32_t>(), false, false, SignatureMap()}); | |
1326 } | |
1327 | |
1328 private: | |
1329 WasmModule mod; | |
1330 }; | |
1331 } // namespace | |
1332 | |
1333 TEST_F(AstDecoderTest, SimpleCalls) { | |
1334 FunctionSig* sig = sigs.i_i(); | |
1335 TestModuleEnv module_env; | |
1336 module = &module_env; | |
1337 | |
1338 module_env.AddFunction(sigs.i_v()); | |
1339 module_env.AddFunction(sigs.i_i()); | |
1340 module_env.AddFunction(sigs.i_ii()); | |
1341 | |
1342 EXPECT_VERIFIES_S(sig, WASM_CALL_FUNCTION0(0)); | |
1343 EXPECT_VERIFIES_S(sig, WASM_CALL_FUNCTION(1, WASM_I8(27))); | |
1344 EXPECT_VERIFIES_S(sig, WASM_CALL_FUNCTION(2, WASM_I8(37), WASM_I8(77))); | |
1345 } | |
1346 | |
1347 TEST_F(AstDecoderTest, CallsWithTooFewArguments) { | |
1348 FunctionSig* sig = sigs.i_i(); | |
1349 TestModuleEnv module_env; | |
1350 module = &module_env; | |
1351 | |
1352 module_env.AddFunction(sigs.i_i()); | |
1353 module_env.AddFunction(sigs.i_ii()); | |
1354 module_env.AddFunction(sigs.f_ff()); | |
1355 | |
1356 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION0(0)); | |
1357 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(1, WASM_ZERO)); | |
1358 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(2, WASM_GET_LOCAL(0))); | |
1359 } | |
1360 | |
1361 TEST_F(AstDecoderTest, CallsWithMismatchedSigs2) { | |
1362 FunctionSig* sig = sigs.i_i(); | |
1363 TestModuleEnv module_env; | |
1364 module = &module_env; | |
1365 | |
1366 module_env.AddFunction(sigs.i_i()); | |
1367 | |
1368 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(0, WASM_I64V_1(17))); | |
1369 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(0, WASM_F32(17.1))); | |
1370 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(0, WASM_F64(17.1))); | |
1371 } | |
1372 | |
1373 TEST_F(AstDecoderTest, CallsWithMismatchedSigs3) { | |
1374 FunctionSig* sig = sigs.i_i(); | |
1375 TestModuleEnv module_env; | |
1376 module = &module_env; | |
1377 | |
1378 module_env.AddFunction(sigs.i_f()); | |
1379 | |
1380 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(0, WASM_I8(17))); | |
1381 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(0, WASM_I64V_1(27))); | |
1382 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(0, WASM_F64(37.2))); | |
1383 | |
1384 module_env.AddFunction(sigs.i_d()); | |
1385 | |
1386 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(1, WASM_I8(16))); | |
1387 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(1, WASM_I64V_1(16))); | |
1388 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(1, WASM_F32(17.6))); | |
1389 } | |
1390 | |
1391 TEST_F(AstDecoderTest, MultiReturn) { | |
1392 FLAG_wasm_mv_prototype = true; | |
1393 LocalType storage[] = {kAstI32, kAstI32}; | |
1394 FunctionSig sig_ii_v(2, 0, storage); | |
1395 FunctionSig sig_v_ii(0, 2, storage); | |
1396 TestModuleEnv module_env; | |
1397 module = &module_env; | |
1398 | |
1399 module_env.AddFunction(&sig_v_ii); | |
1400 module_env.AddFunction(&sig_ii_v); | |
1401 | |
1402 EXPECT_VERIFIES_S(&sig_ii_v, WASM_CALL_FUNCTION0(1)); | |
1403 EXPECT_VERIFIES(v_v, WASM_CALL_FUNCTION0(1), WASM_DROP, WASM_DROP); | |
1404 EXPECT_VERIFIES(v_v, WASM_CALL_FUNCTION0(1), kExprCallFunction, 0); | |
1405 } | |
1406 | |
1407 TEST_F(AstDecoderTest, MultiReturnType) { | |
1408 FLAG_wasm_mv_prototype = true; | |
1409 for (size_t a = 0; a < arraysize(kLocalTypes); a++) { | |
1410 for (size_t b = 0; b < arraysize(kLocalTypes); b++) { | |
1411 for (size_t c = 0; c < arraysize(kLocalTypes); c++) { | |
1412 for (size_t d = 0; d < arraysize(kLocalTypes); d++) { | |
1413 LocalType storage_ab[] = {kLocalTypes[a], kLocalTypes[b]}; | |
1414 FunctionSig sig_ab_v(2, 0, storage_ab); | |
1415 LocalType storage_cd[] = {kLocalTypes[c], kLocalTypes[d]}; | |
1416 FunctionSig sig_cd_v(2, 0, storage_cd); | |
1417 | |
1418 TestModuleEnv module_env; | |
1419 module = &module_env; | |
1420 module_env.AddFunction(&sig_cd_v); | |
1421 | |
1422 EXPECT_VERIFIES_S(&sig_cd_v, WASM_CALL_FUNCTION0(0)); | |
1423 | |
1424 if (a == c && b == d) { | |
1425 EXPECT_VERIFIES_S(&sig_ab_v, WASM_CALL_FUNCTION0(0)); | |
1426 } else { | |
1427 EXPECT_FAILURE_S(&sig_ab_v, WASM_CALL_FUNCTION0(0)); | |
1428 } | |
1429 } | |
1430 } | |
1431 } | |
1432 } | |
1433 } | |
1434 | |
1435 TEST_F(AstDecoderTest, SimpleIndirectCalls) { | |
1436 FunctionSig* sig = sigs.i_i(); | |
1437 TestModuleEnv module_env; | |
1438 module_env.InitializeFunctionTable(); | |
1439 module = &module_env; | |
1440 | |
1441 byte f0 = module_env.AddSignature(sigs.i_v()); | |
1442 byte f1 = module_env.AddSignature(sigs.i_i()); | |
1443 byte f2 = module_env.AddSignature(sigs.i_ii()); | |
1444 | |
1445 EXPECT_VERIFIES_S(sig, WASM_CALL_INDIRECT0(f0, WASM_ZERO)); | |
1446 EXPECT_VERIFIES_S(sig, WASM_CALL_INDIRECT1(f1, WASM_ZERO, WASM_I8(22))); | |
1447 EXPECT_VERIFIES_S( | |
1448 sig, WASM_CALL_INDIRECT2(f2, WASM_ZERO, WASM_I8(32), WASM_I8(72))); | |
1449 } | |
1450 | |
1451 TEST_F(AstDecoderTest, IndirectCallsOutOfBounds) { | |
1452 FunctionSig* sig = sigs.i_i(); | |
1453 TestModuleEnv module_env; | |
1454 module_env.InitializeFunctionTable(); | |
1455 module = &module_env; | |
1456 | |
1457 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT0(0, WASM_ZERO)); | |
1458 module_env.AddSignature(sigs.i_v()); | |
1459 EXPECT_VERIFIES_S(sig, WASM_CALL_INDIRECT0(0, WASM_ZERO)); | |
1460 | |
1461 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT1(1, WASM_ZERO, WASM_I8(22))); | |
1462 module_env.AddSignature(sigs.i_i()); | |
1463 EXPECT_VERIFIES_S(sig, WASM_CALL_INDIRECT1(1, WASM_ZERO, WASM_I8(27))); | |
1464 | |
1465 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT1(2, WASM_ZERO, WASM_I8(27))); | |
1466 } | |
1467 | |
1468 TEST_F(AstDecoderTest, IndirectCallsWithMismatchedSigs3) { | |
1469 FunctionSig* sig = sigs.i_i(); | |
1470 TestModuleEnv module_env; | |
1471 module_env.InitializeFunctionTable(); | |
1472 module = &module_env; | |
1473 | |
1474 byte f0 = module_env.AddFunction(sigs.i_f()); | |
1475 | |
1476 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT1(f0, WASM_ZERO, WASM_I8(17))); | |
1477 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT1(f0, WASM_ZERO, WASM_I64V_1(27))); | |
1478 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT1(f0, WASM_ZERO, WASM_F64(37.2))); | |
1479 | |
1480 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT0(f0, WASM_I8(17))); | |
1481 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT0(f0, WASM_I64V_1(27))); | |
1482 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT0(f0, WASM_F64(37.2))); | |
1483 | |
1484 byte f1 = module_env.AddFunction(sigs.i_d()); | |
1485 | |
1486 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT1(f1, WASM_ZERO, WASM_I8(16))); | |
1487 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT1(f1, WASM_ZERO, WASM_I64V_1(16))); | |
1488 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT1(f1, WASM_ZERO, WASM_F32(17.6))); | |
1489 } | |
1490 | |
1491 TEST_F(AstDecoderTest, IndirectCallsWithoutTableCrash) { | |
1492 FunctionSig* sig = sigs.i_i(); | |
1493 TestModuleEnv module_env; | |
1494 module = &module_env; | |
1495 | |
1496 byte f0 = module_env.AddSignature(sigs.i_v()); | |
1497 byte f1 = module_env.AddSignature(sigs.i_i()); | |
1498 byte f2 = module_env.AddSignature(sigs.i_ii()); | |
1499 | |
1500 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT0(f0, WASM_ZERO)); | |
1501 EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT1(f1, WASM_ZERO, WASM_I8(22))); | |
1502 EXPECT_FAILURE_S( | |
1503 sig, WASM_CALL_INDIRECT2(f2, WASM_ZERO, WASM_I8(32), WASM_I8(72))); | |
1504 } | |
1505 | |
1506 TEST_F(AstDecoderTest, SimpleImportCalls) { | |
1507 FunctionSig* sig = sigs.i_i(); | |
1508 TestModuleEnv module_env; | |
1509 module = &module_env; | |
1510 | |
1511 byte f0 = module_env.AddImport(sigs.i_v()); | |
1512 byte f1 = module_env.AddImport(sigs.i_i()); | |
1513 byte f2 = module_env.AddImport(sigs.i_ii()); | |
1514 | |
1515 EXPECT_VERIFIES_S(sig, WASM_CALL_FUNCTION0(f0)); | |
1516 EXPECT_VERIFIES_S(sig, WASM_CALL_FUNCTION(f1, WASM_I8(22))); | |
1517 EXPECT_VERIFIES_S(sig, WASM_CALL_FUNCTION(f2, WASM_I8(32), WASM_I8(72))); | |
1518 } | |
1519 | |
1520 TEST_F(AstDecoderTest, ImportCallsWithMismatchedSigs3) { | |
1521 FunctionSig* sig = sigs.i_i(); | |
1522 TestModuleEnv module_env; | |
1523 module = &module_env; | |
1524 | |
1525 byte f0 = module_env.AddImport(sigs.i_f()); | |
1526 | |
1527 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION0(f0)); | |
1528 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(f0, WASM_I8(17))); | |
1529 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(f0, WASM_I64V_1(27))); | |
1530 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(f0, WASM_F64(37.2))); | |
1531 | |
1532 byte f1 = module_env.AddImport(sigs.i_d()); | |
1533 | |
1534 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION0(f1)); | |
1535 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(f1, WASM_I8(16))); | |
1536 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(f1, WASM_I64V_1(16))); | |
1537 EXPECT_FAILURE_S(sig, WASM_CALL_FUNCTION(f1, WASM_F32(17.6))); | |
1538 } | |
1539 | |
1540 TEST_F(AstDecoderTest, Int32Globals) { | |
1541 FunctionSig* sig = sigs.i_i(); | |
1542 TestModuleEnv module_env; | |
1543 module = &module_env; | |
1544 | |
1545 module_env.AddGlobal(kAstI32); | |
1546 | |
1547 EXPECT_VERIFIES_S(sig, WASM_GET_GLOBAL(0)); | |
1548 EXPECT_FAILURE_S(sig, WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0))); | |
1549 EXPECT_VERIFIES_S(sig, WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0)), WASM_ZERO); | |
1550 } | |
1551 | |
1552 TEST_F(AstDecoderTest, ImmutableGlobal) { | |
1553 FunctionSig* sig = sigs.v_v(); | |
1554 TestModuleEnv module_env; | |
1555 module = &module_env; | |
1556 | |
1557 uint32_t g0 = module_env.AddGlobal(kAstI32, true); | |
1558 uint32_t g1 = module_env.AddGlobal(kAstI32, false); | |
1559 | |
1560 EXPECT_VERIFIES_S(sig, WASM_SET_GLOBAL(g0, WASM_ZERO)); | |
1561 EXPECT_FAILURE_S(sig, WASM_SET_GLOBAL(g1, WASM_ZERO)); | |
1562 } | |
1563 | |
1564 TEST_F(AstDecoderTest, Int32Globals_fail) { | |
1565 FunctionSig* sig = sigs.i_i(); | |
1566 TestModuleEnv module_env; | |
1567 module = &module_env; | |
1568 | |
1569 module_env.AddGlobal(kAstI64); | |
1570 module_env.AddGlobal(kAstI64); | |
1571 module_env.AddGlobal(kAstF32); | |
1572 module_env.AddGlobal(kAstF64); | |
1573 | |
1574 EXPECT_FAILURE_S(sig, WASM_GET_GLOBAL(0)); | |
1575 EXPECT_FAILURE_S(sig, WASM_GET_GLOBAL(1)); | |
1576 EXPECT_FAILURE_S(sig, WASM_GET_GLOBAL(2)); | |
1577 EXPECT_FAILURE_S(sig, WASM_GET_GLOBAL(3)); | |
1578 | |
1579 EXPECT_FAILURE_S(sig, WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0)), WASM_ZERO); | |
1580 EXPECT_FAILURE_S(sig, WASM_SET_GLOBAL(1, WASM_GET_LOCAL(0)), WASM_ZERO); | |
1581 EXPECT_FAILURE_S(sig, WASM_SET_GLOBAL(2, WASM_GET_LOCAL(0)), WASM_ZERO); | |
1582 EXPECT_FAILURE_S(sig, WASM_SET_GLOBAL(3, WASM_GET_LOCAL(0)), WASM_ZERO); | |
1583 } | |
1584 | |
1585 TEST_F(AstDecoderTest, Int64Globals) { | |
1586 FunctionSig* sig = sigs.l_l(); | |
1587 TestModuleEnv module_env; | |
1588 module = &module_env; | |
1589 | |
1590 module_env.AddGlobal(kAstI64); | |
1591 module_env.AddGlobal(kAstI64); | |
1592 | |
1593 EXPECT_VERIFIES_S(sig, WASM_GET_GLOBAL(0)); | |
1594 EXPECT_VERIFIES_S(sig, WASM_GET_GLOBAL(1)); | |
1595 | |
1596 EXPECT_VERIFIES_S(sig, WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0)), | |
1597 WASM_GET_LOCAL(0)); | |
1598 EXPECT_VERIFIES_S(sig, WASM_SET_GLOBAL(1, WASM_GET_LOCAL(0)), | |
1599 WASM_GET_LOCAL(0)); | |
1600 } | |
1601 | |
1602 TEST_F(AstDecoderTest, Float32Globals) { | |
1603 FunctionSig* sig = sigs.f_ff(); | |
1604 TestModuleEnv module_env; | |
1605 module = &module_env; | |
1606 | |
1607 module_env.AddGlobal(kAstF32); | |
1608 | |
1609 EXPECT_VERIFIES_S(sig, WASM_GET_GLOBAL(0)); | |
1610 EXPECT_VERIFIES_S(sig, WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0)), | |
1611 WASM_GET_LOCAL(0)); | |
1612 } | |
1613 | |
1614 TEST_F(AstDecoderTest, Float64Globals) { | |
1615 FunctionSig* sig = sigs.d_dd(); | |
1616 TestModuleEnv module_env; | |
1617 module = &module_env; | |
1618 | |
1619 module_env.AddGlobal(kAstF64); | |
1620 | |
1621 EXPECT_VERIFIES_S(sig, WASM_GET_GLOBAL(0)); | |
1622 EXPECT_VERIFIES_S(sig, WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0)), | |
1623 WASM_GET_LOCAL(0)); | |
1624 } | |
1625 | |
1626 TEST_F(AstDecoderTest, AllGetGlobalCombinations) { | |
1627 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
1628 LocalType local_type = kLocalTypes[i]; | |
1629 for (size_t j = 0; j < arraysize(kLocalTypes); j++) { | |
1630 LocalType global_type = kLocalTypes[j]; | |
1631 FunctionSig sig(1, 0, &local_type); | |
1632 TestModuleEnv module_env; | |
1633 module = &module_env; | |
1634 module_env.AddGlobal(global_type); | |
1635 if (local_type == global_type) { | |
1636 EXPECT_VERIFIES_S(&sig, WASM_GET_GLOBAL(0)); | |
1637 } else { | |
1638 EXPECT_FAILURE_S(&sig, WASM_GET_GLOBAL(0)); | |
1639 } | |
1640 } | |
1641 } | |
1642 } | |
1643 | |
1644 TEST_F(AstDecoderTest, AllSetGlobalCombinations) { | |
1645 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
1646 LocalType local_type = kLocalTypes[i]; | |
1647 for (size_t j = 0; j < arraysize(kLocalTypes); j++) { | |
1648 LocalType global_type = kLocalTypes[j]; | |
1649 FunctionSig sig(0, 1, &local_type); | |
1650 TestModuleEnv module_env; | |
1651 module = &module_env; | |
1652 module_env.AddGlobal(global_type); | |
1653 if (local_type == global_type) { | |
1654 EXPECT_VERIFIES_S(&sig, WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0))); | |
1655 } else { | |
1656 EXPECT_FAILURE_S(&sig, WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0))); | |
1657 } | |
1658 } | |
1659 } | |
1660 } | |
1661 | |
1662 TEST_F(AstDecoderTest, WasmGrowMemory) { | |
1663 TestModuleEnv module_env; | |
1664 module = &module_env; | |
1665 | |
1666 byte code[] = {WASM_GET_LOCAL(0), kExprGrowMemory, 0}; | |
1667 EXPECT_VERIFIES_C(i_i, code); | |
1668 EXPECT_FAILURE_C(i_d, code); | |
1669 } | |
1670 | |
1671 TEST_F(AstDecoderTest, AsmJsGrowMemory) { | |
1672 TestModuleEnv module_env(kAsmJsOrigin); | |
1673 module = &module_env; | |
1674 | |
1675 byte code[] = {WASM_GET_LOCAL(0), kExprGrowMemory, 0}; | |
1676 EXPECT_FAILURE_C(i_i, code); | |
1677 } | |
1678 | |
1679 TEST_F(AstDecoderTest, AsmJsBinOpsCheckOrigin) { | |
1680 LocalType float32int32float32[] = {kAstF32, kAstI32, kAstF32}; | |
1681 FunctionSig sig_f_if(1, 2, float32int32float32); | |
1682 LocalType float64int32float64[] = {kAstF64, kAstI32, kAstF64}; | |
1683 FunctionSig sig_d_id(1, 2, float64int32float64); | |
1684 struct { | |
1685 WasmOpcode op; | |
1686 FunctionSig* sig; | |
1687 } AsmJsBinOps[] = { | |
1688 {kExprF64Atan2, sigs.d_dd()}, | |
1689 {kExprF64Pow, sigs.d_dd()}, | |
1690 {kExprF64Mod, sigs.d_dd()}, | |
1691 {kExprI32AsmjsDivS, sigs.i_ii()}, | |
1692 {kExprI32AsmjsDivU, sigs.i_ii()}, | |
1693 {kExprI32AsmjsRemS, sigs.i_ii()}, | |
1694 {kExprI32AsmjsRemU, sigs.i_ii()}, | |
1695 {kExprI32AsmjsStoreMem8, sigs.i_ii()}, | |
1696 {kExprI32AsmjsStoreMem16, sigs.i_ii()}, | |
1697 {kExprI32AsmjsStoreMem, sigs.i_ii()}, | |
1698 {kExprF32AsmjsStoreMem, &sig_f_if}, | |
1699 {kExprF64AsmjsStoreMem, &sig_d_id}, | |
1700 }; | |
1701 | |
1702 { | |
1703 TestModuleEnv module_env(kAsmJsOrigin); | |
1704 module = &module_env; | |
1705 for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) { | |
1706 TestBinop(AsmJsBinOps[i].op, AsmJsBinOps[i].sig); | |
1707 } | |
1708 } | |
1709 | |
1710 { | |
1711 TestModuleEnv module_env; | |
1712 module = &module_env; | |
1713 for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) { | |
1714 byte code[] = { | |
1715 WASM_BINOP(AsmJsBinOps[i].op, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}; | |
1716 EXPECT_FAILURE_SC(AsmJsBinOps[i].sig, code); | |
1717 } | |
1718 } | |
1719 } | |
1720 | |
1721 TEST_F(AstDecoderTest, AsmJsUnOpsCheckOrigin) { | |
1722 LocalType float32int32[] = {kAstF32, kAstI32}; | |
1723 FunctionSig sig_f_i(1, 1, float32int32); | |
1724 LocalType float64int32[] = {kAstF64, kAstI32}; | |
1725 FunctionSig sig_d_i(1, 1, float64int32); | |
1726 struct { | |
1727 WasmOpcode op; | |
1728 FunctionSig* sig; | |
1729 } AsmJsUnOps[] = {{kExprF64Acos, sigs.d_d()}, | |
1730 {kExprF64Asin, sigs.d_d()}, | |
1731 {kExprF64Atan, sigs.d_d()}, | |
1732 {kExprF64Cos, sigs.d_d()}, | |
1733 {kExprF64Sin, sigs.d_d()}, | |
1734 {kExprF64Tan, sigs.d_d()}, | |
1735 {kExprF64Exp, sigs.d_d()}, | |
1736 {kExprF64Log, sigs.d_d()}, | |
1737 {kExprI32AsmjsLoadMem8S, sigs.i_i()}, | |
1738 {kExprI32AsmjsLoadMem8U, sigs.i_i()}, | |
1739 {kExprI32AsmjsLoadMem16S, sigs.i_i()}, | |
1740 {kExprI32AsmjsLoadMem16U, sigs.i_i()}, | |
1741 {kExprI32AsmjsLoadMem, sigs.i_i()}, | |
1742 {kExprF32AsmjsLoadMem, &sig_f_i}, | |
1743 {kExprF64AsmjsLoadMem, &sig_d_i}, | |
1744 {kExprI32AsmjsSConvertF32, sigs.i_f()}, | |
1745 {kExprI32AsmjsUConvertF32, sigs.i_f()}, | |
1746 {kExprI32AsmjsSConvertF64, sigs.i_d()}, | |
1747 {kExprI32AsmjsUConvertF64, sigs.i_d()}}; | |
1748 { | |
1749 TestModuleEnv module_env(kAsmJsOrigin); | |
1750 module = &module_env; | |
1751 for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) { | |
1752 TestUnop(AsmJsUnOps[i].op, AsmJsUnOps[i].sig); | |
1753 } | |
1754 } | |
1755 | |
1756 { | |
1757 TestModuleEnv module_env; | |
1758 module = &module_env; | |
1759 for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) { | |
1760 byte code[] = {WASM_UNOP(AsmJsUnOps[i].op, WASM_GET_LOCAL(0))}; | |
1761 EXPECT_FAILURE_SC(AsmJsUnOps[i].sig, code); | |
1762 } | |
1763 } | |
1764 } | |
1765 | |
1766 TEST_F(AstDecoderTest, BreakEnd) { | |
1767 EXPECT_VERIFIES( | |
1768 i_i, WASM_BLOCK_I(WASM_I32_ADD(WASM_BRV(0, WASM_ZERO), WASM_ZERO))); | |
1769 EXPECT_VERIFIES( | |
1770 i_i, WASM_BLOCK_I(WASM_I32_ADD(WASM_ZERO, WASM_BRV(0, WASM_ZERO)))); | |
1771 } | |
1772 | |
1773 TEST_F(AstDecoderTest, BreakIfBinop) { | |
1774 EXPECT_VERIFIES(i_i, WASM_BLOCK_I(WASM_I32_ADD( | |
1775 WASM_BRV_IF(0, WASM_ZERO, WASM_ZERO), WASM_ZERO))); | |
1776 EXPECT_VERIFIES(i_i, WASM_BLOCK_I(WASM_I32_ADD( | |
1777 WASM_ZERO, WASM_BRV_IF(0, WASM_ZERO, WASM_ZERO)))); | |
1778 EXPECT_VERIFIES_S( | |
1779 sigs.f_ff(), | |
1780 WASM_BLOCK_F(WASM_F32_ABS(WASM_BRV_IF(0, WASM_F32(0.0f), WASM_ZERO)))); | |
1781 } | |
1782 | |
1783 TEST_F(AstDecoderTest, BreakIfBinop_fail) { | |
1784 EXPECT_FAILURE_S( | |
1785 sigs.f_ff(), | |
1786 WASM_BLOCK_F(WASM_F32_ABS(WASM_BRV_IF(0, WASM_ZERO, WASM_ZERO)))); | |
1787 EXPECT_FAILURE_S( | |
1788 sigs.i_i(), | |
1789 WASM_BLOCK_I(WASM_F32_ABS(WASM_BRV_IF(0, WASM_F32(0.0f), WASM_ZERO)))); | |
1790 } | |
1791 | |
1792 TEST_F(AstDecoderTest, BreakNesting1) { | |
1793 for (int i = 0; i < 5; i++) { | |
1794 // (block[2] (loop[2] (if (get p) break[N]) (set p 1)) p) | |
1795 byte code[] = {WASM_BLOCK_I( | |
1796 WASM_LOOP(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(i + 1, WASM_ZERO)), | |
1797 WASM_SET_LOCAL(0, WASM_I8(1))), | |
1798 WASM_ZERO)}; | |
1799 if (i < 3) { | |
1800 EXPECT_VERIFIES_C(i_i, code); | |
1801 } else { | |
1802 EXPECT_FAILURE_C(i_i, code); | |
1803 } | |
1804 } | |
1805 } | |
1806 | |
1807 TEST_F(AstDecoderTest, BreakNesting2) { | |
1808 for (int i = 0; i < 7; i++) { | |
1809 byte code[] = {B1(WASM_LOOP(WASM_IF(WASM_ZERO, WASM_BR(i)), WASM_NOP))}; | |
1810 if (i <= 3) { | |
1811 EXPECT_VERIFIES_C(v_v, code); | |
1812 } else { | |
1813 EXPECT_FAILURE_C(v_v, code); | |
1814 } | |
1815 } | |
1816 } | |
1817 | |
1818 TEST_F(AstDecoderTest, BreakNesting3) { | |
1819 for (int i = 0; i < 7; i++) { | |
1820 // (block[1] (loop[1] (block[1] (if 0 break[N]) | |
1821 byte code[] = { | |
1822 WASM_BLOCK(WASM_LOOP(B1(WASM_IF(WASM_ZERO, WASM_BR(i + 1)))))}; | |
1823 if (i < 4) { | |
1824 EXPECT_VERIFIES_C(v_v, code); | |
1825 } else { | |
1826 EXPECT_FAILURE_C(v_v, code); | |
1827 } | |
1828 } | |
1829 } | |
1830 | |
1831 TEST_F(AstDecoderTest, BreaksWithMultipleTypes) { | |
1832 EXPECT_FAILURE(i_i, B2(WASM_BRV_IF_ZERO(0, WASM_I8(7)), WASM_F32(7.7))); | |
1833 | |
1834 EXPECT_FAILURE(i_i, B2(WASM_BRV_IF_ZERO(0, WASM_I8(7)), | |
1835 WASM_BRV_IF_ZERO(0, WASM_F32(7.7)))); | |
1836 EXPECT_FAILURE( | |
1837 i_i, B3(WASM_BRV_IF_ZERO(0, WASM_I8(8)), WASM_BRV_IF_ZERO(0, WASM_I8(0)), | |
1838 WASM_BRV_IF_ZERO(0, WASM_F32(7.7)))); | |
1839 EXPECT_FAILURE(i_i, B3(WASM_BRV_IF_ZERO(0, WASM_I8(9)), | |
1840 WASM_BRV_IF_ZERO(0, WASM_F32(7.7)), | |
1841 WASM_BRV_IF_ZERO(0, WASM_I8(11)))); | |
1842 } | |
1843 | |
1844 TEST_F(AstDecoderTest, BreakNesting_6_levels) { | |
1845 for (int mask = 0; mask < 64; mask++) { | |
1846 for (int i = 0; i < 14; i++) { | |
1847 byte code[] = {WASM_BLOCK(WASM_BLOCK( | |
1848 WASM_BLOCK(WASM_BLOCK(WASM_BLOCK(WASM_BLOCK(WASM_BR(i)))))))}; | |
1849 | |
1850 int depth = 6; | |
1851 int m = mask; | |
1852 for (size_t pos = 0; pos < sizeof(code); pos++) { | |
1853 if (code[pos] != kExprBlock) continue; | |
1854 if (m & 1) { | |
1855 code[pos] = kExprLoop; | |
1856 code[pos + 1] = kLocalVoid; | |
1857 } | |
1858 m >>= 1; | |
1859 } | |
1860 | |
1861 if (i <= depth) { | |
1862 EXPECT_VERIFIES_C(v_v, code); | |
1863 } else { | |
1864 EXPECT_FAILURE_C(v_v, code); | |
1865 } | |
1866 } | |
1867 } | |
1868 } | |
1869 | |
1870 TEST_F(AstDecoderTest, Break_TypeCheck) { | |
1871 FunctionSig* sigarray[] = {sigs.i_i(), sigs.l_l(), sigs.f_ff(), sigs.d_dd()}; | |
1872 for (size_t i = 0; i < arraysize(sigarray); i++) { | |
1873 FunctionSig* sig = sigarray[i]; | |
1874 // unify X and X => OK | |
1875 byte code[] = {WASM_BLOCK_T( | |
1876 sig->GetReturn(), WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_GET_LOCAL(0))), | |
1877 WASM_GET_LOCAL(0))}; | |
1878 EXPECT_VERIFIES_SC(sig, code); | |
1879 } | |
1880 | |
1881 // unify i32 and f32 => fail | |
1882 EXPECT_FAILURE(i_i, WASM_BLOCK_I(WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_ZERO)), | |
1883 WASM_F32(1.2))); | |
1884 | |
1885 // unify f64 and f64 => OK | |
1886 EXPECT_VERIFIES( | |
1887 d_dd, WASM_BLOCK_D(WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_GET_LOCAL(0))), | |
1888 WASM_F64(1.2))); | |
1889 } | |
1890 | |
1891 TEST_F(AstDecoderTest, Break_TypeCheckAll1) { | |
1892 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
1893 for (size_t j = 0; j < arraysize(kLocalTypes); j++) { | |
1894 LocalType storage[] = {kLocalTypes[i], kLocalTypes[i], kLocalTypes[j]}; | |
1895 FunctionSig sig(1, 2, storage); | |
1896 byte code[] = {WASM_BLOCK_T( | |
1897 sig.GetReturn(), WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_GET_LOCAL(0))), | |
1898 WASM_GET_LOCAL(1))}; | |
1899 | |
1900 if (i == j) { | |
1901 EXPECT_VERIFIES_SC(&sig, code); | |
1902 } else { | |
1903 EXPECT_FAILURE_SC(&sig, code); | |
1904 } | |
1905 } | |
1906 } | |
1907 } | |
1908 | |
1909 TEST_F(AstDecoderTest, Break_TypeCheckAll2) { | |
1910 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
1911 for (size_t j = 0; j < arraysize(kLocalTypes); j++) { | |
1912 LocalType storage[] = {kLocalTypes[i], kLocalTypes[i], kLocalTypes[j]}; | |
1913 FunctionSig sig(1, 2, storage); | |
1914 byte code[] = {WASM_IF_ELSE_T(sig.GetReturn(0), WASM_ZERO, | |
1915 WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)), | |
1916 WASM_GET_LOCAL(1))}; | |
1917 | |
1918 if (i == j) { | |
1919 EXPECT_VERIFIES_SC(&sig, code); | |
1920 } else { | |
1921 EXPECT_FAILURE_SC(&sig, code); | |
1922 } | |
1923 } | |
1924 } | |
1925 } | |
1926 | |
1927 TEST_F(AstDecoderTest, Break_TypeCheckAll3) { | |
1928 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
1929 for (size_t j = 0; j < arraysize(kLocalTypes); j++) { | |
1930 LocalType storage[] = {kLocalTypes[i], kLocalTypes[i], kLocalTypes[j]}; | |
1931 FunctionSig sig(1, 2, storage); | |
1932 byte code[] = {WASM_IF_ELSE_T(sig.GetReturn(), WASM_ZERO, | |
1933 WASM_GET_LOCAL(1), | |
1934 WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))}; | |
1935 | |
1936 if (i == j) { | |
1937 EXPECT_VERIFIES_SC(&sig, code); | |
1938 } else { | |
1939 EXPECT_FAILURE_SC(&sig, code); | |
1940 } | |
1941 } | |
1942 } | |
1943 } | |
1944 | |
1945 TEST_F(AstDecoderTest, Break_Unify) { | |
1946 for (int which = 0; which < 2; which++) { | |
1947 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
1948 LocalType type = kLocalTypes[i]; | |
1949 LocalType storage[] = {kAstI32, kAstI32, type}; | |
1950 FunctionSig sig(1, 2, storage); | |
1951 | |
1952 byte code1[] = {WASM_BLOCK_T( | |
1953 type, WASM_IF(WASM_ZERO, WASM_BRV(1, WASM_GET_LOCAL(which))), | |
1954 WASM_GET_LOCAL(which ^ 1))}; | |
1955 | |
1956 if (type == kAstI32) { | |
1957 EXPECT_VERIFIES_SC(&sig, code1); | |
1958 } else { | |
1959 EXPECT_FAILURE_SC(&sig, code1); | |
1960 } | |
1961 } | |
1962 } | |
1963 } | |
1964 | |
1965 TEST_F(AstDecoderTest, BreakIf_cond_type) { | |
1966 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
1967 for (size_t j = 0; j < arraysize(kLocalTypes); j++) { | |
1968 LocalType types[] = {kLocalTypes[i], kLocalTypes[i], kLocalTypes[j]}; | |
1969 FunctionSig sig(1, 2, types); | |
1970 byte code[] = {WASM_BLOCK_T( | |
1971 types[0], WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)))}; | |
1972 | |
1973 if (types[2] == kAstI32) { | |
1974 EXPECT_VERIFIES_SC(&sig, code); | |
1975 } else { | |
1976 EXPECT_FAILURE_SC(&sig, code); | |
1977 } | |
1978 } | |
1979 } | |
1980 } | |
1981 | |
1982 TEST_F(AstDecoderTest, BreakIf_val_type) { | |
1983 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
1984 for (size_t j = 0; j < arraysize(kLocalTypes); j++) { | |
1985 LocalType types[] = {kLocalTypes[i], kLocalTypes[i], kLocalTypes[j], | |
1986 kAstI32}; | |
1987 FunctionSig sig(1, 3, types); | |
1988 byte code[] = {WASM_BLOCK_T( | |
1989 types[1], WASM_BRV_IF(0, WASM_GET_LOCAL(1), WASM_GET_LOCAL(2)), | |
1990 WASM_DROP, WASM_GET_LOCAL(0))}; | |
1991 | |
1992 if (i == j) { | |
1993 EXPECT_VERIFIES_SC(&sig, code); | |
1994 } else { | |
1995 EXPECT_FAILURE_SC(&sig, code); | |
1996 } | |
1997 } | |
1998 } | |
1999 } | |
2000 | |
2001 TEST_F(AstDecoderTest, BreakIf_Unify) { | |
2002 for (int which = 0; which < 2; which++) { | |
2003 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
2004 LocalType type = kLocalTypes[i]; | |
2005 LocalType storage[] = {kAstI32, kAstI32, type}; | |
2006 FunctionSig sig(1, 2, storage); | |
2007 byte code[] = {WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(which)), | |
2008 WASM_DROP, WASM_GET_LOCAL(which ^ 1))}; | |
2009 | |
2010 if (type == kAstI32) { | |
2011 EXPECT_VERIFIES_SC(&sig, code); | |
2012 } else { | |
2013 EXPECT_FAILURE_SC(&sig, code); | |
2014 } | |
2015 } | |
2016 } | |
2017 } | |
2018 | |
2019 TEST_F(AstDecoderTest, BrTable0) { | |
2020 static byte code[] = {kExprBrTable, 0, BR_TARGET(0)}; | |
2021 EXPECT_FAILURE_C(v_v, code); | |
2022 } | |
2023 | |
2024 TEST_F(AstDecoderTest, BrTable0b) { | |
2025 static byte code[] = {kExprI32Const, 11, kExprBrTable, 0, BR_TARGET(0)}; | |
2026 EXPECT_VERIFIES_C(v_v, code); | |
2027 EXPECT_FAILURE_C(i_i, code); | |
2028 } | |
2029 | |
2030 TEST_F(AstDecoderTest, BrTable0c) { | |
2031 static byte code[] = {kExprI32Const, 11, kExprBrTable, 0, BR_TARGET(1)}; | |
2032 EXPECT_FAILURE_C(v_v, code); | |
2033 EXPECT_FAILURE_C(i_i, code); | |
2034 } | |
2035 | |
2036 TEST_F(AstDecoderTest, BrTable1a) { | |
2037 static byte code[] = {B1(WASM_BR_TABLE(WASM_I8(67), 0, BR_TARGET(0)))}; | |
2038 EXPECT_VERIFIES_C(v_v, code); | |
2039 } | |
2040 | |
2041 TEST_F(AstDecoderTest, BrTable1b) { | |
2042 static byte code[] = {B1(WASM_BR_TABLE(WASM_ZERO, 0, BR_TARGET(0)))}; | |
2043 EXPECT_VERIFIES_C(v_v, code); | |
2044 EXPECT_FAILURE_C(i_i, code); | |
2045 EXPECT_FAILURE_C(f_ff, code); | |
2046 EXPECT_FAILURE_C(d_dd, code); | |
2047 } | |
2048 | |
2049 TEST_F(AstDecoderTest, BrTable2a) { | |
2050 static byte code[] = { | |
2051 B1(WASM_BR_TABLE(WASM_I8(67), 1, BR_TARGET(0), BR_TARGET(0)))}; | |
2052 EXPECT_VERIFIES_C(v_v, code); | |
2053 } | |
2054 | |
2055 TEST_F(AstDecoderTest, BrTable2b) { | |
2056 static byte code[] = {WASM_BLOCK( | |
2057 WASM_BLOCK(WASM_BR_TABLE(WASM_I8(67), 1, BR_TARGET(0), BR_TARGET(1))))}; | |
2058 EXPECT_VERIFIES_C(v_v, code); | |
2059 } | |
2060 | |
2061 TEST_F(AstDecoderTest, BrTable_off_end) { | |
2062 static byte code[] = {B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(0)))}; | |
2063 for (size_t len = 1; len < sizeof(code); len++) { | |
2064 Verify(kError, sigs.i_i(), code, code + len); | |
2065 } | |
2066 } | |
2067 | |
2068 TEST_F(AstDecoderTest, BrTable_invalid_br1) { | |
2069 for (int depth = 0; depth < 4; depth++) { | |
2070 byte code[] = {B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(depth)))}; | |
2071 if (depth <= 1) { | |
2072 EXPECT_VERIFIES_C(v_i, code); | |
2073 } else { | |
2074 EXPECT_FAILURE_C(v_i, code); | |
2075 } | |
2076 } | |
2077 } | |
2078 | |
2079 TEST_F(AstDecoderTest, BrTable_invalid_br2) { | |
2080 for (int depth = 0; depth < 7; depth++) { | |
2081 byte code[] = { | |
2082 WASM_LOOP(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(depth)))}; | |
2083 if (depth < 2) { | |
2084 EXPECT_VERIFIES_C(v_i, code); | |
2085 } else { | |
2086 EXPECT_FAILURE_C(v_i, code); | |
2087 } | |
2088 } | |
2089 } | |
2090 | |
2091 TEST_F(AstDecoderTest, Brv1) { | |
2092 EXPECT_VERIFIES(i_i, WASM_BLOCK_I(WASM_BRV(0, WASM_ZERO))); | |
2093 EXPECT_VERIFIES(i_i, WASM_BLOCK_I(WASM_LOOP(WASM_BRV(2, WASM_ZERO)))); | |
2094 } | |
2095 | |
2096 TEST_F(AstDecoderTest, Brv1_type) { | |
2097 EXPECT_VERIFIES(i_ii, WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0)))); | |
2098 EXPECT_VERIFIES(l_ll, WASM_BLOCK_L(WASM_BRV(0, WASM_GET_LOCAL(0)))); | |
2099 EXPECT_VERIFIES(f_ff, WASM_BLOCK_F(WASM_BRV(0, WASM_GET_LOCAL(0)))); | |
2100 EXPECT_VERIFIES(d_dd, WASM_BLOCK_D(WASM_BRV(0, WASM_GET_LOCAL(0)))); | |
2101 } | |
2102 | |
2103 TEST_F(AstDecoderTest, Brv1_type_n) { | |
2104 EXPECT_FAILURE(i_f, WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0)))); | |
2105 EXPECT_FAILURE(i_d, WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0)))); | |
2106 } | |
2107 | |
2108 TEST_F(AstDecoderTest, BrvIf1) { | |
2109 EXPECT_VERIFIES(i_v, WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_ZERO))); | |
2110 } | |
2111 | |
2112 TEST_F(AstDecoderTest, BrvIf1_type) { | |
2113 EXPECT_VERIFIES(i_i, WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))); | |
2114 EXPECT_VERIFIES(l_l, WASM_BLOCK_L(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))); | |
2115 EXPECT_VERIFIES(f_ff, WASM_BLOCK_F(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))); | |
2116 EXPECT_VERIFIES(d_dd, WASM_BLOCK_D(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))); | |
2117 } | |
2118 | |
2119 TEST_F(AstDecoderTest, BrvIf1_type_n) { | |
2120 EXPECT_FAILURE(i_f, WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))); | |
2121 EXPECT_FAILURE(i_d, WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))); | |
2122 } | |
2123 | |
2124 TEST_F(AstDecoderTest, Select) { | |
2125 EXPECT_VERIFIES(i_i, | |
2126 WASM_SELECT(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_ZERO)); | |
2127 EXPECT_VERIFIES(f_ff, WASM_SELECT(WASM_F32(0.0), WASM_F32(0.0), WASM_ZERO)); | |
2128 EXPECT_VERIFIES(d_dd, WASM_SELECT(WASM_F64(0.0), WASM_F64(0.0), WASM_ZERO)); | |
2129 EXPECT_VERIFIES(l_l, WASM_SELECT(WASM_I64V_1(0), WASM_I64V_1(0), WASM_ZERO)); | |
2130 } | |
2131 | |
2132 TEST_F(AstDecoderTest, Select_fail1) { | |
2133 EXPECT_FAILURE( | |
2134 i_i, WASM_SELECT(WASM_F32(0.0), WASM_GET_LOCAL(0), WASM_GET_LOCAL(0))); | |
2135 EXPECT_FAILURE( | |
2136 i_i, WASM_SELECT(WASM_GET_LOCAL(0), WASM_F32(0.0), WASM_GET_LOCAL(0))); | |
2137 EXPECT_FAILURE( | |
2138 i_i, WASM_SELECT(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_F32(0.0))); | |
2139 } | |
2140 | |
2141 TEST_F(AstDecoderTest, Select_fail2) { | |
2142 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
2143 LocalType type = kLocalTypes[i]; | |
2144 if (type == kAstI32) continue; | |
2145 | |
2146 LocalType types[] = {type, kAstI32, type}; | |
2147 FunctionSig sig(1, 2, types); | |
2148 | |
2149 EXPECT_VERIFIES_S(&sig, WASM_SELECT(WASM_GET_LOCAL(1), WASM_GET_LOCAL(1), | |
2150 WASM_GET_LOCAL(0))); | |
2151 | |
2152 EXPECT_FAILURE_S(&sig, WASM_SELECT(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0), | |
2153 WASM_GET_LOCAL(0))); | |
2154 | |
2155 EXPECT_FAILURE_S(&sig, WASM_SELECT(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), | |
2156 WASM_GET_LOCAL(0))); | |
2157 | |
2158 EXPECT_FAILURE_S(&sig, WASM_SELECT(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), | |
2159 WASM_GET_LOCAL(1))); | |
2160 } | |
2161 } | |
2162 | |
2163 TEST_F(AstDecoderTest, Select_TypeCheck) { | |
2164 EXPECT_FAILURE( | |
2165 i_i, WASM_SELECT(WASM_F32(9.9), WASM_GET_LOCAL(0), WASM_GET_LOCAL(0))); | |
2166 | |
2167 EXPECT_FAILURE( | |
2168 i_i, WASM_SELECT(WASM_GET_LOCAL(0), WASM_F64(0.25), WASM_GET_LOCAL(0))); | |
2169 | |
2170 EXPECT_FAILURE(i_i, | |
2171 WASM_SELECT(WASM_F32(9.9), WASM_GET_LOCAL(0), WASM_I64V_1(0))); | |
2172 } | |
2173 | |
2174 TEST_F(AstDecoderTest, Throw) { | |
2175 FLAG_wasm_eh_prototype = true; | |
2176 EXPECT_VERIFIES(v_i, WASM_GET_LOCAL(0), kExprThrow); | |
2177 | |
2178 EXPECT_FAILURE(i_d, WASM_GET_LOCAL(0), kExprThrow, WASM_I32V(0)); | |
2179 EXPECT_FAILURE(i_f, WASM_GET_LOCAL(0), kExprThrow, WASM_I32V(0)); | |
2180 EXPECT_FAILURE(l_l, WASM_GET_LOCAL(0), kExprThrow, WASM_I64V(0)); | |
2181 } | |
2182 | |
2183 #define WASM_TRY_OP kExprTry, kLocalVoid | |
2184 | |
2185 #define WASM_CATCH(local) kExprCatch, static_cast<byte>(local) | |
2186 | |
2187 TEST_F(AstDecoderTest, TryCatch) { | |
2188 FLAG_wasm_eh_prototype = true; | |
2189 EXPECT_VERIFIES(v_i, WASM_TRY_OP, WASM_CATCH(0), kExprEnd); | |
2190 | |
2191 // Missing catch. | |
2192 EXPECT_FAILURE(v_v, WASM_TRY_OP, kExprEnd); | |
2193 | |
2194 // Missing end. | |
2195 EXPECT_FAILURE(v_i, WASM_TRY_OP, WASM_CATCH(0)); | |
2196 | |
2197 // Double catch. | |
2198 EXPECT_FAILURE(v_i, WASM_TRY_OP, WASM_CATCH(0), WASM_CATCH(0), kExprEnd); | |
2199 } | |
2200 | |
2201 TEST_F(AstDecoderTest, MultiValBlock1) { | |
2202 FLAG_wasm_mv_prototype = true; | |
2203 EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(kAstI32, kAstI32, WASM_GET_LOCAL(0), | |
2204 WASM_GET_LOCAL(1)), | |
2205 kExprI32Add); | |
2206 } | |
2207 | |
2208 TEST_F(AstDecoderTest, MultiValBlock2) { | |
2209 FLAG_wasm_mv_prototype = true; | |
2210 EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(kAstI32, kAstI32, WASM_GET_LOCAL(0), | |
2211 WASM_GET_LOCAL(1)), | |
2212 WASM_I32_ADD(WASM_NOP, WASM_NOP)); | |
2213 } | |
2214 | |
2215 TEST_F(AstDecoderTest, MultiValBlockBr1) { | |
2216 FLAG_wasm_mv_prototype = true; | |
2217 EXPECT_FAILURE(i_ii, | |
2218 WASM_BLOCK_TT(kAstI32, kAstI32, WASM_GET_LOCAL(0), WASM_BR(0)), | |
2219 kExprI32Add); | |
2220 EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(kAstI32, kAstI32, WASM_GET_LOCAL(0), | |
2221 WASM_GET_LOCAL(1), WASM_BR(0)), | |
2222 kExprI32Add); | |
2223 } | |
2224 | |
2225 TEST_F(AstDecoderTest, MultiValIf1) { | |
2226 FLAG_wasm_mv_prototype = true; | |
2227 EXPECT_FAILURE( | |
2228 i_ii, WASM_IF_ELSE_TT(kAstI32, kAstI32, WASM_GET_LOCAL(0), | |
2229 WASM_SEQ(WASM_GET_LOCAL(0)), | |
2230 WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))), | |
2231 kExprI32Add); | |
2232 EXPECT_FAILURE(i_ii, | |
2233 WASM_IF_ELSE_TT(kAstI32, kAstI32, WASM_GET_LOCAL(0), | |
2234 WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), | |
2235 WASM_SEQ(WASM_GET_LOCAL(1))), | |
2236 kExprI32Add); | |
2237 EXPECT_VERIFIES( | |
2238 i_ii, WASM_IF_ELSE_TT(kAstI32, kAstI32, WASM_GET_LOCAL(0), | |
2239 WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), | |
2240 WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))), | |
2241 kExprI32Add); | |
2242 } | |
2243 | |
2244 class BranchTableIteratorTest : public TestWithZone { | |
2245 public: | |
2246 BranchTableIteratorTest() : TestWithZone() {} | |
2247 void CheckBrTableSize(const byte* start, const byte* end) { | |
2248 Decoder decoder(start, end); | |
2249 BranchTableOperand operand(&decoder, start); | |
2250 BranchTableIterator iterator(&decoder, operand); | |
2251 EXPECT_EQ(end - start - 1u, iterator.length()); | |
2252 EXPECT_TRUE(decoder.ok()); | |
2253 } | |
2254 void CheckBrTableError(const byte* start, const byte* end) { | |
2255 Decoder decoder(start, end); | |
2256 BranchTableOperand operand(&decoder, start); | |
2257 BranchTableIterator iterator(&decoder, operand); | |
2258 iterator.length(); | |
2259 EXPECT_FALSE(decoder.ok()); | |
2260 } | |
2261 }; | |
2262 | |
2263 #define CHECK_BR_TABLE_LENGTH(...) \ | |
2264 { \ | |
2265 static byte code[] = {kExprBrTable, __VA_ARGS__}; \ | |
2266 CheckBrTableSize(code, code + sizeof(code)); \ | |
2267 } | |
2268 | |
2269 #define CHECK_BR_TABLE_ERROR(...) \ | |
2270 { \ | |
2271 static byte code[] = {kExprBrTable, __VA_ARGS__}; \ | |
2272 CheckBrTableError(code, code + sizeof(code)); \ | |
2273 } | |
2274 | |
2275 TEST_F(BranchTableIteratorTest, count0) { | |
2276 CHECK_BR_TABLE_LENGTH(0, U32V_1(1)); | |
2277 CHECK_BR_TABLE_LENGTH(0, U32V_2(200)); | |
2278 CHECK_BR_TABLE_LENGTH(0, U32V_3(30000)); | |
2279 CHECK_BR_TABLE_LENGTH(0, U32V_4(400000)); | |
2280 | |
2281 CHECK_BR_TABLE_LENGTH(0, U32V_1(2)); | |
2282 CHECK_BR_TABLE_LENGTH(0, U32V_2(300)); | |
2283 CHECK_BR_TABLE_LENGTH(0, U32V_3(40000)); | |
2284 CHECK_BR_TABLE_LENGTH(0, U32V_4(500000)); | |
2285 } | |
2286 | |
2287 TEST_F(BranchTableIteratorTest, count1) { | |
2288 CHECK_BR_TABLE_LENGTH(1, U32V_1(1), U32V_1(6)); | |
2289 CHECK_BR_TABLE_LENGTH(1, U32V_2(200), U32V_1(8)); | |
2290 CHECK_BR_TABLE_LENGTH(1, U32V_3(30000), U32V_1(9)); | |
2291 CHECK_BR_TABLE_LENGTH(1, U32V_4(400000), U32V_1(11)); | |
2292 | |
2293 CHECK_BR_TABLE_LENGTH(1, U32V_1(2), U32V_2(6)); | |
2294 CHECK_BR_TABLE_LENGTH(1, U32V_2(300), U32V_2(7)); | |
2295 CHECK_BR_TABLE_LENGTH(1, U32V_3(40000), U32V_2(8)); | |
2296 CHECK_BR_TABLE_LENGTH(1, U32V_4(500000), U32V_2(9)); | |
2297 } | |
2298 | |
2299 TEST_F(BranchTableIteratorTest, error0) { | |
2300 CHECK_BR_TABLE_ERROR(0); | |
2301 CHECK_BR_TABLE_ERROR(1, U32V_1(33)); | |
2302 } | |
2303 | |
2304 class WasmOpcodeLengthTest : public TestWithZone { | |
2305 public: | |
2306 WasmOpcodeLengthTest() : TestWithZone() {} | |
2307 }; | |
2308 | |
2309 #define EXPECT_LENGTH(expected, opcode) \ | |
2310 { \ | |
2311 static const byte code[] = {opcode, 0, 0, 0, 0, 0, 0, 0, 0}; \ | |
2312 EXPECT_EQ(static_cast<unsigned>(expected), \ | |
2313 OpcodeLength(code, code + sizeof(code))); \ | |
2314 } | |
2315 | |
2316 #define EXPECT_LENGTH_N(expected, ...) \ | |
2317 { \ | |
2318 static const byte code[] = {__VA_ARGS__}; \ | |
2319 EXPECT_EQ(static_cast<unsigned>(expected), \ | |
2320 OpcodeLength(code, code + sizeof(code))); \ | |
2321 } | |
2322 | |
2323 TEST_F(WasmOpcodeLengthTest, Statements) { | |
2324 EXPECT_LENGTH(1, kExprNop); | |
2325 EXPECT_LENGTH(2, kExprBlock); | |
2326 EXPECT_LENGTH(2, kExprLoop); | |
2327 EXPECT_LENGTH(2, kExprIf); | |
2328 EXPECT_LENGTH(1, kExprElse); | |
2329 EXPECT_LENGTH(1, kExprEnd); | |
2330 EXPECT_LENGTH(1, kExprSelect); | |
2331 EXPECT_LENGTH(2, kExprBr); | |
2332 EXPECT_LENGTH(2, kExprBrIf); | |
2333 EXPECT_LENGTH(1, kExprThrow); | |
2334 EXPECT_LENGTH(2, kExprTry); | |
2335 EXPECT_LENGTH(2, kExprCatch); | |
2336 } | |
2337 | |
2338 TEST_F(WasmOpcodeLengthTest, MiscExpressions) { | |
2339 EXPECT_LENGTH(2, kExprI8Const); | |
2340 EXPECT_LENGTH(5, kExprF32Const); | |
2341 EXPECT_LENGTH(9, kExprF64Const); | |
2342 EXPECT_LENGTH(2, kExprGetLocal); | |
2343 EXPECT_LENGTH(2, kExprSetLocal); | |
2344 EXPECT_LENGTH(2, kExprGetGlobal); | |
2345 EXPECT_LENGTH(2, kExprSetGlobal); | |
2346 EXPECT_LENGTH(2, kExprCallFunction); | |
2347 EXPECT_LENGTH(3, kExprCallIndirect); | |
2348 } | |
2349 | |
2350 TEST_F(WasmOpcodeLengthTest, I32Const) { | |
2351 EXPECT_LENGTH_N(2, kExprI32Const, U32V_1(1)); | |
2352 EXPECT_LENGTH_N(3, kExprI32Const, U32V_2(999)); | |
2353 EXPECT_LENGTH_N(4, kExprI32Const, U32V_3(9999)); | |
2354 EXPECT_LENGTH_N(5, kExprI32Const, U32V_4(999999)); | |
2355 EXPECT_LENGTH_N(6, kExprI32Const, U32V_5(99999999)); | |
2356 } | |
2357 | |
2358 TEST_F(WasmOpcodeLengthTest, I64Const) { | |
2359 EXPECT_LENGTH_N(2, kExprI64Const, U32V_1(1)); | |
2360 EXPECT_LENGTH_N(3, kExprI64Const, U32V_2(99)); | |
2361 EXPECT_LENGTH_N(4, kExprI64Const, U32V_3(9999)); | |
2362 EXPECT_LENGTH_N(5, kExprI64Const, U32V_4(99999)); | |
2363 EXPECT_LENGTH_N(6, kExprI64Const, U32V_5(9999999)); | |
2364 EXPECT_LENGTH_N(7, WASM_I64V_6(777777)); | |
2365 EXPECT_LENGTH_N(8, WASM_I64V_7(7777777)); | |
2366 EXPECT_LENGTH_N(9, WASM_I64V_8(77777777)); | |
2367 EXPECT_LENGTH_N(10, WASM_I64V_9(777777777)); | |
2368 } | |
2369 | |
2370 TEST_F(WasmOpcodeLengthTest, VariableLength) { | |
2371 EXPECT_LENGTH_N(2, kExprGetGlobal, U32V_1(1)); | |
2372 EXPECT_LENGTH_N(3, kExprGetGlobal, U32V_2(33)); | |
2373 EXPECT_LENGTH_N(4, kExprGetGlobal, U32V_3(44)); | |
2374 EXPECT_LENGTH_N(5, kExprGetGlobal, U32V_4(66)); | |
2375 EXPECT_LENGTH_N(6, kExprGetGlobal, U32V_5(77)); | |
2376 } | |
2377 | |
2378 TEST_F(WasmOpcodeLengthTest, LoadsAndStores) { | |
2379 EXPECT_LENGTH(3, kExprI32LoadMem8S); | |
2380 EXPECT_LENGTH(3, kExprI32LoadMem8U); | |
2381 EXPECT_LENGTH(3, kExprI32LoadMem16S); | |
2382 EXPECT_LENGTH(3, kExprI32LoadMem16U); | |
2383 EXPECT_LENGTH(3, kExprI32LoadMem); | |
2384 EXPECT_LENGTH(3, kExprI64LoadMem8S); | |
2385 EXPECT_LENGTH(3, kExprI64LoadMem8U); | |
2386 EXPECT_LENGTH(3, kExprI64LoadMem16S); | |
2387 EXPECT_LENGTH(3, kExprI64LoadMem16U); | |
2388 EXPECT_LENGTH(3, kExprI64LoadMem32S); | |
2389 EXPECT_LENGTH(3, kExprI64LoadMem32U); | |
2390 EXPECT_LENGTH(3, kExprI64LoadMem); | |
2391 EXPECT_LENGTH(3, kExprF32LoadMem); | |
2392 EXPECT_LENGTH(3, kExprF64LoadMem); | |
2393 | |
2394 EXPECT_LENGTH(3, kExprI32StoreMem8); | |
2395 EXPECT_LENGTH(3, kExprI32StoreMem16); | |
2396 EXPECT_LENGTH(3, kExprI32StoreMem); | |
2397 EXPECT_LENGTH(3, kExprI64StoreMem8); | |
2398 EXPECT_LENGTH(3, kExprI64StoreMem16); | |
2399 EXPECT_LENGTH(3, kExprI64StoreMem32); | |
2400 EXPECT_LENGTH(3, kExprI64StoreMem); | |
2401 EXPECT_LENGTH(3, kExprF32StoreMem); | |
2402 EXPECT_LENGTH(3, kExprF64StoreMem); | |
2403 } | |
2404 | |
2405 TEST_F(WasmOpcodeLengthTest, MiscMemExpressions) { | |
2406 EXPECT_LENGTH(2, kExprMemorySize); | |
2407 EXPECT_LENGTH(2, kExprGrowMemory); | |
2408 } | |
2409 | |
2410 TEST_F(WasmOpcodeLengthTest, SimpleExpressions) { | |
2411 EXPECT_LENGTH(1, kExprI32Add); | |
2412 EXPECT_LENGTH(1, kExprI32Sub); | |
2413 EXPECT_LENGTH(1, kExprI32Mul); | |
2414 EXPECT_LENGTH(1, kExprI32DivS); | |
2415 EXPECT_LENGTH(1, kExprI32DivU); | |
2416 EXPECT_LENGTH(1, kExprI32RemS); | |
2417 EXPECT_LENGTH(1, kExprI32RemU); | |
2418 EXPECT_LENGTH(1, kExprI32And); | |
2419 EXPECT_LENGTH(1, kExprI32Ior); | |
2420 EXPECT_LENGTH(1, kExprI32Xor); | |
2421 EXPECT_LENGTH(1, kExprI32Shl); | |
2422 EXPECT_LENGTH(1, kExprI32ShrU); | |
2423 EXPECT_LENGTH(1, kExprI32ShrS); | |
2424 EXPECT_LENGTH(1, kExprI32Eq); | |
2425 EXPECT_LENGTH(1, kExprI32Ne); | |
2426 EXPECT_LENGTH(1, kExprI32LtS); | |
2427 EXPECT_LENGTH(1, kExprI32LeS); | |
2428 EXPECT_LENGTH(1, kExprI32LtU); | |
2429 EXPECT_LENGTH(1, kExprI32LeU); | |
2430 EXPECT_LENGTH(1, kExprI32GtS); | |
2431 EXPECT_LENGTH(1, kExprI32GeS); | |
2432 EXPECT_LENGTH(1, kExprI32GtU); | |
2433 EXPECT_LENGTH(1, kExprI32GeU); | |
2434 EXPECT_LENGTH(1, kExprI32Clz); | |
2435 EXPECT_LENGTH(1, kExprI32Ctz); | |
2436 EXPECT_LENGTH(1, kExprI32Popcnt); | |
2437 EXPECT_LENGTH(1, kExprI32Eqz); | |
2438 EXPECT_LENGTH(1, kExprI64Add); | |
2439 EXPECT_LENGTH(1, kExprI64Sub); | |
2440 EXPECT_LENGTH(1, kExprI64Mul); | |
2441 EXPECT_LENGTH(1, kExprI64DivS); | |
2442 EXPECT_LENGTH(1, kExprI64DivU); | |
2443 EXPECT_LENGTH(1, kExprI64RemS); | |
2444 EXPECT_LENGTH(1, kExprI64RemU); | |
2445 EXPECT_LENGTH(1, kExprI64And); | |
2446 EXPECT_LENGTH(1, kExprI64Ior); | |
2447 EXPECT_LENGTH(1, kExprI64Xor); | |
2448 EXPECT_LENGTH(1, kExprI64Shl); | |
2449 EXPECT_LENGTH(1, kExprI64ShrU); | |
2450 EXPECT_LENGTH(1, kExprI64ShrS); | |
2451 EXPECT_LENGTH(1, kExprI64Eq); | |
2452 EXPECT_LENGTH(1, kExprI64Ne); | |
2453 EXPECT_LENGTH(1, kExprI64LtS); | |
2454 EXPECT_LENGTH(1, kExprI64LeS); | |
2455 EXPECT_LENGTH(1, kExprI64LtU); | |
2456 EXPECT_LENGTH(1, kExprI64LeU); | |
2457 EXPECT_LENGTH(1, kExprI64GtS); | |
2458 EXPECT_LENGTH(1, kExprI64GeS); | |
2459 EXPECT_LENGTH(1, kExprI64GtU); | |
2460 EXPECT_LENGTH(1, kExprI64GeU); | |
2461 EXPECT_LENGTH(1, kExprI64Clz); | |
2462 EXPECT_LENGTH(1, kExprI64Ctz); | |
2463 EXPECT_LENGTH(1, kExprI64Popcnt); | |
2464 EXPECT_LENGTH(1, kExprF32Add); | |
2465 EXPECT_LENGTH(1, kExprF32Sub); | |
2466 EXPECT_LENGTH(1, kExprF32Mul); | |
2467 EXPECT_LENGTH(1, kExprF32Div); | |
2468 EXPECT_LENGTH(1, kExprF32Min); | |
2469 EXPECT_LENGTH(1, kExprF32Max); | |
2470 EXPECT_LENGTH(1, kExprF32Abs); | |
2471 EXPECT_LENGTH(1, kExprF32Neg); | |
2472 EXPECT_LENGTH(1, kExprF32CopySign); | |
2473 EXPECT_LENGTH(1, kExprF32Ceil); | |
2474 EXPECT_LENGTH(1, kExprF32Floor); | |
2475 EXPECT_LENGTH(1, kExprF32Trunc); | |
2476 EXPECT_LENGTH(1, kExprF32NearestInt); | |
2477 EXPECT_LENGTH(1, kExprF32Sqrt); | |
2478 EXPECT_LENGTH(1, kExprF32Eq); | |
2479 EXPECT_LENGTH(1, kExprF32Ne); | |
2480 EXPECT_LENGTH(1, kExprF32Lt); | |
2481 EXPECT_LENGTH(1, kExprF32Le); | |
2482 EXPECT_LENGTH(1, kExprF32Gt); | |
2483 EXPECT_LENGTH(1, kExprF32Ge); | |
2484 EXPECT_LENGTH(1, kExprF64Add); | |
2485 EXPECT_LENGTH(1, kExprF64Sub); | |
2486 EXPECT_LENGTH(1, kExprF64Mul); | |
2487 EXPECT_LENGTH(1, kExprF64Div); | |
2488 EXPECT_LENGTH(1, kExprF64Min); | |
2489 EXPECT_LENGTH(1, kExprF64Max); | |
2490 EXPECT_LENGTH(1, kExprF64Abs); | |
2491 EXPECT_LENGTH(1, kExprF64Neg); | |
2492 EXPECT_LENGTH(1, kExprF64CopySign); | |
2493 EXPECT_LENGTH(1, kExprF64Ceil); | |
2494 EXPECT_LENGTH(1, kExprF64Floor); | |
2495 EXPECT_LENGTH(1, kExprF64Trunc); | |
2496 EXPECT_LENGTH(1, kExprF64NearestInt); | |
2497 EXPECT_LENGTH(1, kExprF64Sqrt); | |
2498 EXPECT_LENGTH(1, kExprF64Eq); | |
2499 EXPECT_LENGTH(1, kExprF64Ne); | |
2500 EXPECT_LENGTH(1, kExprF64Lt); | |
2501 EXPECT_LENGTH(1, kExprF64Le); | |
2502 EXPECT_LENGTH(1, kExprF64Gt); | |
2503 EXPECT_LENGTH(1, kExprF64Ge); | |
2504 EXPECT_LENGTH(1, kExprI32SConvertF32); | |
2505 EXPECT_LENGTH(1, kExprI32SConvertF64); | |
2506 EXPECT_LENGTH(1, kExprI32UConvertF32); | |
2507 EXPECT_LENGTH(1, kExprI32UConvertF64); | |
2508 EXPECT_LENGTH(1, kExprI32ConvertI64); | |
2509 EXPECT_LENGTH(1, kExprI64SConvertF32); | |
2510 EXPECT_LENGTH(1, kExprI64SConvertF64); | |
2511 EXPECT_LENGTH(1, kExprI64UConvertF32); | |
2512 EXPECT_LENGTH(1, kExprI64UConvertF64); | |
2513 EXPECT_LENGTH(1, kExprI64SConvertI32); | |
2514 EXPECT_LENGTH(1, kExprI64UConvertI32); | |
2515 EXPECT_LENGTH(1, kExprF32SConvertI32); | |
2516 EXPECT_LENGTH(1, kExprF32UConvertI32); | |
2517 EXPECT_LENGTH(1, kExprF32SConvertI64); | |
2518 EXPECT_LENGTH(1, kExprF32UConvertI64); | |
2519 EXPECT_LENGTH(1, kExprF32ConvertF64); | |
2520 EXPECT_LENGTH(1, kExprF32ReinterpretI32); | |
2521 EXPECT_LENGTH(1, kExprF64SConvertI32); | |
2522 EXPECT_LENGTH(1, kExprF64UConvertI32); | |
2523 EXPECT_LENGTH(1, kExprF64SConvertI64); | |
2524 EXPECT_LENGTH(1, kExprF64UConvertI64); | |
2525 EXPECT_LENGTH(1, kExprF64ConvertF32); | |
2526 EXPECT_LENGTH(1, kExprF64ReinterpretI64); | |
2527 EXPECT_LENGTH(1, kExprI32ReinterpretF32); | |
2528 EXPECT_LENGTH(1, kExprI64ReinterpretF64); | |
2529 } | |
2530 | |
2531 TEST_F(WasmOpcodeLengthTest, SimdExpressions) { | |
2532 #define TEST_SIMD(name, opcode, sig) \ | |
2533 EXPECT_LENGTH_N(2, kSimdPrefix, static_cast<byte>(kExpr##name & 0xff)); | |
2534 FOREACH_SIMD_0_OPERAND_OPCODE(TEST_SIMD) | |
2535 #undef TEST_SIMD | |
2536 #define TEST_SIMD(name, opcode, sig) \ | |
2537 EXPECT_LENGTH_N(3, kSimdPrefix, static_cast<byte>(kExpr##name & 0xff)); | |
2538 FOREACH_SIMD_1_OPERAND_OPCODE(TEST_SIMD) | |
2539 #undef TEST_SIMD | |
2540 // test for bad simd opcode | |
2541 EXPECT_LENGTH_N(2, kSimdPrefix, 0xff); | |
2542 } | |
2543 | |
2544 typedef ZoneVector<LocalType> LocalTypeMap; | |
2545 | |
2546 class LocalDeclDecoderTest : public TestWithZone { | |
2547 public: | |
2548 v8::internal::AccountingAllocator allocator; | |
2549 | |
2550 size_t ExpectRun(LocalTypeMap map, size_t pos, LocalType expected, | |
2551 size_t count) { | |
2552 for (size_t i = 0; i < count; i++) { | |
2553 EXPECT_EQ(expected, map[pos++]); | |
2554 } | |
2555 return pos; | |
2556 } | |
2557 | |
2558 LocalTypeMap Expand(AstLocalDecls& decls) { | |
2559 ZoneVector<LocalType> map(zone()); | |
2560 for (auto p : decls.local_types) { | |
2561 map.insert(map.end(), p.second, p.first); | |
2562 } | |
2563 return map; | |
2564 } | |
2565 }; | |
2566 | |
2567 TEST_F(LocalDeclDecoderTest, EmptyLocals) { | |
2568 AstLocalDecls decls(zone()); | |
2569 bool result = DecodeLocalDecls(decls, nullptr, nullptr); | |
2570 EXPECT_FALSE(result); | |
2571 } | |
2572 | |
2573 TEST_F(LocalDeclDecoderTest, NoLocals) { | |
2574 static const byte data[] = {0}; | |
2575 AstLocalDecls decls(zone()); | |
2576 bool result = DecodeLocalDecls(decls, data, data + sizeof(data)); | |
2577 EXPECT_TRUE(result); | |
2578 EXPECT_EQ(0u, decls.total_local_count); | |
2579 } | |
2580 | |
2581 TEST_F(LocalDeclDecoderTest, OneLocal) { | |
2582 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
2583 LocalType type = kLocalTypes[i]; | |
2584 const byte data[] = { | |
2585 1, 1, static_cast<byte>(WasmOpcodes::LocalTypeCodeFor(type))}; | |
2586 AstLocalDecls decls(zone()); | |
2587 bool result = DecodeLocalDecls(decls, data, data + sizeof(data)); | |
2588 EXPECT_TRUE(result); | |
2589 EXPECT_EQ(1u, decls.total_local_count); | |
2590 | |
2591 LocalTypeMap map = Expand(decls); | |
2592 EXPECT_EQ(1u, map.size()); | |
2593 EXPECT_EQ(type, map[0]); | |
2594 } | |
2595 } | |
2596 | |
2597 TEST_F(LocalDeclDecoderTest, FiveLocals) { | |
2598 for (size_t i = 0; i < arraysize(kLocalTypes); i++) { | |
2599 LocalType type = kLocalTypes[i]; | |
2600 const byte data[] = { | |
2601 1, 5, static_cast<byte>(WasmOpcodes::LocalTypeCodeFor(type))}; | |
2602 AstLocalDecls decls(zone()); | |
2603 bool result = DecodeLocalDecls(decls, data, data + sizeof(data)); | |
2604 EXPECT_TRUE(result); | |
2605 EXPECT_EQ(sizeof(data), decls.decls_encoded_size); | |
2606 EXPECT_EQ(5u, decls.total_local_count); | |
2607 | |
2608 LocalTypeMap map = Expand(decls); | |
2609 EXPECT_EQ(5u, map.size()); | |
2610 ExpectRun(map, 0, type, 5); | |
2611 } | |
2612 } | |
2613 | |
2614 TEST_F(LocalDeclDecoderTest, MixedLocals) { | |
2615 for (byte a = 0; a < 3; a++) { | |
2616 for (byte b = 0; b < 3; b++) { | |
2617 for (byte c = 0; c < 3; c++) { | |
2618 for (byte d = 0; d < 3; d++) { | |
2619 const byte data[] = {4, a, kLocalI32, b, kLocalI64, | |
2620 c, kLocalF32, d, kLocalF64}; | |
2621 AstLocalDecls decls(zone()); | |
2622 bool result = DecodeLocalDecls(decls, data, data + sizeof(data)); | |
2623 EXPECT_TRUE(result); | |
2624 EXPECT_EQ(sizeof(data), decls.decls_encoded_size); | |
2625 EXPECT_EQ(static_cast<uint32_t>(a + b + c + d), | |
2626 decls.total_local_count); | |
2627 | |
2628 LocalTypeMap map = Expand(decls); | |
2629 EXPECT_EQ(static_cast<uint32_t>(a + b + c + d), map.size()); | |
2630 | |
2631 size_t pos = 0; | |
2632 pos = ExpectRun(map, pos, kAstI32, a); | |
2633 pos = ExpectRun(map, pos, kAstI64, b); | |
2634 pos = ExpectRun(map, pos, kAstF32, c); | |
2635 pos = ExpectRun(map, pos, kAstF64, d); | |
2636 } | |
2637 } | |
2638 } | |
2639 } | |
2640 } | |
2641 | |
2642 TEST_F(LocalDeclDecoderTest, UseEncoder) { | |
2643 const byte* data = nullptr; | |
2644 const byte* end = nullptr; | |
2645 LocalDeclEncoder local_decls(zone()); | |
2646 | |
2647 local_decls.AddLocals(5, kAstF32); | |
2648 local_decls.AddLocals(1337, kAstI32); | |
2649 local_decls.AddLocals(212, kAstI64); | |
2650 local_decls.Prepend(zone(), &data, &end); | |
2651 | |
2652 AstLocalDecls decls(zone()); | |
2653 bool result = DecodeLocalDecls(decls, data, end); | |
2654 EXPECT_TRUE(result); | |
2655 EXPECT_EQ(5u + 1337u + 212u, decls.total_local_count); | |
2656 | |
2657 LocalTypeMap map = Expand(decls); | |
2658 size_t pos = 0; | |
2659 pos = ExpectRun(map, pos, kAstF32, 5); | |
2660 pos = ExpectRun(map, pos, kAstI32, 1337); | |
2661 pos = ExpectRun(map, pos, kAstI64, 212); | |
2662 } | |
2663 | |
2664 class BytecodeIteratorTest : public TestWithZone {}; | |
2665 | |
2666 TEST_F(BytecodeIteratorTest, SimpleForeach) { | |
2667 byte code[] = {WASM_IF_ELSE(WASM_ZERO, WASM_ZERO, WASM_ZERO)}; | |
2668 BytecodeIterator iter(code, code + sizeof(code)); | |
2669 WasmOpcode expected[] = {kExprI8Const, kExprIf, kExprI8Const, | |
2670 kExprElse, kExprI8Const, kExprEnd}; | |
2671 size_t pos = 0; | |
2672 for (WasmOpcode opcode : iter.opcodes()) { | |
2673 if (pos >= arraysize(expected)) { | |
2674 EXPECT_TRUE(false); | |
2675 break; | |
2676 } | |
2677 EXPECT_EQ(expected[pos++], opcode); | |
2678 } | |
2679 EXPECT_EQ(arraysize(expected), pos); | |
2680 } | |
2681 | |
2682 TEST_F(BytecodeIteratorTest, ForeachTwice) { | |
2683 byte code[] = {WASM_IF_ELSE(WASM_ZERO, WASM_ZERO, WASM_ZERO)}; | |
2684 BytecodeIterator iter(code, code + sizeof(code)); | |
2685 int count = 0; | |
2686 | |
2687 count = 0; | |
2688 for (WasmOpcode opcode : iter.opcodes()) { | |
2689 USE(opcode); | |
2690 count++; | |
2691 } | |
2692 EXPECT_EQ(6, count); | |
2693 | |
2694 count = 0; | |
2695 for (WasmOpcode opcode : iter.opcodes()) { | |
2696 USE(opcode); | |
2697 count++; | |
2698 } | |
2699 EXPECT_EQ(6, count); | |
2700 } | |
2701 | |
2702 TEST_F(BytecodeIteratorTest, ForeachOffset) { | |
2703 byte code[] = {WASM_IF_ELSE(WASM_ZERO, WASM_ZERO, WASM_ZERO)}; | |
2704 BytecodeIterator iter(code, code + sizeof(code)); | |
2705 int count = 0; | |
2706 | |
2707 count = 0; | |
2708 for (auto offset : iter.offsets()) { | |
2709 USE(offset); | |
2710 count++; | |
2711 } | |
2712 EXPECT_EQ(6, count); | |
2713 | |
2714 count = 0; | |
2715 for (auto offset : iter.offsets()) { | |
2716 USE(offset); | |
2717 count++; | |
2718 } | |
2719 EXPECT_EQ(6, count); | |
2720 } | |
2721 | |
2722 TEST_F(BytecodeIteratorTest, WithAstDecls) { | |
2723 byte code[] = {1, 1, kLocalI32, WASM_I8(9), WASM_I8(11)}; | |
2724 AstLocalDecls decls(zone()); | |
2725 BytecodeIterator iter(code, code + sizeof(code), &decls); | |
2726 | |
2727 EXPECT_EQ(3u, decls.decls_encoded_size); | |
2728 EXPECT_EQ(3u, iter.pc_offset()); | |
2729 EXPECT_TRUE(iter.has_next()); | |
2730 EXPECT_EQ(kExprI8Const, iter.current()); | |
2731 iter.next(); | |
2732 EXPECT_TRUE(iter.has_next()); | |
2733 EXPECT_EQ(kExprI8Const, iter.current()); | |
2734 iter.next(); | |
2735 EXPECT_FALSE(iter.has_next()); | |
2736 } | |
2737 | |
2738 } // namespace wasm | |
2739 } // namespace internal | |
2740 } // namespace v8 | |
OLD | NEW |