1 package wazeroir
2
3 import (
4 "fmt"
5 "math"
6 "testing"
7
8 "github.com/tetratelabs/wazero/api"
9 "github.com/tetratelabs/wazero/internal/leb128"
10 "github.com/tetratelabs/wazero/internal/testing/require"
11 "github.com/tetratelabs/wazero/internal/wasm"
12 )
13
14 var (
15 f32, f64, i32 = wasm.ValueTypeF32, wasm.ValueTypeF64, wasm.ValueTypeI32
16 f32_i32 = wasm.FunctionType{
17 Params: []wasm.ValueType{f32}, Results: []wasm.ValueType{i32},
18 ParamNumInUint64: 1,
19 ResultNumInUint64: 1,
20 }
21 i32_i32 = wasm.FunctionType{
22 Params: []wasm.ValueType{i32}, Results: []wasm.ValueType{i32},
23 ParamNumInUint64: 1,
24 ResultNumInUint64: 1,
25 }
26 i32i32_i32 = wasm.FunctionType{
27 Params: []wasm.ValueType{i32, i32}, Results: []wasm.ValueType{i32},
28 ParamNumInUint64: 2,
29 ResultNumInUint64: 1,
30 }
31 v_v = wasm.FunctionType{}
32 v_f64f64 = wasm.FunctionType{Results: []wasm.ValueType{f64, f64}, ResultNumInUint64: 2}
33 )
34
35 func TestCompile(t *testing.T) {
36 tests := []struct {
37 name string
38 module *wasm.Module
39 expected *CompilationResult
40 enabledFeatures api.CoreFeatures
41 }{
42 {
43 name: "nullary",
44 module: &wasm.Module{
45 TypeSection: []wasm.FunctionType{v_v},
46 FunctionSection: []wasm.Index{0},
47 CodeSection: []wasm.Code{{Body: []byte{wasm.OpcodeEnd}}},
48 },
49 expected: &CompilationResult{
50 Operations: []UnionOperation{
51 NewOperationBr(NewLabel(LabelKindReturn, 0)),
52 },
53 LabelCallers: map[Label]uint32{},
54 Functions: []uint32{0},
55 Types: []wasm.FunctionType{v_v},
56 },
57 },
58 {
59 name: "host wasm nullary",
60 module: &wasm.Module{
61 TypeSection: []wasm.FunctionType{v_v},
62 FunctionSection: []wasm.Index{0},
63 CodeSection: []wasm.Code{{Body: []byte{wasm.OpcodeEnd}}},
64 },
65 expected: &CompilationResult{
66 Operations: []UnionOperation{
67 NewOperationBr(NewLabel(LabelKindReturn, 0)),
68 },
69 LabelCallers: map[Label]uint32{},
70 Functions: []uint32{0},
71 Types: []wasm.FunctionType{v_v},
72 },
73 },
74 {
75 name: "identity",
76 module: &wasm.Module{
77 TypeSection: []wasm.FunctionType{i32_i32},
78 FunctionSection: []wasm.Index{0},
79 CodeSection: []wasm.Code{{Body: []byte{wasm.OpcodeLocalGet, 0, wasm.OpcodeEnd}}},
80 },
81 expected: &CompilationResult{
82 Operations: []UnionOperation{
83 NewOperationPick(0, false),
84 NewOperationDrop(InclusiveRange{Start: 1, End: 1}),
85 NewOperationBr(NewLabel(LabelKindReturn, 0)),
86 },
87 LabelCallers: map[Label]uint32{},
88 Types: []wasm.FunctionType{
89 {
90 Params: []wasm.ValueType{i32}, Results: []wasm.ValueType{i32},
91 ParamNumInUint64: 1,
92 ResultNumInUint64: 1,
93 },
94 },
95 Functions: []uint32{0},
96 },
97 },
98 {
99 name: "uses memory",
100 module: &wasm.Module{
101 TypeSection: []wasm.FunctionType{v_v},
102 FunctionSection: []wasm.Index{0},
103 CodeSection: []wasm.Code{{Body: []byte{
104 wasm.OpcodeI32Const, 8,
105 wasm.OpcodeI32Load, 0x2, 0x0,
106 wasm.OpcodeDrop,
107 wasm.OpcodeEnd,
108 }}},
109 },
110 expected: &CompilationResult{
111 Operations: []UnionOperation{
112 NewOperationConstI32(8),
113 NewOperationLoad(UnsignedTypeI32, MemoryArg{Alignment: 2, Offset: 0}),
114 NewOperationDrop(InclusiveRange{}),
115 NewOperationBr(NewLabel(LabelKindReturn, 0)),
116 },
117 LabelCallers: map[Label]uint32{},
118 Types: []wasm.FunctionType{v_v},
119 Functions: []uint32{0},
120 UsesMemory: true,
121 },
122 },
123 {
124 name: "host uses memory",
125 module: &wasm.Module{
126 TypeSection: []wasm.FunctionType{v_v},
127 FunctionSection: []wasm.Index{0},
128 CodeSection: []wasm.Code{{Body: []byte{
129 wasm.OpcodeI32Const, 8,
130 wasm.OpcodeI32Load, 0x2, 0x0,
131 wasm.OpcodeDrop,
132 wasm.OpcodeEnd,
133 }}},
134 },
135 expected: &CompilationResult{
136 Operations: []UnionOperation{
137 NewOperationConstI32(8),
138 NewOperationLoad(UnsignedTypeI32, MemoryArg{Alignment: 2, Offset: 0}),
139 NewOperationDrop(InclusiveRange{}),
140 NewOperationBr(NewLabel(LabelKindReturn, 0)),
141 },
142 LabelCallers: map[Label]uint32{},
143 Types: []wasm.FunctionType{v_v},
144 Functions: []uint32{0},
145 UsesMemory: true,
146 },
147 },
148 {
149 name: "memory.grow",
150 module: &wasm.Module{
151 TypeSection: []wasm.FunctionType{i32_i32},
152 FunctionSection: []wasm.Index{0},
153 CodeSection: []wasm.Code{{Body: []byte{
154 wasm.OpcodeLocalGet, 0, wasm.OpcodeMemoryGrow, 0, wasm.OpcodeEnd,
155 }}},
156 },
157 expected: &CompilationResult{
158 Operations: []UnionOperation{
159 NewOperationPick(0, false),
160 NewOperationMemoryGrow(),
161 NewOperationDrop(InclusiveRange{Start: 1, End: 1}),
162 NewOperationBr(NewLabel(LabelKindReturn, 0)),
163 },
164 LabelCallers: map[Label]uint32{},
165 Types: []wasm.FunctionType{{
166 Params: []wasm.ValueType{i32}, Results: []wasm.ValueType{i32},
167 ParamNumInUint64: 1,
168 ResultNumInUint64: 1,
169 }},
170 Functions: []uint32{0},
171 UsesMemory: true,
172 },
173 },
174 }
175
176 for _, tt := range tests {
177 tc := tt
178
179 t.Run(tc.name, func(t *testing.T) {
180 enabledFeatures := tc.enabledFeatures
181 if enabledFeatures == 0 {
182 enabledFeatures = api.CoreFeaturesV2
183 }
184 for _, tp := range tc.module.TypeSection {
185 tp.CacheNumInUint64()
186 }
187 c, err := NewCompiler(enabledFeatures, 0, tc.module, false)
188 require.NoError(t, err)
189
190 fn, err := c.Next()
191 require.NoError(t, err)
192 require.Equal(t, tc.expected, fn)
193 })
194 }
195 }
196
197 func TestCompile_Block(t *testing.T) {
198 tests := []struct {
199 name string
200 module *wasm.Module
201 expected *CompilationResult
202 enabledFeatures api.CoreFeatures
203 }{
204 {
205 name: "type-i32-i32",
206 module: &wasm.Module{
207 TypeSection: []wasm.FunctionType{v_v},
208 FunctionSection: []wasm.Index{0},
209 CodeSection: []wasm.Code{{Body: []byte{
210 wasm.OpcodeBlock, 0x40,
211 wasm.OpcodeBr, 0,
212 wasm.OpcodeI32Add,
213 wasm.OpcodeDrop,
214 wasm.OpcodeEnd,
215 wasm.OpcodeEnd,
216 }}},
217 },
218
219
220 expected: &CompilationResult{
221 Operations: []UnionOperation{
222 NewOperationBr(NewLabel(LabelKindContinuation, 2)),
223 NewOperationLabel(NewLabel(LabelKindContinuation, 2)),
224 NewOperationBr(NewLabel(LabelKindReturn, 0)),
225 },
226
227
228
229 LabelCallers: map[Label]uint32{NewLabel(LabelKindContinuation, 2): 1},
230 Functions: []uint32{0},
231 Types: []wasm.FunctionType{v_v},
232 },
233 },
234 }
235
236 for _, tt := range tests {
237 tc := tt
238
239 t.Run(tc.name, func(t *testing.T) {
240 requireCompilationResult(t, tc.enabledFeatures, tc.expected, tc.module)
241 })
242 }
243 }
244
245
246 func TestCompile_BulkMemoryOperations(t *testing.T) {
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266 two := uint32(2)
267 module := &wasm.Module{
268 TypeSection: []wasm.FunctionType{v_v},
269 FunctionSection: []wasm.Index{0},
270 MemorySection: &wasm.Memory{Min: 1},
271 DataSection: []wasm.DataSegment{
272 {
273 OffsetExpression: wasm.ConstantExpression{
274 Opcode: wasm.OpcodeI32Const,
275 Data: []byte{0x00},
276 },
277 Init: []byte("hello"),
278 },
279 {
280 Passive: true,
281 Init: []byte("goodbye"),
282 },
283 },
284 DataCountSection: &two,
285 CodeSection: []wasm.Code{{Body: []byte{
286 wasm.OpcodeI32Const, 16,
287 wasm.OpcodeI32Const, 0,
288 wasm.OpcodeI32Const, 7,
289 wasm.OpcodeMiscPrefix, wasm.OpcodeMiscMemoryInit, 1, 0,
290 wasm.OpcodeMiscPrefix, wasm.OpcodeMiscDataDrop, 1,
291 wasm.OpcodeEnd,
292 }}},
293 }
294
295 expected := &CompilationResult{
296 Operations: []UnionOperation{
297 NewOperationConstI32(16),
298 NewOperationConstI32(0),
299 NewOperationConstI32(7),
300 NewOperationMemoryInit(1),
301 NewOperationDataDrop(1),
302 NewOperationBr(NewLabel(LabelKindReturn, 0)),
303 },
304 HasMemory: true,
305 UsesMemory: true,
306 HasDataInstances: true,
307 LabelCallers: map[Label]uint32{},
308 Functions: []wasm.Index{0},
309 Types: []wasm.FunctionType{v_v},
310 }
311
312 c, err := NewCompiler(api.CoreFeatureBulkMemoryOperations, 0, module, false)
313 require.NoError(t, err)
314
315 actual, err := c.Next()
316 require.NoError(t, err)
317 require.Equal(t, expected, actual)
318 }
319
320 func TestCompile_MultiValue(t *testing.T) {
321 i32i32_i32i32 := wasm.FunctionType{
322 Params: []wasm.ValueType{wasm.ValueTypeI32, wasm.ValueTypeI32},
323 Results: []wasm.ValueType{wasm.ValueTypeI32, wasm.ValueTypeI32},
324 ParamNumInUint64: 2,
325 ResultNumInUint64: 2,
326 }
327 _i32i64 := wasm.FunctionType{
328 Results: []wasm.ValueType{wasm.ValueTypeI32, wasm.ValueTypeI64},
329 ParamNumInUint64: 0,
330 ResultNumInUint64: 2,
331 }
332
333 tests := []struct {
334 name string
335 module *wasm.Module
336 expected *CompilationResult
337 enabledFeatures api.CoreFeatures
338 }{
339 {
340 name: "swap",
341 module: &wasm.Module{
342 TypeSection: []wasm.FunctionType{i32i32_i32i32},
343 FunctionSection: []wasm.Index{0},
344 CodeSection: []wasm.Code{{Body: []byte{
345
346 wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 0, wasm.OpcodeEnd,
347 }}},
348 },
349 expected: &CompilationResult{
350 Operations: []UnionOperation{
351 NewOperationPick(0, false),
352 NewOperationPick(2, false),
353 NewOperationDrop(InclusiveRange{Start: 2, End: 3}),
354 NewOperationBr(NewLabel(LabelKindReturn, 0)),
355 },
356 LabelCallers: map[Label]uint32{},
357 Functions: []wasm.Index{0},
358 Types: []wasm.FunctionType{i32i32_i32i32},
359 },
360 },
361 {
362 name: "br.wast - type-f64-f64-value",
363 module: &wasm.Module{
364 TypeSection: []wasm.FunctionType{v_f64f64},
365 FunctionSection: []wasm.Index{0},
366 CodeSection: []wasm.Code{{Body: []byte{
367 wasm.OpcodeBlock, 0,
368 wasm.OpcodeF64Const, 0, 0, 0, 0, 0, 0, 0x10, 0x40,
369 wasm.OpcodeF64Const, 0, 0, 0, 0, 0, 0, 0x14, 0x40,
370 wasm.OpcodeBr, 0,
371 wasm.OpcodeF64Add,
372 wasm.OpcodeF64Const, 0, 0, 0, 0, 0, 0, 0x18, 0x40,
373 wasm.OpcodeEnd,
374 wasm.OpcodeEnd,
375 }}},
376 },
377
378
379
380
381
382
383 expected: &CompilationResult{
384 Operations: []UnionOperation{
385 NewOperationConstF64(4),
386 NewOperationConstF64(5),
387 NewOperationBr(NewLabel(LabelKindContinuation, 2)),
388 NewOperationLabel(NewLabel(LabelKindContinuation, 2)),
389 NewOperationBr(NewLabel(LabelKindReturn, 0)),
390 },
391
392
393 LabelCallers: map[Label]uint32{NewLabel(LabelKindContinuation, 2): 1},
394 Functions: []wasm.Index{0},
395 Types: []wasm.FunctionType{v_f64f64},
396 },
397 },
398 {
399 name: "call.wast - $const-i32-i64",
400 module: &wasm.Module{
401 TypeSection: []wasm.FunctionType{_i32i64},
402 FunctionSection: []wasm.Index{0},
403 CodeSection: []wasm.Code{{Body: []byte{
404
405 wasm.OpcodeI32Const, 0xb2, 0x2, wasm.OpcodeI64Const, 0xe4, 0x2, wasm.OpcodeEnd,
406 }}},
407 },
408 expected: &CompilationResult{
409 Operations: []UnionOperation{
410 NewOperationConstI32(306),
411 NewOperationConstI64(356),
412 NewOperationBr(NewLabel(LabelKindReturn, 0)),
413 },
414 LabelCallers: map[Label]uint32{},
415 Functions: []wasm.Index{0},
416 Types: []wasm.FunctionType{_i32i64},
417 },
418 },
419 {
420 name: "if.wast - param",
421 module: &wasm.Module{
422 TypeSection: []wasm.FunctionType{i32_i32},
423 FunctionSection: []wasm.Index{0},
424 CodeSection: []wasm.Code{{Body: []byte{
425 wasm.OpcodeI32Const, 1,
426 wasm.OpcodeLocalGet, 0, wasm.OpcodeIf, 0,
427 wasm.OpcodeI32Const, 2, wasm.OpcodeI32Add,
428 wasm.OpcodeElse, wasm.OpcodeI32Const, 0x7e, wasm.OpcodeI32Add,
429 wasm.OpcodeEnd,
430 wasm.OpcodeEnd,
431 }}},
432 },
433
434
435
436
437
438
439
440
441 expected: &CompilationResult{
442 Operations: []UnionOperation{
443 NewOperationConstI32(1),
444 NewOperationPick(1, false),
445 NewOperationBrIf(
446 NewLabel(LabelKindHeader, 2),
447 NewLabel(LabelKindElse, 2),
448 NopInclusiveRange,
449 ),
450 NewOperationLabel(NewLabel(LabelKindHeader, 2)),
451 NewOperationConstI32(2),
452 NewOperationAdd(UnsignedTypeI32),
453 NewOperationBr(NewLabel(LabelKindContinuation, 2)),
454 NewOperationLabel(NewLabel(LabelKindElse, 2)),
455 NewOperationConstI32(uint32(api.EncodeI32(-2))),
456 NewOperationAdd(UnsignedTypeI32),
457 NewOperationBr(NewLabel(LabelKindContinuation, 2)),
458 NewOperationLabel(NewLabel(LabelKindContinuation, 2)),
459 NewOperationDrop(InclusiveRange{Start: 1, End: 1}),
460 NewOperationBr(NewLabel(LabelKindReturn, 0)),
461 },
462 LabelCallers: map[Label]uint32{
463 NewLabel(LabelKindHeader, 2): 1,
464 NewLabel(LabelKindContinuation, 2): 2,
465 NewLabel(LabelKindElse, 2): 1,
466 },
467 Functions: []wasm.Index{0},
468 Types: []wasm.FunctionType{i32_i32},
469 },
470 },
471 {
472 name: "if.wast - params",
473 module: &wasm.Module{
474 TypeSection: []wasm.FunctionType{
475 i32_i32,
476 i32i32_i32,
477 },
478 FunctionSection: []wasm.Index{0},
479 CodeSection: []wasm.Code{{Body: []byte{
480 wasm.OpcodeI32Const, 1,
481 wasm.OpcodeI32Const, 2,
482 wasm.OpcodeLocalGet, 0, wasm.OpcodeIf, 1,
483 wasm.OpcodeI32Add,
484 wasm.OpcodeElse, wasm.OpcodeI32Sub,
485 wasm.OpcodeEnd,
486 wasm.OpcodeEnd,
487 }}},
488 },
489
490
491
492
493
494
495
496
497
498 expected: &CompilationResult{
499 Operations: []UnionOperation{
500 NewOperationConstI32(1),
501 NewOperationConstI32(2),
502 NewOperationPick(2, false),
503 NewOperationBrIf(
504 NewLabel(LabelKindHeader, 2),
505 NewLabel(LabelKindElse, 2),
506 NopInclusiveRange,
507 ),
508 NewOperationLabel(NewLabel(LabelKindHeader, 2)),
509 NewOperationAdd(UnsignedTypeI32),
510 NewOperationBr(NewLabel(LabelKindContinuation, 2)),
511 NewOperationLabel(NewLabel(LabelKindElse, 2)),
512 NewOperationSub(UnsignedTypeI32),
513 NewOperationBr(NewLabel(LabelKindContinuation, 2)),
514 NewOperationLabel(NewLabel(LabelKindContinuation, 2)),
515 NewOperationDrop(InclusiveRange{Start: 1, End: 1}),
516 NewOperationBr(NewLabel(LabelKindReturn, 0)),
517 },
518 LabelCallers: map[Label]uint32{
519 NewLabel(LabelKindHeader, 2): 1,
520 NewLabel(LabelKindContinuation, 2): 2,
521 NewLabel(LabelKindElse, 2): 1,
522 },
523 Functions: []wasm.Index{0},
524 Types: []wasm.FunctionType{i32_i32, i32i32_i32},
525 },
526 },
527 {
528 name: "if.wast - params-break",
529 module: &wasm.Module{
530 TypeSection: []wasm.FunctionType{
531 i32_i32,
532 i32i32_i32,
533 },
534 FunctionSection: []wasm.Index{0},
535 CodeSection: []wasm.Code{{Body: []byte{
536 wasm.OpcodeI32Const, 1,
537 wasm.OpcodeI32Const, 2,
538 wasm.OpcodeLocalGet, 0, wasm.OpcodeIf, 1,
539 wasm.OpcodeI32Add, wasm.OpcodeBr, 0,
540 wasm.OpcodeElse, wasm.OpcodeI32Sub, wasm.OpcodeBr, 0,
541 wasm.OpcodeEnd,
542 wasm.OpcodeEnd,
543 }}},
544 },
545
546
547
548
549
550
551
552
553
554 expected: &CompilationResult{
555 Operations: []UnionOperation{
556 NewOperationConstI32(1),
557 NewOperationConstI32(2),
558 NewOperationPick(2, false),
559 NewOperationBrIf(
560 NewLabel(LabelKindHeader, 2),
561 NewLabel(LabelKindElse, 2),
562 NopInclusiveRange,
563 ),
564 NewOperationLabel(NewLabel(LabelKindHeader, 2)),
565 NewOperationAdd(UnsignedTypeI32),
566 NewOperationBr(NewLabel(LabelKindContinuation, 2)),
567 NewOperationLabel(NewLabel(LabelKindElse, 2)),
568 NewOperationSub(UnsignedTypeI32),
569 NewOperationBr(NewLabel(LabelKindContinuation, 2)),
570 NewOperationLabel(NewLabel(LabelKindContinuation, 2)),
571 NewOperationDrop(InclusiveRange{Start: 1, End: 1}),
572 NewOperationBr(NewLabel(LabelKindReturn, 0)),
573 },
574 LabelCallers: map[Label]uint32{
575 NewLabel(LabelKindHeader, 2): 1,
576 NewLabel(LabelKindContinuation, 2): 2,
577 NewLabel(LabelKindElse, 2): 1,
578 },
579 Functions: []wasm.Index{0},
580 Types: []wasm.FunctionType{i32_i32, i32i32_i32},
581 },
582 },
583 }
584
585 for _, tt := range tests {
586 tc := tt
587
588 t.Run(tc.name, func(t *testing.T) {
589 enabledFeatures := tc.enabledFeatures
590 if enabledFeatures == 0 {
591 enabledFeatures = api.CoreFeaturesV2
592 }
593 for _, tp := range tc.module.TypeSection {
594 tp.CacheNumInUint64()
595 }
596 c, err := NewCompiler(enabledFeatures, 0, tc.module, false)
597 require.NoError(t, err)
598
599 actual, err := c.Next()
600 require.NoError(t, err)
601 require.Equal(t, tc.expected, actual)
602 })
603 }
604 }
605
606
607 func TestCompile_NonTrappingFloatToIntConversion(t *testing.T) {
608 module := &wasm.Module{
609 TypeSection: []wasm.FunctionType{f32_i32},
610 FunctionSection: []wasm.Index{0},
611
612 CodeSection: []wasm.Code{{Body: []byte{
613 wasm.OpcodeLocalGet, 0, wasm.OpcodeMiscPrefix, wasm.OpcodeMiscI32TruncSatF32S, wasm.OpcodeEnd,
614 }}},
615 }
616
617 expected := &CompilationResult{
618 Operations: []UnionOperation{
619 NewOperationPick(0, false),
620 NewOperationITruncFromF(
621 Float32,
622 SignedInt32,
623 true,
624 ),
625 NewOperationDrop(InclusiveRange{Start: 1, End: 1}),
626 NewOperationBr(NewLabel(LabelKindReturn, 0)),
627 },
628 LabelCallers: map[Label]uint32{},
629 Functions: []wasm.Index{0},
630 Types: []wasm.FunctionType{f32_i32},
631 }
632 c, err := NewCompiler(api.CoreFeatureNonTrappingFloatToIntConversion, 0, module, false)
633 require.NoError(t, err)
634
635 actual, err := c.Next()
636 require.NoError(t, err)
637 require.Equal(t, expected, actual)
638 }
639
640
641 func TestCompile_SignExtensionOps(t *testing.T) {
642 module := &wasm.Module{
643 TypeSection: []wasm.FunctionType{i32_i32},
644 FunctionSection: []wasm.Index{0},
645 CodeSection: []wasm.Code{{Body: []byte{
646 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Extend8S, wasm.OpcodeEnd,
647 }}},
648 }
649
650 expected := &CompilationResult{
651 Operations: []UnionOperation{
652 NewOperationPick(0, false),
653 NewOperationSignExtend32From8(),
654 NewOperationDrop(InclusiveRange{Start: 1, End: 1}),
655 NewOperationBr(NewLabel(LabelKindReturn, 0)),
656 },
657 LabelCallers: map[Label]uint32{},
658 Functions: []wasm.Index{0},
659 Types: []wasm.FunctionType{i32_i32},
660 }
661 c, err := NewCompiler(api.CoreFeatureSignExtensionOps, 0, module, false)
662 require.NoError(t, err)
663
664 actual, err := c.Next()
665 require.NoError(t, err)
666 require.Equal(t, expected, actual)
667 }
668
669 func requireCompilationResult(t *testing.T, enabledFeatures api.CoreFeatures, expected *CompilationResult, module *wasm.Module) {
670 if enabledFeatures == 0 {
671 enabledFeatures = api.CoreFeaturesV2
672 }
673 c, err := NewCompiler(enabledFeatures, 0, module, false)
674 require.NoError(t, err)
675
676 actual, err := c.Next()
677 require.NoError(t, err)
678
679 require.NoError(t, err)
680 require.Equal(t, expected, actual)
681 }
682
683 func TestCompile_CallIndirectNonZeroTableIndex(t *testing.T) {
684 module := &wasm.Module{
685 TypeSection: []wasm.FunctionType{v_v, v_v, v_v},
686 FunctionSection: []wasm.Index{0},
687 CodeSection: []wasm.Code{{Body: []byte{
688 wasm.OpcodeI32Const, 0,
689 wasm.OpcodeCallIndirect,
690 2,
691 5,
692 wasm.OpcodeEnd,
693 }}},
694 TableSection: []wasm.Table{
695 {Type: wasm.RefTypeExternref},
696 {Type: wasm.RefTypeFuncref},
697 {Type: wasm.RefTypeFuncref},
698 {Type: wasm.RefTypeFuncref},
699 {Type: wasm.RefTypeFuncref},
700 {Type: wasm.RefTypeFuncref, Min: 100},
701 },
702 }
703
704 expected := &CompilationResult{
705 Operations: []UnionOperation{
706 NewOperationConstI32(0),
707 NewOperationCallIndirect(2, 5),
708 NewOperationBr(NewLabel(LabelKindReturn, 0)),
709 },
710 HasTable: true,
711 LabelCallers: map[Label]uint32{},
712 Functions: []wasm.Index{0},
713 Types: []wasm.FunctionType{v_v, v_v, v_v},
714 }
715
716 c, err := NewCompiler(api.CoreFeatureBulkMemoryOperations, 0, module, false)
717 require.NoError(t, err)
718
719 actual, err := c.Next()
720 require.NoError(t, err)
721 require.Equal(t, expected, actual)
722 }
723
724 func TestCompile_Refs(t *testing.T) {
725 tests := []struct {
726 name string
727 body []byte
728 expected []UnionOperation
729 }{
730 {
731 name: "ref.func",
732 body: []byte{
733 wasm.OpcodeRefFunc, 100,
734 wasm.OpcodeDrop,
735 wasm.OpcodeEnd,
736 },
737 expected: []UnionOperation{
738 NewOperationRefFunc(100),
739 NewOperationDrop(InclusiveRange{Start: 0, End: 0}),
740 NewOperationBr(NewLabel(LabelKindReturn, 0)),
741 },
742 },
743 {
744 name: "ref.null (externref)",
745 body: []byte{
746 wasm.OpcodeRefNull, wasm.ValueTypeExternref,
747 wasm.OpcodeDrop,
748 wasm.OpcodeEnd,
749 },
750 expected: []UnionOperation{
751 NewOperationConstI64(0),
752 NewOperationDrop(InclusiveRange{Start: 0, End: 0}),
753 NewOperationBr(NewLabel(LabelKindReturn, 0)),
754 },
755 },
756 {
757 name: "ref.null (funcref)",
758 body: []byte{
759 wasm.OpcodeRefNull, wasm.ValueTypeFuncref,
760 wasm.OpcodeDrop,
761 wasm.OpcodeEnd,
762 },
763 expected: []UnionOperation{
764 NewOperationConstI64(0),
765 NewOperationDrop(InclusiveRange{Start: 0, End: 0}),
766 NewOperationBr(NewLabel(LabelKindReturn, 0)),
767 },
768 },
769 {
770 name: "ref.is_null",
771 body: []byte{
772 wasm.OpcodeRefFunc, 100,
773 wasm.OpcodeRefIsNull,
774 wasm.OpcodeDrop,
775 wasm.OpcodeEnd,
776 },
777 expected: []UnionOperation{
778 NewOperationRefFunc(100),
779 NewOperationEqz(UnsignedInt64),
780 NewOperationDrop(InclusiveRange{Start: 0, End: 0}),
781 NewOperationBr(NewLabel(LabelKindReturn, 0)),
782 },
783 },
784 {
785 name: "ref.is_null (externref)",
786 body: []byte{
787 wasm.OpcodeRefNull, wasm.ValueTypeExternref,
788 wasm.OpcodeRefIsNull,
789 wasm.OpcodeDrop,
790 wasm.OpcodeEnd,
791 },
792 expected: []UnionOperation{
793 NewOperationConstI64(0),
794 NewOperationEqz(UnsignedInt64),
795 NewOperationDrop(InclusiveRange{Start: 0, End: 0}),
796 NewOperationBr(NewLabel(LabelKindReturn, 0)),
797 },
798 },
799 }
800
801 for _, tt := range tests {
802 tc := tt
803 t.Run(tc.name, func(t *testing.T) {
804 module := &wasm.Module{
805 TypeSection: []wasm.FunctionType{v_v},
806 FunctionSection: []wasm.Index{0},
807 CodeSection: []wasm.Code{{Body: tc.body}},
808 }
809 c, err := NewCompiler(api.CoreFeaturesV2, 0, module, false)
810 require.NoError(t, err)
811
812 actual, err := c.Next()
813 require.NoError(t, err)
814 require.Equal(t, tc.expected, actual.Operations)
815 })
816 }
817 }
818
819 func TestCompile_TableGetOrSet(t *testing.T) {
820 tests := []struct {
821 name string
822 body []byte
823 expected []UnionOperation
824 }{
825 {
826 name: "table.get",
827 body: []byte{
828 wasm.OpcodeI32Const, 10,
829 wasm.OpcodeTableGet, 0,
830 wasm.OpcodeDrop,
831 wasm.OpcodeEnd,
832 },
833 expected: []UnionOperation{
834 NewOperationConstI32(10),
835 NewOperationTableGet(0),
836 NewOperationDrop(InclusiveRange{Start: 0, End: 0}),
837 NewOperationBr(NewLabel(LabelKindReturn, 0)),
838 },
839 },
840 {
841 name: "table.set (externref)",
842 body: []byte{
843 wasm.OpcodeI32Const, 10,
844 wasm.OpcodeRefNull, wasm.ValueTypeExternref,
845 wasm.OpcodeTableSet, 0,
846 wasm.OpcodeEnd,
847 },
848 expected: []UnionOperation{
849 NewOperationConstI32(10),
850 NewOperationConstI64(0),
851 NewOperationTableSet(0),
852 NewOperationBr(NewLabel(LabelKindReturn, 0)),
853 },
854 },
855 {
856 name: "table.set (funcref)",
857 body: []byte{
858 wasm.OpcodeI32Const, 10,
859 wasm.OpcodeRefFunc, 1,
860 wasm.OpcodeTableSet, 0,
861 wasm.OpcodeEnd,
862 },
863 expected: []UnionOperation{
864 NewOperationConstI32(10),
865 NewOperationRefFunc(1),
866 NewOperationTableSet(0),
867 NewOperationBr(NewLabel(LabelKindReturn, 0)),
868 },
869 },
870 }
871
872 for _, tt := range tests {
873 tc := tt
874 t.Run(tc.name, func(t *testing.T) {
875 module := &wasm.Module{
876 TypeSection: []wasm.FunctionType{v_v},
877 FunctionSection: []wasm.Index{0},
878 CodeSection: []wasm.Code{{Body: tc.body}},
879 TableSection: []wasm.Table{{}},
880 }
881 c, err := NewCompiler(api.CoreFeaturesV2, 0, module, false)
882 require.NoError(t, err)
883
884 actual, err := c.Next()
885 require.NoError(t, err)
886 require.Equal(t, tc.expected, actual.Operations)
887 })
888 }
889 }
890
891 func TestCompile_TableGrowFillSize(t *testing.T) {
892 tests := []struct {
893 name string
894 body []byte
895 expected []UnionOperation
896 }{
897 {
898 name: "table.grow",
899 body: []byte{
900 wasm.OpcodeRefNull, wasm.RefTypeFuncref,
901 wasm.OpcodeI32Const, 1,
902 wasm.OpcodeMiscPrefix, wasm.OpcodeMiscTableGrow, 1,
903 wasm.OpcodeEnd,
904 },
905 expected: []UnionOperation{
906 NewOperationConstI64(0),
907 NewOperationConstI32(1),
908 NewOperationTableGrow(1),
909 NewOperationDrop(InclusiveRange{Start: 0, End: 0}),
910 NewOperationBr(NewLabel(LabelKindReturn, 0)),
911 },
912 },
913 {
914 name: "table.fill",
915 body: []byte{
916 wasm.OpcodeI32Const, 10,
917 wasm.OpcodeRefNull, wasm.RefTypeFuncref,
918 wasm.OpcodeI32Const, 1,
919 wasm.OpcodeMiscPrefix, wasm.OpcodeMiscTableFill, 1,
920 wasm.OpcodeEnd,
921 },
922 expected: []UnionOperation{
923 NewOperationConstI32(10),
924 NewOperationConstI64(0),
925 NewOperationConstI32(1),
926 NewOperationTableFill(1),
927 NewOperationBr(NewLabel(LabelKindReturn, 0)),
928 },
929 },
930 {
931 name: "table.size",
932 body: []byte{
933 wasm.OpcodeMiscPrefix, wasm.OpcodeMiscTableSize, 1,
934 wasm.OpcodeEnd,
935 },
936 expected: []UnionOperation{
937 NewOperationTableSize(1),
938 NewOperationDrop(InclusiveRange{Start: 0, End: 0}),
939 NewOperationBr(NewLabel(LabelKindReturn, 0)),
940 },
941 },
942 }
943
944 for _, tt := range tests {
945 tc := tt
946 t.Run(tc.name, func(t *testing.T) {
947 module := &wasm.Module{
948 TypeSection: []wasm.FunctionType{v_v},
949 FunctionSection: []wasm.Index{0},
950 CodeSection: []wasm.Code{{Body: tc.body}},
951 TableSection: []wasm.Table{{}},
952 }
953 c, err := NewCompiler(api.CoreFeaturesV2, 0, module, false)
954 require.NoError(t, err)
955
956 actual, err := c.Next()
957 require.NoError(t, err)
958 require.Equal(t, tc.expected, actual.Operations)
959 require.True(t, actual.HasTable)
960 })
961 }
962 }
963
964 func TestCompile_Locals(t *testing.T) {
965 tests := []struct {
966 name string
967 mod *wasm.Module
968 expected []UnionOperation
969 }{
970 {
971 name: "local.get - func param - v128",
972 mod: &wasm.Module{
973 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{wasm.ValueTypeV128}}},
974 FunctionSection: []wasm.Index{0},
975 CodeSection: []wasm.Code{{Body: []byte{
976 wasm.OpcodeLocalGet, 0,
977 wasm.OpcodeEnd,
978 }}},
979 },
980 expected: []UnionOperation{
981 NewOperationPick(1, true),
982 NewOperationDrop(InclusiveRange{Start: 0, End: 3}),
983 NewOperationBr(NewLabel(LabelKindReturn, 0)),
984 },
985 },
986 {
987 name: "local.get - func param - i64",
988 mod: &wasm.Module{
989 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{wasm.ValueTypeI64}}},
990 FunctionSection: []wasm.Index{0},
991 CodeSection: []wasm.Code{{Body: []byte{
992 wasm.OpcodeLocalGet, 0,
993 wasm.OpcodeEnd,
994 }}},
995 },
996 expected: []UnionOperation{
997 NewOperationPick(0, false),
998 NewOperationDrop(InclusiveRange{Start: 0, End: 1}),
999 NewOperationBr(NewLabel(LabelKindReturn, 0)),
1000 },
1001 },
1002 {
1003 name: "local.get - non func param - v128",
1004 mod: &wasm.Module{
1005 TypeSection: []wasm.FunctionType{v_v},
1006 FunctionSection: []wasm.Index{0},
1007 CodeSection: []wasm.Code{{
1008 Body: []byte{
1009 wasm.OpcodeLocalGet, 0,
1010 wasm.OpcodeEnd,
1011 },
1012 LocalTypes: []wasm.ValueType{wasm.ValueTypeV128},
1013 }},
1014 },
1015 expected: []UnionOperation{
1016 NewOperationV128Const(0, 0),
1017 NewOperationPick(1, true),
1018 NewOperationDrop(InclusiveRange{Start: 0, End: 3}),
1019 NewOperationBr(NewLabel(LabelKindReturn, 0)),
1020 },
1021 },
1022 {
1023 name: "local.set - func param - v128",
1024 mod: &wasm.Module{
1025 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{wasm.ValueTypeV128}}},
1026 FunctionSection: []wasm.Index{0},
1027 CodeSection: []wasm.Code{{Body: []byte{
1028 wasm.OpcodeVecPrefix, wasm.OpcodeVecV128Const,
1029 1, 0, 0, 0, 0, 0, 0, 0,
1030 2, 0, 0, 0, 0, 0, 0, 0,
1031 wasm.OpcodeLocalSet, 0,
1032 wasm.OpcodeEnd,
1033 }}},
1034 },
1035 expected: []UnionOperation{
1036
1037 NewOperationV128Const(0x01, 0x02),
1038
1039 NewOperationSet(3, true),
1040 NewOperationDrop(InclusiveRange{Start: 0, End: 1}),
1041 NewOperationBr(NewLabel(LabelKindReturn, 0)),
1042 },
1043 },
1044 {
1045 name: "local.set - func param - i32",
1046 mod: &wasm.Module{
1047 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{wasm.ValueTypeI32}}},
1048 FunctionSection: []wasm.Index{0},
1049 CodeSection: []wasm.Code{{Body: []byte{
1050 wasm.OpcodeI32Const, 0x1,
1051 wasm.OpcodeLocalSet, 0,
1052 wasm.OpcodeEnd,
1053 }}},
1054 },
1055 expected: []UnionOperation{
1056 NewOperationConstI32(0x1),
1057 NewOperationSet(1, false),
1058 NewOperationDrop(InclusiveRange{Start: 0, End: 0}),
1059 NewOperationBr(NewLabel(LabelKindReturn, 0)),
1060 },
1061 },
1062 {
1063 name: "local.set - non func param - v128",
1064 mod: &wasm.Module{
1065 TypeSection: []wasm.FunctionType{v_v},
1066 FunctionSection: []wasm.Index{0},
1067 CodeSection: []wasm.Code{{
1068 Body: []byte{
1069 wasm.OpcodeVecPrefix, wasm.OpcodeVecV128Const,
1070 1, 0, 0, 0, 0, 0, 0, 0,
1071 2, 0, 0, 0, 0, 0, 0, 0,
1072 wasm.OpcodeLocalSet, 0,
1073 wasm.OpcodeEnd,
1074 },
1075 LocalTypes: []wasm.ValueType{wasm.ValueTypeV128},
1076 }},
1077 },
1078 expected: []UnionOperation{
1079 NewOperationV128Const(0, 0),
1080
1081 NewOperationV128Const(0x01, 0x02),
1082
1083 NewOperationSet(3, true),
1084 NewOperationDrop(InclusiveRange{Start: 0, End: 1}),
1085 NewOperationBr(NewLabel(LabelKindReturn, 0)),
1086 },
1087 },
1088 {
1089 name: "local.tee - func param - v128",
1090 mod: &wasm.Module{
1091 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{wasm.ValueTypeV128}}},
1092 FunctionSection: []wasm.Index{0},
1093 CodeSection: []wasm.Code{{Body: []byte{
1094 wasm.OpcodeVecPrefix, wasm.OpcodeVecV128Const,
1095 1, 0, 0, 0, 0, 0, 0, 0,
1096 2, 0, 0, 0, 0, 0, 0, 0,
1097 wasm.OpcodeLocalTee, 0,
1098 wasm.OpcodeEnd,
1099 }}},
1100 },
1101 expected: []UnionOperation{
1102
1103 NewOperationV128Const(0x01, 0x02),
1104
1105 NewOperationPick(1, true),
1106
1107 NewOperationSet(5, true),
1108 NewOperationDrop(InclusiveRange{Start: 0, End: 3}),
1109 NewOperationBr(NewLabel(LabelKindReturn, 0)),
1110 },
1111 },
1112 {
1113 name: "local.tee - func param - f32",
1114 mod: &wasm.Module{
1115 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{wasm.ValueTypeF32}}},
1116 FunctionSection: []wasm.Index{0},
1117 CodeSection: []wasm.Code{{Body: []byte{
1118 wasm.OpcodeF32Const, 1, 0, 0, 0,
1119 wasm.OpcodeLocalTee, 0,
1120 wasm.OpcodeEnd,
1121 }}},
1122 },
1123 expected: []UnionOperation{
1124 NewOperationConstF32(math.Float32frombits(1)),
1125 NewOperationPick(0, false),
1126 NewOperationSet(2, false),
1127 NewOperationDrop(InclusiveRange{Start: 0, End: 1}),
1128 NewOperationBr(NewLabel(LabelKindReturn, 0)),
1129 },
1130 },
1131 {
1132 name: "local.tee - non func param",
1133 mod: &wasm.Module{
1134 TypeSection: []wasm.FunctionType{v_v},
1135 FunctionSection: []wasm.Index{0},
1136 CodeSection: []wasm.Code{{
1137 Body: []byte{
1138 wasm.OpcodeVecPrefix, wasm.OpcodeVecV128Const,
1139 1, 0, 0, 0, 0, 0, 0, 0,
1140 2, 0, 0, 0, 0, 0, 0, 0,
1141 wasm.OpcodeLocalTee, 0,
1142 wasm.OpcodeEnd,
1143 },
1144 LocalTypes: []wasm.ValueType{wasm.ValueTypeV128},
1145 }},
1146 },
1147 expected: []UnionOperation{
1148 NewOperationV128Const(0, 0),
1149
1150 NewOperationV128Const(0x01, 0x02),
1151
1152 NewOperationPick(1, true),
1153
1154 NewOperationSet(5, true),
1155 NewOperationDrop(InclusiveRange{Start: 0, End: 3}),
1156 NewOperationBr(NewLabel(LabelKindReturn, 0)),
1157 },
1158 },
1159 }
1160
1161 for _, tt := range tests {
1162 tc := tt
1163 t.Run(tc.name, func(t *testing.T) {
1164 c, err := NewCompiler(api.CoreFeaturesV2, 0, tc.mod, false)
1165 require.NoError(t, err)
1166
1167 actual, err := c.Next()
1168 require.NoError(t, err)
1169 msg := fmt.Sprintf("\nhave:\n\t%s\nwant:\n\t%s", Format(actual.Operations), Format(tc.expected))
1170 require.Equal(t, tc.expected, actual.Operations, msg)
1171 })
1172 }
1173 }
1174
1175 func TestCompile_Vec(t *testing.T) {
1176 addV128Const := func(in []byte) []byte {
1177 return append(in, wasm.OpcodeVecPrefix,
1178 wasm.OpcodeVecV128Const,
1179 1, 1, 1, 1, 1, 1, 1, 1,
1180 1, 1, 1, 1, 1, 1, 1, 1)
1181 }
1182
1183 vvv2v := func(vec wasm.OpcodeVec) (ret []byte) {
1184 ret = addV128Const(ret)
1185 ret = addV128Const(ret)
1186 ret = addV128Const(ret)
1187 return append(ret, wasm.OpcodeVecPrefix, vec, wasm.OpcodeDrop, wasm.OpcodeEnd)
1188 }
1189
1190 vv2v := func(vec wasm.OpcodeVec) (ret []byte) {
1191 ret = addV128Const(ret)
1192 ret = addV128Const(ret)
1193 return append(ret, wasm.OpcodeVecPrefix, vec, wasm.OpcodeDrop, wasm.OpcodeEnd)
1194 }
1195
1196 vi2v := func(vec wasm.OpcodeVec) (ret []byte) {
1197 ret = addV128Const(ret)
1198 return append(ret, wasm.OpcodeI32Const, 1,
1199 wasm.OpcodeVecPrefix, vec,
1200 wasm.OpcodeDrop, wasm.OpcodeEnd)
1201 }
1202
1203 v2v := func(vec wasm.OpcodeVec) (ret []byte) {
1204 ret = addV128Const(ret)
1205 return append(ret, wasm.OpcodeVecPrefix, vec, wasm.OpcodeDrop, wasm.OpcodeEnd)
1206 }
1207
1208 load := func(vec wasm.OpcodeVec, offset, align uint32) (ret []byte) {
1209 ret = []byte{wasm.OpcodeI32Const, 1, 1, 1, 1, wasm.OpcodeVecPrefix, vec}
1210 ret = append(ret, leb128.EncodeUint32(align)...)
1211 ret = append(ret, leb128.EncodeUint32(offset)...)
1212 ret = append(ret, wasm.OpcodeDrop, wasm.OpcodeEnd)
1213 return
1214 }
1215
1216 loadLane := func(vec wasm.OpcodeVec, offset, align uint32, lane byte) (ret []byte) {
1217 ret = addV128Const([]byte{wasm.OpcodeI32Const, 1, 1, 1, 1})
1218 ret = append(ret, wasm.OpcodeVecPrefix, vec)
1219 ret = append(ret, leb128.EncodeUint32(align)...)
1220 ret = append(ret, leb128.EncodeUint32(offset)...)
1221 ret = append(ret, lane, wasm.OpcodeDrop, wasm.OpcodeEnd)
1222 return
1223 }
1224
1225 storeLane := func(vec wasm.OpcodeVec, offset, align uint32, lane byte) (ret []byte) {
1226 ret = addV128Const([]byte{wasm.OpcodeI32Const, 0})
1227 ret = append(ret, wasm.OpcodeVecPrefix, vec)
1228 ret = append(ret, leb128.EncodeUint32(align)...)
1229 ret = append(ret, leb128.EncodeUint32(offset)...)
1230 ret = append(ret, lane, wasm.OpcodeEnd)
1231 return
1232 }
1233
1234 extractLane := func(vec wasm.OpcodeVec, lane byte) (ret []byte) {
1235 ret = addV128Const(ret)
1236 ret = append(ret, wasm.OpcodeVecPrefix, vec, lane, wasm.OpcodeDrop, wasm.OpcodeEnd)
1237 return
1238 }
1239
1240 replaceLane := func(vec wasm.OpcodeVec, lane byte) (ret []byte) {
1241 ret = addV128Const(ret)
1242
1243 switch vec {
1244 case wasm.OpcodeVecI8x16ReplaceLane, wasm.OpcodeVecI16x8ReplaceLane, wasm.OpcodeVecI32x4ReplaceLane:
1245 ret = append(ret, wasm.OpcodeI32Const, 0)
1246 case wasm.OpcodeVecI64x2ReplaceLane:
1247 ret = append(ret, wasm.OpcodeI64Const, 0)
1248 case wasm.OpcodeVecF32x4ReplaceLane:
1249 ret = append(ret, wasm.OpcodeF32Const, 0, 0, 0, 0)
1250 case wasm.OpcodeVecF64x2ReplaceLane:
1251 ret = append(ret, wasm.OpcodeF64Const, 0, 0, 0, 0, 0, 0, 0, 0)
1252 }
1253
1254 ret = append(ret, wasm.OpcodeVecPrefix, vec, lane, wasm.OpcodeDrop, wasm.OpcodeEnd)
1255 return
1256 }
1257
1258 splat := func(vec wasm.OpcodeVec) (ret []byte) {
1259 switch vec {
1260 case wasm.OpcodeVecI8x16Splat, wasm.OpcodeVecI16x8Splat, wasm.OpcodeVecI32x4Splat:
1261 ret = append(ret, wasm.OpcodeI32Const, 0)
1262 case wasm.OpcodeVecI64x2Splat:
1263 ret = append(ret, wasm.OpcodeI64Const, 0)
1264 case wasm.OpcodeVecF32x4Splat:
1265 ret = append(ret, wasm.OpcodeF32Const, 0, 0, 0, 0)
1266 case wasm.OpcodeVecF64x2Splat:
1267 ret = append(ret, wasm.OpcodeF64Const, 0, 0, 0, 0, 0, 0, 0, 0)
1268 }
1269 ret = append(ret, wasm.OpcodeVecPrefix, vec, wasm.OpcodeDrop, wasm.OpcodeEnd)
1270 return
1271 }
1272
1273 tests := []struct {
1274 name string
1275 body []byte
1276 expected UnionOperation
1277 needDropBeforeReturn bool
1278 }{
1279 {
1280 name: "i8x16 add",
1281 needDropBeforeReturn: true,
1282 body: vv2v(wasm.OpcodeVecI8x16Add),
1283 expected: NewOperationV128Add(ShapeI8x16),
1284 },
1285 {
1286 name: "i8x16 add",
1287 needDropBeforeReturn: true,
1288 body: vv2v(wasm.OpcodeVecI16x8Add),
1289 expected: NewOperationV128Add(ShapeI16x8),
1290 },
1291 {
1292 name: "i32x2 add",
1293 needDropBeforeReturn: true,
1294 body: vv2v(wasm.OpcodeVecI64x2Add),
1295 expected: NewOperationV128Add(ShapeI64x2),
1296 },
1297 {
1298 name: "i64x2 add",
1299 needDropBeforeReturn: true,
1300 body: vv2v(wasm.OpcodeVecI64x2Add),
1301 expected: NewOperationV128Add(ShapeI64x2),
1302 },
1303 {
1304 name: "i8x16 sub",
1305 needDropBeforeReturn: true,
1306 body: vv2v(wasm.OpcodeVecI8x16Sub),
1307 expected: NewOperationV128Sub(ShapeI8x16),
1308 },
1309 {
1310 name: "i16x8 sub",
1311 needDropBeforeReturn: true,
1312 body: vv2v(wasm.OpcodeVecI16x8Sub),
1313 expected: NewOperationV128Sub(ShapeI16x8),
1314 },
1315 {
1316 name: "i32x2 sub",
1317 needDropBeforeReturn: true,
1318 body: vv2v(wasm.OpcodeVecI64x2Sub),
1319 expected: NewOperationV128Sub(ShapeI64x2),
1320 },
1321 {
1322 name: "i64x2 sub",
1323 needDropBeforeReturn: true,
1324 body: vv2v(wasm.OpcodeVecI64x2Sub),
1325 expected: NewOperationV128Sub(ShapeI64x2),
1326 },
1327 {
1328 name: wasm.OpcodeVecV128LoadName, body: load(wasm.OpcodeVecV128Load, 0, 0),
1329 needDropBeforeReturn: true,
1330 expected: NewOperationV128Load(V128LoadType128, MemoryArg{Alignment: 0, Offset: 0}),
1331 },
1332 {
1333 name: wasm.OpcodeVecV128LoadName + "/align=4", body: load(wasm.OpcodeVecV128Load, 0, 4),
1334 needDropBeforeReturn: true,
1335 expected: NewOperationV128Load(V128LoadType128, MemoryArg{Alignment: 4, Offset: 0}),
1336 },
1337 {
1338 name: wasm.OpcodeVecV128Load8x8SName, body: load(wasm.OpcodeVecV128Load8x8s, 1, 0),
1339 needDropBeforeReturn: true,
1340 expected: NewOperationV128Load(V128LoadType8x8s, MemoryArg{Alignment: 0, Offset: 1}),
1341 },
1342 {
1343 name: wasm.OpcodeVecV128Load8x8SName + "/align=1", body: load(wasm.OpcodeVecV128Load8x8s, 0, 1),
1344 needDropBeforeReturn: true,
1345 expected: NewOperationV128Load(V128LoadType8x8s, MemoryArg{Alignment: 1, Offset: 0}),
1346 },
1347 {
1348 name: wasm.OpcodeVecV128Load8x8UName, body: load(wasm.OpcodeVecV128Load8x8u, 0, 0),
1349 needDropBeforeReturn: true,
1350 expected: NewOperationV128Load(V128LoadType8x8u, MemoryArg{Alignment: 0, Offset: 0}),
1351 },
1352 {
1353 name: wasm.OpcodeVecV128Load8x8UName + "/align=1", body: load(wasm.OpcodeVecV128Load8x8u, 0, 1),
1354 needDropBeforeReturn: true,
1355 expected: NewOperationV128Load(V128LoadType8x8u, MemoryArg{Alignment: 1, Offset: 0}),
1356 },
1357 {
1358 name: wasm.OpcodeVecV128Load16x4SName, body: load(wasm.OpcodeVecV128Load16x4s, 1, 0),
1359 needDropBeforeReturn: true,
1360 expected: NewOperationV128Load(V128LoadType16x4s, MemoryArg{Alignment: 0, Offset: 1}),
1361 },
1362 {
1363 name: wasm.OpcodeVecV128Load16x4SName + "/align=2", body: load(wasm.OpcodeVecV128Load16x4s, 0, 2),
1364 needDropBeforeReturn: true,
1365 expected: NewOperationV128Load(V128LoadType16x4s, MemoryArg{Alignment: 2, Offset: 0}),
1366 },
1367 {
1368 name: wasm.OpcodeVecV128Load16x4UName, body: load(wasm.OpcodeVecV128Load16x4u, 0, 0),
1369 needDropBeforeReturn: true,
1370 expected: NewOperationV128Load(V128LoadType16x4u, MemoryArg{Alignment: 0, Offset: 0}),
1371 },
1372 {
1373 name: wasm.OpcodeVecV128Load16x4UName + "/align=2", body: load(wasm.OpcodeVecV128Load16x4u, 0, 2),
1374 needDropBeforeReturn: true,
1375 expected: NewOperationV128Load(V128LoadType16x4u, MemoryArg{Alignment: 2, Offset: 0}),
1376 },
1377 {
1378 name: wasm.OpcodeVecV128Load32x2SName, body: load(wasm.OpcodeVecV128Load32x2s, 1, 0),
1379 needDropBeforeReturn: true,
1380 expected: NewOperationV128Load(V128LoadType32x2s, MemoryArg{Alignment: 0, Offset: 1}),
1381 },
1382 {
1383 name: wasm.OpcodeVecV128Load32x2SName + "/align=3", body: load(wasm.OpcodeVecV128Load32x2s, 0, 3),
1384 needDropBeforeReturn: true,
1385 expected: NewOperationV128Load(V128LoadType32x2s, MemoryArg{Alignment: 3, Offset: 0}),
1386 },
1387 {
1388 name: wasm.OpcodeVecV128Load32x2UName, body: load(wasm.OpcodeVecV128Load32x2u, 0, 0),
1389 needDropBeforeReturn: true,
1390 expected: NewOperationV128Load(V128LoadType32x2u, MemoryArg{Alignment: 0, Offset: 0}),
1391 },
1392 {
1393 name: wasm.OpcodeVecV128Load32x2UName + "/align=3", body: load(wasm.OpcodeVecV128Load32x2u, 0, 3),
1394 needDropBeforeReturn: true,
1395 expected: NewOperationV128Load(V128LoadType32x2u, MemoryArg{Alignment: 3, Offset: 0}),
1396 },
1397 {
1398 name: wasm.OpcodeVecV128Load8SplatName, body: load(wasm.OpcodeVecV128Load8Splat, 2, 0),
1399 needDropBeforeReturn: true,
1400 expected: NewOperationV128Load(V128LoadType8Splat, MemoryArg{Alignment: 0, Offset: 2}),
1401 },
1402 {
1403 name: wasm.OpcodeVecV128Load16SplatName, body: load(wasm.OpcodeVecV128Load16Splat, 0, 1),
1404 needDropBeforeReturn: true,
1405 expected: NewOperationV128Load(V128LoadType16Splat, MemoryArg{Alignment: 1, Offset: 0}),
1406 },
1407 {
1408 name: wasm.OpcodeVecV128Load32SplatName, body: load(wasm.OpcodeVecV128Load32Splat, 3, 2),
1409 needDropBeforeReturn: true,
1410 expected: NewOperationV128Load(V128LoadType32Splat, MemoryArg{Alignment: 2, Offset: 3}),
1411 },
1412 {
1413 name: wasm.OpcodeVecV128Load64SplatName, body: load(wasm.OpcodeVecV128Load64Splat, 0, 3),
1414 needDropBeforeReturn: true,
1415 expected: NewOperationV128Load(V128LoadType64Splat, MemoryArg{Alignment: 3, Offset: 0}),
1416 },
1417 {
1418 name: wasm.OpcodeVecV128Load32zeroName, body: load(wasm.OpcodeVecV128Load32zero, 0, 2),
1419 needDropBeforeReturn: true,
1420 expected: NewOperationV128Load(V128LoadType32zero, MemoryArg{Alignment: 2, Offset: 0}),
1421 },
1422 {
1423 name: wasm.OpcodeVecV128Load64zeroName, body: load(wasm.OpcodeVecV128Load64zero, 5, 3),
1424 needDropBeforeReturn: true,
1425 expected: NewOperationV128Load(V128LoadType64zero, MemoryArg{Alignment: 3, Offset: 5}),
1426 },
1427 {
1428 name: wasm.OpcodeVecV128Load8LaneName, needDropBeforeReturn: true,
1429 body: loadLane(wasm.OpcodeVecV128Load8Lane, 5, 0, 10),
1430 expected: NewOperationV128LoadLane(10, 8, MemoryArg{Alignment: 0, Offset: 5}),
1431 },
1432 {
1433 name: wasm.OpcodeVecV128Load16LaneName, needDropBeforeReturn: true,
1434 body: loadLane(wasm.OpcodeVecV128Load16Lane, 100, 1, 7),
1435 expected: NewOperationV128LoadLane(7, 16, MemoryArg{Alignment: 1, Offset: 100}),
1436 },
1437 {
1438 name: wasm.OpcodeVecV128Load32LaneName, needDropBeforeReturn: true,
1439 body: loadLane(wasm.OpcodeVecV128Load32Lane, 0, 2, 3),
1440 expected: NewOperationV128LoadLane(3, 32, MemoryArg{Alignment: 2, Offset: 0}),
1441 },
1442 {
1443 name: wasm.OpcodeVecV128Load64LaneName, needDropBeforeReturn: true,
1444 body: loadLane(wasm.OpcodeVecV128Load64Lane, 0, 3, 1),
1445 expected: NewOperationV128LoadLane(1, 64, MemoryArg{Alignment: 3, Offset: 0}),
1446 },
1447 {
1448 name: wasm.OpcodeVecV128StoreName, body: []byte{
1449 wasm.OpcodeI32Const,
1450 1, 1, 1, 1,
1451 wasm.OpcodeVecPrefix,
1452 wasm.OpcodeVecV128Const,
1453 1, 1, 1, 1, 1, 1, 1, 1,
1454 1, 1, 1, 1, 1, 1, 1, 1,
1455 wasm.OpcodeVecPrefix,
1456 wasm.OpcodeVecV128Store,
1457 4,
1458 10,
1459 wasm.OpcodeEnd,
1460 },
1461 expected: NewOperationV128Store(MemoryArg{Alignment: 4, Offset: 10}),
1462 },
1463 {
1464 name: wasm.OpcodeVecV128Store8LaneName,
1465 body: storeLane(wasm.OpcodeVecV128Store8Lane, 0, 0, 0),
1466 expected: NewOperationV128StoreLane(0, 8, MemoryArg{Alignment: 0, Offset: 0}),
1467 },
1468 {
1469 name: wasm.OpcodeVecV128Store8LaneName + "/lane=15",
1470 body: storeLane(wasm.OpcodeVecV128Store8Lane, 100, 0, 15),
1471 expected: NewOperationV128StoreLane(15, 8, MemoryArg{Alignment: 0, Offset: 100}),
1472 },
1473 {
1474 name: wasm.OpcodeVecV128Store16LaneName,
1475 body: storeLane(wasm.OpcodeVecV128Store16Lane, 0, 0, 0),
1476 expected: NewOperationV128StoreLane(0, 16, MemoryArg{Alignment: 0, Offset: 0}),
1477 },
1478 {
1479 name: wasm.OpcodeVecV128Store16LaneName + "/lane=7/align=1",
1480 body: storeLane(wasm.OpcodeVecV128Store16Lane, 100, 1, 7),
1481 expected: NewOperationV128StoreLane(7, 16, MemoryArg{Alignment: 1, Offset: 100}),
1482 },
1483 {
1484 name: wasm.OpcodeVecV128Store32LaneName,
1485 body: storeLane(wasm.OpcodeVecV128Store32Lane, 0, 0, 0),
1486 expected: NewOperationV128StoreLane(0, 32, MemoryArg{Alignment: 0, Offset: 0}),
1487 },
1488 {
1489 name: wasm.OpcodeVecV128Store32LaneName + "/lane=3/align=2",
1490 body: storeLane(wasm.OpcodeVecV128Store32Lane, 100, 2, 3),
1491 expected: NewOperationV128StoreLane(3, 32, MemoryArg{Alignment: 2, Offset: 100}),
1492 },
1493 {
1494 name: wasm.OpcodeVecV128Store64LaneName,
1495 body: storeLane(wasm.OpcodeVecV128Store64Lane, 0, 0, 0),
1496 expected: NewOperationV128StoreLane(0, 64, MemoryArg{Alignment: 0, Offset: 0}),
1497 },
1498 {
1499 name: wasm.OpcodeVecV128Store64LaneName + "/lane=1/align=3",
1500 body: storeLane(wasm.OpcodeVecV128Store64Lane, 50, 3, 1),
1501 expected: NewOperationV128StoreLane(1, 64, MemoryArg{Alignment: 3, Offset: 50}),
1502 },
1503 {
1504 name: wasm.OpcodeVecI8x16ExtractLaneSName,
1505 body: extractLane(wasm.OpcodeVecI8x16ExtractLaneS, 0),
1506 expected: NewOperationV128ExtractLane(0, true, ShapeI8x16),
1507 needDropBeforeReturn: true,
1508 },
1509 {
1510 name: wasm.OpcodeVecI8x16ExtractLaneSName + "/lane=15",
1511 body: extractLane(wasm.OpcodeVecI8x16ExtractLaneS, 15),
1512 expected: NewOperationV128ExtractLane(15, true, ShapeI8x16),
1513 needDropBeforeReturn: true,
1514 },
1515 {
1516 name: wasm.OpcodeVecI8x16ExtractLaneUName,
1517 body: extractLane(wasm.OpcodeVecI8x16ExtractLaneU, 0),
1518 expected: NewOperationV128ExtractLane(0, false, ShapeI8x16),
1519 needDropBeforeReturn: true,
1520 },
1521 {
1522 name: wasm.OpcodeVecI8x16ExtractLaneUName + "/lane=15",
1523 body: extractLane(wasm.OpcodeVecI8x16ExtractLaneU, 15),
1524 expected: NewOperationV128ExtractLane(15, false, ShapeI8x16),
1525 needDropBeforeReturn: true,
1526 },
1527 {
1528 name: wasm.OpcodeVecI16x8ExtractLaneSName,
1529 body: extractLane(wasm.OpcodeVecI16x8ExtractLaneS, 0),
1530 expected: NewOperationV128ExtractLane(0, true, ShapeI16x8),
1531 needDropBeforeReturn: true,
1532 },
1533 {
1534 name: wasm.OpcodeVecI16x8ExtractLaneSName + "/lane=7",
1535 body: extractLane(wasm.OpcodeVecI16x8ExtractLaneS, 7),
1536 expected: NewOperationV128ExtractLane(7, true, ShapeI16x8),
1537 needDropBeforeReturn: true,
1538 },
1539 {
1540 name: wasm.OpcodeVecI16x8ExtractLaneUName,
1541 body: extractLane(wasm.OpcodeVecI16x8ExtractLaneU, 0),
1542 expected: NewOperationV128ExtractLane(0, false, ShapeI16x8),
1543 needDropBeforeReturn: true,
1544 },
1545 {
1546 name: wasm.OpcodeVecI16x8ExtractLaneUName + "/lane=7",
1547 body: extractLane(wasm.OpcodeVecI16x8ExtractLaneU, 7),
1548 expected: NewOperationV128ExtractLane(7, false, ShapeI16x8),
1549 needDropBeforeReturn: true,
1550 },
1551 {
1552 name: wasm.OpcodeVecI32x4ExtractLaneName,
1553 body: extractLane(wasm.OpcodeVecI32x4ExtractLane, 0),
1554 expected: NewOperationV128ExtractLane(0, false, ShapeI32x4),
1555 needDropBeforeReturn: true,
1556 },
1557 {
1558 name: wasm.OpcodeVecI32x4ExtractLaneName + "/lane=3",
1559 body: extractLane(wasm.OpcodeVecI32x4ExtractLane, 3),
1560 expected: NewOperationV128ExtractLane(3, false, ShapeI32x4),
1561 needDropBeforeReturn: true,
1562 },
1563 {
1564 name: wasm.OpcodeVecI64x2ExtractLaneName,
1565 body: extractLane(wasm.OpcodeVecI64x2ExtractLane, 0),
1566 expected: NewOperationV128ExtractLane(0, false, ShapeI64x2),
1567 needDropBeforeReturn: true,
1568 },
1569 {
1570 name: wasm.OpcodeVecI64x2ExtractLaneName + "/lane=1",
1571 body: extractLane(wasm.OpcodeVecI64x2ExtractLane, 1),
1572 expected: NewOperationV128ExtractLane(1, false, ShapeI64x2),
1573 needDropBeforeReturn: true,
1574 },
1575 {
1576 name: wasm.OpcodeVecF32x4ExtractLaneName,
1577 body: extractLane(wasm.OpcodeVecF32x4ExtractLane, 0),
1578 expected: NewOperationV128ExtractLane(0, false, ShapeF32x4),
1579 needDropBeforeReturn: true,
1580 },
1581 {
1582 name: wasm.OpcodeVecF32x4ExtractLaneName + "/lane=3",
1583 body: extractLane(wasm.OpcodeVecF32x4ExtractLane, 3),
1584 expected: NewOperationV128ExtractLane(3, false, ShapeF32x4),
1585 needDropBeforeReturn: true,
1586 },
1587 {
1588 name: wasm.OpcodeVecF64x2ExtractLaneName,
1589 body: extractLane(wasm.OpcodeVecF64x2ExtractLane, 0),
1590 expected: NewOperationV128ExtractLane(0, false, ShapeF64x2),
1591 needDropBeforeReturn: true,
1592 },
1593 {
1594 name: wasm.OpcodeVecF64x2ExtractLaneName + "/lane=1",
1595 body: extractLane(wasm.OpcodeVecF64x2ExtractLane, 1),
1596 expected: NewOperationV128ExtractLane(1, false, ShapeF64x2),
1597 needDropBeforeReturn: true,
1598 },
1599
1600 {
1601 name: wasm.OpcodeVecI8x16ReplaceLaneName,
1602 body: replaceLane(wasm.OpcodeVecI8x16ReplaceLane, 0),
1603 expected: NewOperationV128ReplaceLane(0, ShapeI8x16),
1604 needDropBeforeReturn: true,
1605 },
1606 {
1607 name: wasm.OpcodeVecI8x16ReplaceLaneName + "/lane=15",
1608 body: replaceLane(wasm.OpcodeVecI8x16ReplaceLane, 15),
1609 expected: NewOperationV128ReplaceLane(15, ShapeI8x16),
1610 needDropBeforeReturn: true,
1611 },
1612 {
1613 name: wasm.OpcodeVecI16x8ReplaceLaneName,
1614 body: replaceLane(wasm.OpcodeVecI16x8ReplaceLane, 0),
1615 expected: NewOperationV128ReplaceLane(0, ShapeI16x8),
1616 needDropBeforeReturn: true,
1617 },
1618 {
1619 name: wasm.OpcodeVecI16x8ReplaceLaneName + "/lane=7",
1620 body: replaceLane(wasm.OpcodeVecI16x8ReplaceLane, 7),
1621 expected: NewOperationV128ReplaceLane(7, ShapeI16x8),
1622 needDropBeforeReturn: true,
1623 },
1624 {
1625 name: wasm.OpcodeVecI32x4ReplaceLaneName,
1626 body: replaceLane(wasm.OpcodeVecI32x4ReplaceLane, 0),
1627 expected: NewOperationV128ReplaceLane(0, ShapeI32x4),
1628 needDropBeforeReturn: true,
1629 },
1630 {
1631 name: wasm.OpcodeVecI32x4ReplaceLaneName + "/lane=3",
1632 body: replaceLane(wasm.OpcodeVecI32x4ReplaceLane, 3),
1633 expected: NewOperationV128ReplaceLane(3, ShapeI32x4),
1634 needDropBeforeReturn: true,
1635 },
1636 {
1637 name: wasm.OpcodeVecI64x2ReplaceLaneName,
1638 body: replaceLane(wasm.OpcodeVecI64x2ReplaceLane, 0),
1639 expected: NewOperationV128ReplaceLane(0, ShapeI64x2),
1640 needDropBeforeReturn: true,
1641 },
1642 {
1643 name: wasm.OpcodeVecI64x2ReplaceLaneName + "/lane=1",
1644 body: replaceLane(wasm.OpcodeVecI64x2ReplaceLane, 1),
1645 expected: NewOperationV128ReplaceLane(1, ShapeI64x2),
1646 needDropBeforeReturn: true,
1647 },
1648 {
1649 name: wasm.OpcodeVecF32x4ReplaceLaneName,
1650 body: replaceLane(wasm.OpcodeVecF32x4ReplaceLane, 0),
1651 expected: NewOperationV128ReplaceLane(0, ShapeF32x4),
1652 needDropBeforeReturn: true,
1653 },
1654 {
1655 name: wasm.OpcodeVecF32x4ReplaceLaneName + "/lane=3",
1656 body: replaceLane(wasm.OpcodeVecF32x4ReplaceLane, 3),
1657 expected: NewOperationV128ReplaceLane(3, ShapeF32x4),
1658 needDropBeforeReturn: true,
1659 },
1660 {
1661 name: wasm.OpcodeVecF64x2ReplaceLaneName,
1662 body: replaceLane(wasm.OpcodeVecF64x2ReplaceLane, 0),
1663 expected: NewOperationV128ReplaceLane(0, ShapeF64x2),
1664 needDropBeforeReturn: true,
1665 },
1666 {
1667 name: wasm.OpcodeVecF64x2ReplaceLaneName + "/lane=1",
1668 body: replaceLane(wasm.OpcodeVecF64x2ReplaceLane, 1),
1669 expected: NewOperationV128ReplaceLane(1, ShapeF64x2),
1670 needDropBeforeReturn: true,
1671 },
1672 {
1673 name: wasm.OpcodeVecI8x16SplatName, body: splat(wasm.OpcodeVecI8x16Splat),
1674 expected: NewOperationV128Splat(ShapeI8x16),
1675 needDropBeforeReturn: true,
1676 },
1677 {
1678 name: wasm.OpcodeVecI16x8SplatName, body: splat(wasm.OpcodeVecI16x8Splat),
1679 expected: NewOperationV128Splat(ShapeI16x8),
1680 needDropBeforeReturn: true,
1681 },
1682 {
1683 name: wasm.OpcodeVecI32x4SplatName, body: splat(wasm.OpcodeVecI32x4Splat),
1684 expected: NewOperationV128Splat(ShapeI32x4),
1685 needDropBeforeReturn: true,
1686 },
1687 {
1688 name: wasm.OpcodeVecI64x2SplatName, body: splat(wasm.OpcodeVecI64x2Splat),
1689 expected: NewOperationV128Splat(ShapeI64x2),
1690 needDropBeforeReturn: true,
1691 },
1692 {
1693 name: wasm.OpcodeVecF32x4SplatName, body: splat(wasm.OpcodeVecF32x4Splat),
1694 expected: NewOperationV128Splat(ShapeF32x4),
1695 needDropBeforeReturn: true,
1696 },
1697 {
1698 name: wasm.OpcodeVecF64x2SplatName, body: splat(wasm.OpcodeVecF64x2Splat),
1699 expected: NewOperationV128Splat(ShapeF64x2),
1700 needDropBeforeReturn: true,
1701 },
1702 {
1703 name: wasm.OpcodeVecI8x16SwizzleName, body: vv2v(wasm.OpcodeVecI8x16Swizzle),
1704 expected: NewOperationV128Swizzle(),
1705 needDropBeforeReturn: true,
1706 },
1707 {
1708 name: wasm.OpcodeVecV128i8x16ShuffleName, body: []byte{
1709 wasm.OpcodeVecPrefix,
1710 wasm.OpcodeVecV128Const, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1711 wasm.OpcodeVecPrefix,
1712 wasm.OpcodeVecV128Const, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1713 wasm.OpcodeVecPrefix,
1714 wasm.OpcodeVecV128i8x16Shuffle,
1715 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1716 wasm.OpcodeDrop,
1717 wasm.OpcodeEnd,
1718 },
1719 expected: NewOperationV128Shuffle([]uint64{
1720 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1721 }),
1722 needDropBeforeReturn: true,
1723 },
1724 {
1725 name: wasm.OpcodeVecV128NotName, body: v2v(wasm.OpcodeVecV128Not),
1726 needDropBeforeReturn: true,
1727 expected: NewOperationV128Not(),
1728 },
1729 {
1730 name: wasm.OpcodeVecV128AndName, body: vv2v(wasm.OpcodeVecV128And),
1731 needDropBeforeReturn: true,
1732 expected: NewOperationV128And(),
1733 },
1734 {
1735 name: wasm.OpcodeVecV128AndNotName, body: vv2v(wasm.OpcodeVecV128AndNot),
1736 needDropBeforeReturn: true,
1737 expected: NewOperationV128AndNot(),
1738 },
1739 {
1740 name: wasm.OpcodeVecV128OrName, body: vv2v(wasm.OpcodeVecV128Or),
1741 needDropBeforeReturn: true,
1742 expected: NewOperationV128Or(),
1743 },
1744 {
1745 name: wasm.OpcodeVecV128XorName, body: vv2v(wasm.OpcodeVecV128Xor),
1746 needDropBeforeReturn: true,
1747 expected: NewOperationV128Xor(),
1748 },
1749 {
1750 name: wasm.OpcodeVecV128BitselectName, body: vvv2v(wasm.OpcodeVecV128Bitselect),
1751 needDropBeforeReturn: true,
1752 expected: NewOperationV128Bitselect(),
1753 },
1754 {
1755 name: wasm.OpcodeVecI8x16ShlName, body: vi2v(wasm.OpcodeVecI8x16Shl),
1756 needDropBeforeReturn: true,
1757 expected: NewOperationV128Shl(ShapeI8x16),
1758 },
1759 {
1760 name: wasm.OpcodeVecI8x16ShrSName, body: vi2v(wasm.OpcodeVecI8x16ShrS),
1761 needDropBeforeReturn: true,
1762 expected: NewOperationV128Shr(ShapeI8x16, true),
1763 },
1764 {
1765 name: wasm.OpcodeVecI8x16ShrUName, body: vi2v(wasm.OpcodeVecI8x16ShrU),
1766 needDropBeforeReturn: true,
1767 expected: NewOperationV128Shr(ShapeI8x16, false),
1768 },
1769 {
1770 name: wasm.OpcodeVecI16x8ShlName, body: vi2v(wasm.OpcodeVecI16x8Shl),
1771 needDropBeforeReturn: true,
1772 expected: NewOperationV128Shl(ShapeI16x8),
1773 },
1774 {
1775 name: wasm.OpcodeVecI16x8ShrSName, body: vi2v(wasm.OpcodeVecI16x8ShrS),
1776 needDropBeforeReturn: true,
1777 expected: NewOperationV128Shr(ShapeI16x8, true),
1778 },
1779 {
1780 name: wasm.OpcodeVecI16x8ShrUName, body: vi2v(wasm.OpcodeVecI16x8ShrU),
1781 needDropBeforeReturn: true,
1782 expected: NewOperationV128Shr(ShapeI16x8, false),
1783 },
1784 {
1785 name: wasm.OpcodeVecI32x4ShlName, body: vi2v(wasm.OpcodeVecI32x4Shl),
1786 needDropBeforeReturn: true,
1787 expected: NewOperationV128Shl(ShapeI32x4),
1788 },
1789 {
1790 name: wasm.OpcodeVecI32x4ShrSName, body: vi2v(wasm.OpcodeVecI32x4ShrS),
1791 needDropBeforeReturn: true,
1792 expected: NewOperationV128Shr(ShapeI32x4, true),
1793 },
1794 {
1795 name: wasm.OpcodeVecI32x4ShrUName, body: vi2v(wasm.OpcodeVecI32x4ShrU),
1796 needDropBeforeReturn: true,
1797 expected: NewOperationV128Shr(ShapeI32x4, false),
1798 },
1799 {
1800 name: wasm.OpcodeVecI64x2ShlName, body: vi2v(wasm.OpcodeVecI64x2Shl),
1801 needDropBeforeReturn: true,
1802 expected: NewOperationV128Shl(ShapeI64x2),
1803 },
1804 {
1805 name: wasm.OpcodeVecI64x2ShrSName, body: vi2v(wasm.OpcodeVecI64x2ShrS),
1806 needDropBeforeReturn: true,
1807 expected: NewOperationV128Shr(ShapeI64x2, true),
1808 },
1809 {
1810 name: wasm.OpcodeVecI64x2ShrUName, body: vi2v(wasm.OpcodeVecI64x2ShrU),
1811 needDropBeforeReturn: true,
1812 expected: NewOperationV128Shr(ShapeI64x2, false),
1813 },
1814 {
1815 name: wasm.OpcodeVecI8x16EqName, body: vv2v(wasm.OpcodeVecI8x16Eq),
1816 needDropBeforeReturn: true,
1817 expected: NewOperationV128Cmp(V128CmpTypeI8x16Eq),
1818 },
1819 {
1820 name: wasm.OpcodeVecI8x16NeName, body: vv2v(wasm.OpcodeVecI8x16Ne),
1821 needDropBeforeReturn: true,
1822 expected: NewOperationV128Cmp(V128CmpTypeI8x16Ne),
1823 },
1824 {
1825 name: wasm.OpcodeVecI8x16LtSName, body: vv2v(wasm.OpcodeVecI8x16LtS),
1826 needDropBeforeReturn: true,
1827 expected: NewOperationV128Cmp(V128CmpTypeI8x16LtS),
1828 },
1829 {
1830 name: wasm.OpcodeVecI8x16LtUName, body: vv2v(wasm.OpcodeVecI8x16LtU),
1831 needDropBeforeReturn: true,
1832 expected: NewOperationV128Cmp(V128CmpTypeI8x16LtU),
1833 },
1834 {
1835 name: wasm.OpcodeVecI8x16GtSName, body: vv2v(wasm.OpcodeVecI8x16GtS),
1836 needDropBeforeReturn: true,
1837 expected: NewOperationV128Cmp(V128CmpTypeI8x16GtS),
1838 },
1839 {
1840 name: wasm.OpcodeVecI8x16GtUName, body: vv2v(wasm.OpcodeVecI8x16GtU),
1841 needDropBeforeReturn: true,
1842 expected: NewOperationV128Cmp(V128CmpTypeI8x16GtU),
1843 },
1844 {
1845 name: wasm.OpcodeVecI8x16LeSName, body: vv2v(wasm.OpcodeVecI8x16LeS),
1846 needDropBeforeReturn: true,
1847 expected: NewOperationV128Cmp(V128CmpTypeI8x16LeS),
1848 },
1849 {
1850 name: wasm.OpcodeVecI8x16LeUName, body: vv2v(wasm.OpcodeVecI8x16LeU),
1851 needDropBeforeReturn: true,
1852 expected: NewOperationV128Cmp(V128CmpTypeI8x16LeU),
1853 },
1854 {
1855 name: wasm.OpcodeVecI8x16GeSName, body: vv2v(wasm.OpcodeVecI8x16GeS),
1856 needDropBeforeReturn: true,
1857 expected: NewOperationV128Cmp(V128CmpTypeI8x16GeS),
1858 },
1859 {
1860 name: wasm.OpcodeVecI8x16GeUName, body: vv2v(wasm.OpcodeVecI8x16GeU),
1861 needDropBeforeReturn: true,
1862 expected: NewOperationV128Cmp(V128CmpTypeI8x16GeU),
1863 },
1864 {
1865 name: wasm.OpcodeVecI16x8EqName, body: vv2v(wasm.OpcodeVecI16x8Eq),
1866 needDropBeforeReturn: true,
1867 expected: NewOperationV128Cmp(V128CmpTypeI16x8Eq),
1868 },
1869 {
1870 name: wasm.OpcodeVecI16x8NeName, body: vv2v(wasm.OpcodeVecI16x8Ne),
1871 needDropBeforeReturn: true,
1872 expected: NewOperationV128Cmp(V128CmpTypeI16x8Ne),
1873 },
1874 {
1875 name: wasm.OpcodeVecI16x8LtSName, body: vv2v(wasm.OpcodeVecI16x8LtS),
1876 needDropBeforeReturn: true,
1877 expected: NewOperationV128Cmp(V128CmpTypeI16x8LtS),
1878 },
1879 {
1880 name: wasm.OpcodeVecI16x8LtUName, body: vv2v(wasm.OpcodeVecI16x8LtU),
1881 needDropBeforeReturn: true,
1882 expected: NewOperationV128Cmp(V128CmpTypeI16x8LtU),
1883 },
1884 {
1885 name: wasm.OpcodeVecI16x8GtSName, body: vv2v(wasm.OpcodeVecI16x8GtS),
1886 needDropBeforeReturn: true,
1887 expected: NewOperationV128Cmp(V128CmpTypeI16x8GtS),
1888 },
1889 {
1890 name: wasm.OpcodeVecI16x8GtUName, body: vv2v(wasm.OpcodeVecI16x8GtU),
1891 needDropBeforeReturn: true,
1892 expected: NewOperationV128Cmp(V128CmpTypeI16x8GtU),
1893 },
1894 {
1895 name: wasm.OpcodeVecI16x8LeSName, body: vv2v(wasm.OpcodeVecI16x8LeS),
1896 needDropBeforeReturn: true,
1897 expected: NewOperationV128Cmp(V128CmpTypeI16x8LeS),
1898 },
1899 {
1900 name: wasm.OpcodeVecI16x8LeUName, body: vv2v(wasm.OpcodeVecI16x8LeU),
1901 needDropBeforeReturn: true,
1902 expected: NewOperationV128Cmp(V128CmpTypeI16x8LeU),
1903 },
1904 {
1905 name: wasm.OpcodeVecI16x8GeSName, body: vv2v(wasm.OpcodeVecI16x8GeS),
1906 needDropBeforeReturn: true,
1907 expected: NewOperationV128Cmp(V128CmpTypeI16x8GeS),
1908 },
1909 {
1910 name: wasm.OpcodeVecI16x8GeUName, body: vv2v(wasm.OpcodeVecI16x8GeU),
1911 needDropBeforeReturn: true,
1912 expected: NewOperationV128Cmp(V128CmpTypeI16x8GeU),
1913 },
1914 {
1915 name: wasm.OpcodeVecI32x4EqName, body: vv2v(wasm.OpcodeVecI32x4Eq),
1916 needDropBeforeReturn: true,
1917 expected: NewOperationV128Cmp(V128CmpTypeI32x4Eq),
1918 },
1919 {
1920 name: wasm.OpcodeVecI32x4NeName, body: vv2v(wasm.OpcodeVecI32x4Ne),
1921 needDropBeforeReturn: true,
1922 expected: NewOperationV128Cmp(V128CmpTypeI32x4Ne),
1923 },
1924 {
1925 name: wasm.OpcodeVecI32x4LtSName, body: vv2v(wasm.OpcodeVecI32x4LtS),
1926 needDropBeforeReturn: true,
1927 expected: NewOperationV128Cmp(V128CmpTypeI32x4LtS),
1928 },
1929 {
1930 name: wasm.OpcodeVecI32x4LtUName, body: vv2v(wasm.OpcodeVecI32x4LtU),
1931 needDropBeforeReturn: true,
1932 expected: NewOperationV128Cmp(V128CmpTypeI32x4LtU),
1933 },
1934 {
1935 name: wasm.OpcodeVecI32x4GtSName, body: vv2v(wasm.OpcodeVecI32x4GtS),
1936 needDropBeforeReturn: true,
1937 expected: NewOperationV128Cmp(V128CmpTypeI32x4GtS),
1938 },
1939 {
1940 name: wasm.OpcodeVecI32x4GtUName, body: vv2v(wasm.OpcodeVecI32x4GtU),
1941 needDropBeforeReturn: true,
1942 expected: NewOperationV128Cmp(V128CmpTypeI32x4GtU),
1943 },
1944 {
1945 name: wasm.OpcodeVecI32x4LeSName, body: vv2v(wasm.OpcodeVecI32x4LeS),
1946 needDropBeforeReturn: true,
1947 expected: NewOperationV128Cmp(V128CmpTypeI32x4LeS),
1948 },
1949 {
1950 name: wasm.OpcodeVecI32x4LeUName, body: vv2v(wasm.OpcodeVecI32x4LeU),
1951 needDropBeforeReturn: true,
1952 expected: NewOperationV128Cmp(V128CmpTypeI32x4LeU),
1953 },
1954 {
1955 name: wasm.OpcodeVecI32x4GeSName, body: vv2v(wasm.OpcodeVecI32x4GeS),
1956 needDropBeforeReturn: true,
1957 expected: NewOperationV128Cmp(V128CmpTypeI32x4GeS),
1958 },
1959 {
1960 name: wasm.OpcodeVecI32x4GeUName, body: vv2v(wasm.OpcodeVecI32x4GeU),
1961 needDropBeforeReturn: true,
1962 expected: NewOperationV128Cmp(V128CmpTypeI32x4GeU),
1963 },
1964 {
1965 name: wasm.OpcodeVecI64x2EqName, body: vv2v(wasm.OpcodeVecI64x2Eq),
1966 needDropBeforeReturn: true,
1967 expected: NewOperationV128Cmp(V128CmpTypeI64x2Eq),
1968 },
1969 {
1970 name: wasm.OpcodeVecI64x2NeName, body: vv2v(wasm.OpcodeVecI64x2Ne),
1971 needDropBeforeReturn: true,
1972 expected: NewOperationV128Cmp(V128CmpTypeI64x2Ne),
1973 },
1974 {
1975 name: wasm.OpcodeVecI64x2LtSName, body: vv2v(wasm.OpcodeVecI64x2LtS),
1976 needDropBeforeReturn: true,
1977 expected: NewOperationV128Cmp(V128CmpTypeI64x2LtS),
1978 },
1979 {
1980 name: wasm.OpcodeVecI64x2GtSName, body: vv2v(wasm.OpcodeVecI64x2GtS),
1981 needDropBeforeReturn: true,
1982 expected: NewOperationV128Cmp(V128CmpTypeI64x2GtS),
1983 },
1984 {
1985 name: wasm.OpcodeVecI64x2LeSName, body: vv2v(wasm.OpcodeVecI64x2LeS),
1986 needDropBeforeReturn: true,
1987 expected: NewOperationV128Cmp(V128CmpTypeI64x2LeS),
1988 },
1989 {
1990 name: wasm.OpcodeVecI64x2GeSName, body: vv2v(wasm.OpcodeVecI64x2GeS),
1991 needDropBeforeReturn: true,
1992 expected: NewOperationV128Cmp(V128CmpTypeI64x2GeS),
1993 },
1994 {
1995 name: wasm.OpcodeVecF32x4EqName, body: vv2v(wasm.OpcodeVecF32x4Eq),
1996 needDropBeforeReturn: true,
1997 expected: NewOperationV128Cmp(V128CmpTypeF32x4Eq),
1998 },
1999 {
2000 name: wasm.OpcodeVecF32x4NeName, body: vv2v(wasm.OpcodeVecF32x4Ne),
2001 needDropBeforeReturn: true,
2002 expected: NewOperationV128Cmp(V128CmpTypeF32x4Ne),
2003 },
2004 {
2005 name: wasm.OpcodeVecF32x4LtName, body: vv2v(wasm.OpcodeVecF32x4Lt),
2006 needDropBeforeReturn: true,
2007 expected: NewOperationV128Cmp(V128CmpTypeF32x4Lt),
2008 },
2009 {
2010 name: wasm.OpcodeVecF32x4GtName, body: vv2v(wasm.OpcodeVecF32x4Gt),
2011 needDropBeforeReturn: true,
2012 expected: NewOperationV128Cmp(V128CmpTypeF32x4Gt),
2013 },
2014 {
2015 name: wasm.OpcodeVecF32x4LeName, body: vv2v(wasm.OpcodeVecF32x4Le),
2016 needDropBeforeReturn: true,
2017 expected: NewOperationV128Cmp(V128CmpTypeF32x4Le),
2018 },
2019 {
2020 name: wasm.OpcodeVecF32x4GeName, body: vv2v(wasm.OpcodeVecF32x4Ge),
2021 needDropBeforeReturn: true,
2022 expected: NewOperationV128Cmp(V128CmpTypeF32x4Ge),
2023 },
2024 {
2025 name: wasm.OpcodeVecF64x2EqName, body: vv2v(wasm.OpcodeVecF64x2Eq),
2026 needDropBeforeReturn: true,
2027 expected: NewOperationV128Cmp(V128CmpTypeF64x2Eq),
2028 },
2029 {
2030 name: wasm.OpcodeVecF64x2NeName, body: vv2v(wasm.OpcodeVecF64x2Ne),
2031 needDropBeforeReturn: true,
2032 expected: NewOperationV128Cmp(V128CmpTypeF64x2Ne),
2033 },
2034 {
2035 name: wasm.OpcodeVecF64x2LtName, body: vv2v(wasm.OpcodeVecF64x2Lt),
2036 needDropBeforeReturn: true,
2037 expected: NewOperationV128Cmp(V128CmpTypeF64x2Lt),
2038 },
2039 {
2040 name: wasm.OpcodeVecF64x2GtName, body: vv2v(wasm.OpcodeVecF64x2Gt),
2041 needDropBeforeReturn: true,
2042 expected: NewOperationV128Cmp(V128CmpTypeF64x2Gt),
2043 },
2044 {
2045 name: wasm.OpcodeVecF64x2LeName, body: vv2v(wasm.OpcodeVecF64x2Le),
2046 needDropBeforeReturn: true,
2047 expected: NewOperationV128Cmp(V128CmpTypeF64x2Le),
2048 },
2049 {
2050 name: wasm.OpcodeVecF64x2GeName, body: vv2v(wasm.OpcodeVecF64x2Ge),
2051 needDropBeforeReturn: true,
2052 expected: NewOperationV128Cmp(V128CmpTypeF64x2Ge),
2053 },
2054 {
2055 name: wasm.OpcodeVecI8x16AllTrueName, body: v2v(wasm.OpcodeVecI8x16AllTrue),
2056 needDropBeforeReturn: true,
2057 expected: NewOperationV128AllTrue(ShapeI8x16),
2058 },
2059 {
2060 name: wasm.OpcodeVecI16x8AllTrueName, body: v2v(wasm.OpcodeVecI16x8AllTrue),
2061 needDropBeforeReturn: true,
2062 expected: NewOperationV128AllTrue(ShapeI16x8),
2063 },
2064 {
2065 name: wasm.OpcodeVecI32x4AllTrueName, body: v2v(wasm.OpcodeVecI32x4AllTrue),
2066 needDropBeforeReturn: true,
2067 expected: NewOperationV128AllTrue(ShapeI32x4),
2068 },
2069 {
2070 name: wasm.OpcodeVecI64x2AllTrueName, body: v2v(wasm.OpcodeVecI64x2AllTrue),
2071 needDropBeforeReturn: true,
2072 expected: NewOperationV128AllTrue(ShapeI64x2),
2073 },
2074 {
2075 name: wasm.OpcodeVecI8x16BitMaskName, body: v2v(wasm.OpcodeVecI8x16BitMask),
2076 needDropBeforeReturn: true, expected: NewOperationV128BitMask(ShapeI8x16),
2077 },
2078 {
2079 name: wasm.OpcodeVecI16x8BitMaskName, body: v2v(wasm.OpcodeVecI16x8BitMask),
2080 needDropBeforeReturn: true, expected: NewOperationV128BitMask(ShapeI16x8),
2081 },
2082 {
2083 name: wasm.OpcodeVecI32x4BitMaskName, body: v2v(wasm.OpcodeVecI32x4BitMask),
2084 needDropBeforeReturn: true, expected: NewOperationV128BitMask(ShapeI32x4),
2085 },
2086 {
2087 name: wasm.OpcodeVecI64x2BitMaskName, body: v2v(wasm.OpcodeVecI64x2BitMask),
2088 needDropBeforeReturn: true, expected: NewOperationV128BitMask(ShapeI64x2),
2089 },
2090 {
2091 name: wasm.OpcodeVecV128AnyTrueName, body: v2v(wasm.OpcodeVecV128AnyTrue),
2092 needDropBeforeReturn: true,
2093 expected: NewOperationV128AnyTrue(),
2094 },
2095 {
2096 name: wasm.OpcodeVecI8x16AddName, body: vv2v(wasm.OpcodeVecI8x16Add),
2097 needDropBeforeReturn: true,
2098 expected: NewOperationV128Add(ShapeI8x16),
2099 },
2100 {
2101 name: wasm.OpcodeVecI8x16AddSatSName, body: vv2v(wasm.OpcodeVecI8x16AddSatS),
2102 needDropBeforeReturn: true,
2103 expected: NewOperationV128AddSat(ShapeI8x16, true),
2104 },
2105 {
2106 name: wasm.OpcodeVecI8x16AddSatUName, body: vv2v(wasm.OpcodeVecI8x16AddSatU),
2107 needDropBeforeReturn: true,
2108 expected: NewOperationV128AddSat(ShapeI8x16, false),
2109 },
2110 {
2111 name: wasm.OpcodeVecI8x16SubName, body: vv2v(wasm.OpcodeVecI8x16Sub),
2112 needDropBeforeReturn: true,
2113 expected: NewOperationV128Sub(ShapeI8x16),
2114 },
2115 {
2116 name: wasm.OpcodeVecI8x16SubSatSName, body: vv2v(wasm.OpcodeVecI8x16SubSatS),
2117 needDropBeforeReturn: true,
2118 expected: NewOperationV128SubSat(ShapeI8x16, true),
2119 },
2120 {
2121 name: wasm.OpcodeVecI8x16SubSatUName, body: vv2v(wasm.OpcodeVecI8x16SubSatU),
2122 needDropBeforeReturn: true,
2123 expected: NewOperationV128SubSat(ShapeI8x16, false),
2124 },
2125 {
2126 name: wasm.OpcodeVecI16x8AddName, body: vv2v(wasm.OpcodeVecI16x8Add),
2127 needDropBeforeReturn: true,
2128 expected: NewOperationV128Add(ShapeI16x8),
2129 },
2130 {
2131 name: wasm.OpcodeVecI16x8AddSatSName, body: vv2v(wasm.OpcodeVecI16x8AddSatS),
2132 needDropBeforeReturn: true,
2133 expected: NewOperationV128AddSat(ShapeI16x8, true),
2134 },
2135 {
2136 name: wasm.OpcodeVecI16x8AddSatUName, body: vv2v(wasm.OpcodeVecI16x8AddSatU),
2137 needDropBeforeReturn: true,
2138 expected: NewOperationV128AddSat(ShapeI16x8, false),
2139 },
2140 {
2141 name: wasm.OpcodeVecI16x8SubName, body: vv2v(wasm.OpcodeVecI16x8Sub),
2142 needDropBeforeReturn: true,
2143 expected: NewOperationV128Sub(ShapeI16x8),
2144 },
2145 {
2146 name: wasm.OpcodeVecI16x8SubSatSName, body: vv2v(wasm.OpcodeVecI16x8SubSatS),
2147 needDropBeforeReturn: true,
2148 expected: NewOperationV128SubSat(ShapeI16x8, true),
2149 },
2150 {
2151 name: wasm.OpcodeVecI16x8SubSatUName, body: vv2v(wasm.OpcodeVecI16x8SubSatU),
2152 needDropBeforeReturn: true,
2153 expected: NewOperationV128SubSat(ShapeI16x8, false),
2154 },
2155 {
2156 name: wasm.OpcodeVecI16x8MulName, body: vv2v(wasm.OpcodeVecI16x8Mul),
2157 needDropBeforeReturn: true,
2158 expected: NewOperationV128Mul(ShapeI16x8),
2159 },
2160 {
2161 name: wasm.OpcodeVecI32x4AddName, body: vv2v(wasm.OpcodeVecI32x4Add),
2162 needDropBeforeReturn: true,
2163 expected: NewOperationV128Add(ShapeI32x4),
2164 },
2165 {
2166 name: wasm.OpcodeVecI32x4SubName, body: vv2v(wasm.OpcodeVecI32x4Sub),
2167 needDropBeforeReturn: true,
2168 expected: NewOperationV128Sub(ShapeI32x4),
2169 },
2170 {
2171 name: wasm.OpcodeVecI32x4MulName, body: vv2v(wasm.OpcodeVecI32x4Mul),
2172 needDropBeforeReturn: true,
2173 expected: NewOperationV128Mul(ShapeI32x4),
2174 },
2175 {
2176 name: wasm.OpcodeVecI64x2AddName, body: vv2v(wasm.OpcodeVecI64x2Add),
2177 needDropBeforeReturn: true,
2178 expected: NewOperationV128Add(ShapeI64x2),
2179 },
2180 {
2181 name: wasm.OpcodeVecI64x2SubName, body: vv2v(wasm.OpcodeVecI64x2Sub),
2182 needDropBeforeReturn: true,
2183 expected: NewOperationV128Sub(ShapeI64x2),
2184 },
2185 {
2186 name: wasm.OpcodeVecI64x2MulName, body: vv2v(wasm.OpcodeVecI64x2Mul),
2187 needDropBeforeReturn: true,
2188 expected: NewOperationV128Mul(ShapeI64x2),
2189 },
2190 {
2191 name: wasm.OpcodeVecF32x4AddName, body: vv2v(wasm.OpcodeVecF32x4Add),
2192 needDropBeforeReturn: true,
2193 expected: NewOperationV128Add(ShapeF32x4),
2194 },
2195 {
2196 name: wasm.OpcodeVecF32x4SubName, body: vv2v(wasm.OpcodeVecF32x4Sub),
2197 needDropBeforeReturn: true,
2198 expected: NewOperationV128Sub(ShapeF32x4),
2199 },
2200 {
2201 name: wasm.OpcodeVecF32x4MulName, body: vv2v(wasm.OpcodeVecF32x4Mul),
2202 needDropBeforeReturn: true,
2203 expected: NewOperationV128Mul(ShapeF32x4),
2204 },
2205 {
2206 name: wasm.OpcodeVecF32x4DivName, body: vv2v(wasm.OpcodeVecF32x4Div),
2207 needDropBeforeReturn: true,
2208 expected: NewOperationV128Div(ShapeF32x4),
2209 },
2210 {
2211 name: wasm.OpcodeVecF64x2AddName, body: vv2v(wasm.OpcodeVecF64x2Add),
2212 needDropBeforeReturn: true,
2213 expected: NewOperationV128Add(ShapeF64x2),
2214 },
2215 {
2216 name: wasm.OpcodeVecF64x2SubName, body: vv2v(wasm.OpcodeVecF64x2Sub),
2217 needDropBeforeReturn: true,
2218 expected: NewOperationV128Sub(ShapeF64x2),
2219 },
2220 {
2221 name: wasm.OpcodeVecF64x2MulName, body: vv2v(wasm.OpcodeVecF64x2Mul),
2222 needDropBeforeReturn: true,
2223 expected: NewOperationV128Mul(ShapeF64x2),
2224 },
2225 {
2226 name: wasm.OpcodeVecF64x2DivName, body: vv2v(wasm.OpcodeVecF64x2Div),
2227 needDropBeforeReturn: true,
2228 expected: NewOperationV128Div(ShapeF64x2),
2229 },
2230 {
2231 name: wasm.OpcodeVecI8x16MinSName, body: vv2v(wasm.OpcodeVecI8x16MinS),
2232 needDropBeforeReturn: true,
2233 expected: NewOperationV128Min(ShapeI8x16, true),
2234 },
2235 {
2236 name: wasm.OpcodeVecI8x16MinUName, body: vv2v(wasm.OpcodeVecI8x16MinU),
2237 needDropBeforeReturn: true,
2238 expected: NewOperationV128Min(ShapeI8x16, false),
2239 },
2240 {
2241 name: wasm.OpcodeVecI8x16MaxSName, body: vv2v(wasm.OpcodeVecI8x16MaxS),
2242 needDropBeforeReturn: true,
2243 expected: NewOperationV128Max(ShapeI8x16, true),
2244 },
2245 {
2246 name: wasm.OpcodeVecI8x16MaxUName, body: vv2v(wasm.OpcodeVecI8x16MaxU),
2247 needDropBeforeReturn: true,
2248 expected: NewOperationV128Max(ShapeI8x16, false),
2249 },
2250 {
2251 name: wasm.OpcodeVecI8x16AvgrUName, body: vv2v(wasm.OpcodeVecI8x16AvgrU),
2252 needDropBeforeReturn: true,
2253 expected: NewOperationV128AvgrU(ShapeI8x16),
2254 },
2255 {
2256 name: wasm.OpcodeVecI16x8MinSName, body: vv2v(wasm.OpcodeVecI16x8MinS),
2257 needDropBeforeReturn: true,
2258 expected: NewOperationV128Min(ShapeI16x8, true),
2259 },
2260 {
2261 name: wasm.OpcodeVecI16x8MinUName, body: vv2v(wasm.OpcodeVecI16x8MinU),
2262 needDropBeforeReturn: true,
2263 expected: NewOperationV128Min(ShapeI16x8, false),
2264 },
2265 {
2266 name: wasm.OpcodeVecI16x8MaxSName, body: vv2v(wasm.OpcodeVecI16x8MaxS),
2267 needDropBeforeReturn: true,
2268 expected: NewOperationV128Max(ShapeI16x8, true),
2269 },
2270 {
2271 name: wasm.OpcodeVecI16x8MaxUName, body: vv2v(wasm.OpcodeVecI16x8MaxU),
2272 needDropBeforeReturn: true,
2273 expected: NewOperationV128Max(ShapeI16x8, false),
2274 },
2275 {
2276 name: wasm.OpcodeVecI16x8AvgrUName, body: vv2v(wasm.OpcodeVecI16x8AvgrU),
2277 needDropBeforeReturn: true,
2278 expected: NewOperationV128AvgrU(ShapeI16x8),
2279 },
2280 {
2281 name: wasm.OpcodeVecI32x4MinSName, body: vv2v(wasm.OpcodeVecI32x4MinS),
2282 needDropBeforeReturn: true,
2283 expected: NewOperationV128Min(ShapeI32x4, true),
2284 },
2285 {
2286 name: wasm.OpcodeVecI32x4MinUName, body: vv2v(wasm.OpcodeVecI32x4MinU),
2287 needDropBeforeReturn: true,
2288 expected: NewOperationV128Min(ShapeI32x4, false),
2289 },
2290 {
2291 name: wasm.OpcodeVecI32x4MaxSName, body: vv2v(wasm.OpcodeVecI32x4MaxS),
2292 needDropBeforeReturn: true,
2293 expected: NewOperationV128Max(ShapeI32x4, true),
2294 },
2295 {
2296 name: wasm.OpcodeVecI32x4MaxUName, body: vv2v(wasm.OpcodeVecI32x4MaxU),
2297 needDropBeforeReturn: true,
2298 expected: NewOperationV128Max(ShapeI32x4, false),
2299 },
2300 {
2301 name: wasm.OpcodeVecF32x4MinName, body: vv2v(wasm.OpcodeVecF32x4Min),
2302 needDropBeforeReturn: true,
2303 expected: NewOperationV128Min(ShapeF32x4, false),
2304 },
2305 {
2306 name: wasm.OpcodeVecF32x4MaxName, body: vv2v(wasm.OpcodeVecF32x4Max),
2307 needDropBeforeReturn: true,
2308 expected: NewOperationV128Max(ShapeF32x4, false),
2309 },
2310 {
2311 name: wasm.OpcodeVecF64x2MinName, body: vv2v(wasm.OpcodeVecF64x2Min),
2312 needDropBeforeReturn: true,
2313 expected: NewOperationV128Min(ShapeF64x2, false),
2314 },
2315 {
2316 name: wasm.OpcodeVecF64x2MaxName, body: vv2v(wasm.OpcodeVecF64x2Max),
2317 needDropBeforeReturn: true,
2318 expected: NewOperationV128Max(ShapeF64x2, false),
2319 },
2320 {
2321 name: wasm.OpcodeVecI8x16AbsName, body: v2v(wasm.OpcodeVecI8x16Abs),
2322 needDropBeforeReturn: true,
2323 expected: NewOperationV128Abs(ShapeI8x16),
2324 },
2325 {
2326 name: wasm.OpcodeVecI8x16PopcntName, body: v2v(wasm.OpcodeVecI8x16Popcnt),
2327 needDropBeforeReturn: true,
2328 expected: NewOperationV128Popcnt(ShapeI8x16),
2329 },
2330 {
2331 name: wasm.OpcodeVecI16x8AbsName, body: v2v(wasm.OpcodeVecI16x8Abs),
2332 needDropBeforeReturn: true,
2333 expected: NewOperationV128Abs(ShapeI16x8),
2334 },
2335 {
2336 name: wasm.OpcodeVecI32x4AbsName, body: v2v(wasm.OpcodeVecI32x4Abs),
2337 needDropBeforeReturn: true,
2338 expected: NewOperationV128Abs(ShapeI32x4),
2339 },
2340 {
2341 name: wasm.OpcodeVecI64x2AbsName, body: v2v(wasm.OpcodeVecI64x2Abs),
2342 needDropBeforeReturn: true,
2343 expected: NewOperationV128Abs(ShapeI64x2),
2344 },
2345 {
2346 name: wasm.OpcodeVecF32x4AbsName, body: v2v(wasm.OpcodeVecF32x4Abs),
2347 needDropBeforeReturn: true,
2348 expected: NewOperationV128Abs(ShapeF32x4),
2349 },
2350 {
2351 name: wasm.OpcodeVecF64x2AbsName, body: v2v(wasm.OpcodeVecF64x2Abs),
2352 needDropBeforeReturn: true,
2353 expected: NewOperationV128Abs(ShapeF64x2),
2354 },
2355 {
2356 name: wasm.OpcodeVecF32x4CeilName, body: v2v(wasm.OpcodeVecF32x4Ceil),
2357 needDropBeforeReturn: true,
2358 expected: NewOperationV128Ceil(ShapeF32x4),
2359 },
2360 {
2361 name: wasm.OpcodeVecF32x4FloorName, body: v2v(wasm.OpcodeVecF32x4Floor),
2362 needDropBeforeReturn: true,
2363 expected: NewOperationV128Floor(ShapeF32x4),
2364 },
2365 {
2366 name: wasm.OpcodeVecF32x4TruncName, body: v2v(wasm.OpcodeVecF32x4Trunc),
2367 needDropBeforeReturn: true,
2368 expected: NewOperationV128Trunc(ShapeF32x4),
2369 },
2370 {
2371 name: wasm.OpcodeVecF32x4NearestName, body: v2v(wasm.OpcodeVecF32x4Nearest),
2372 needDropBeforeReturn: true,
2373 expected: NewOperationV128Nearest(ShapeF32x4),
2374 },
2375 {
2376 name: wasm.OpcodeVecF64x2CeilName, body: v2v(wasm.OpcodeVecF64x2Ceil),
2377 needDropBeforeReturn: true,
2378 expected: NewOperationV128Ceil(ShapeF64x2),
2379 },
2380 {
2381 name: wasm.OpcodeVecF64x2FloorName, body: v2v(wasm.OpcodeVecF64x2Floor),
2382 needDropBeforeReturn: true,
2383 expected: NewOperationV128Floor(ShapeF64x2),
2384 },
2385 {
2386 name: wasm.OpcodeVecF64x2TruncName, body: v2v(wasm.OpcodeVecF64x2Trunc),
2387 needDropBeforeReturn: true,
2388 expected: NewOperationV128Trunc(ShapeF64x2),
2389 },
2390 {
2391 name: wasm.OpcodeVecF64x2NearestName, body: v2v(wasm.OpcodeVecF64x2Nearest),
2392 needDropBeforeReturn: true,
2393 expected: NewOperationV128Nearest(ShapeF64x2),
2394 },
2395 {
2396 name: wasm.OpcodeVecF32x4PminName, body: vv2v(wasm.OpcodeVecF32x4Pmin),
2397 needDropBeforeReturn: true,
2398 expected: NewOperationV128Pmin(ShapeF32x4),
2399 },
2400 {
2401 name: wasm.OpcodeVecF32x4PmaxName, body: vv2v(wasm.OpcodeVecF32x4Pmax),
2402 needDropBeforeReturn: true,
2403 expected: NewOperationV128Pmax(ShapeF32x4),
2404 },
2405 {
2406 name: wasm.OpcodeVecF64x2PminName, body: vv2v(wasm.OpcodeVecF64x2Pmin),
2407 needDropBeforeReturn: true,
2408 expected: NewOperationV128Pmin(ShapeF64x2),
2409 },
2410 {
2411 name: wasm.OpcodeVecF64x2PmaxName, body: vv2v(wasm.OpcodeVecF64x2Pmax),
2412 needDropBeforeReturn: true,
2413 expected: NewOperationV128Pmax(ShapeF64x2),
2414 },
2415 {
2416 name: wasm.OpcodeVecI16x8Q15mulrSatSName, body: vv2v(wasm.OpcodeVecI16x8Q15mulrSatS),
2417 needDropBeforeReturn: true,
2418 expected: NewOperationV128Q15mulrSatS(),
2419 },
2420 {
2421 name: wasm.OpcodeVecI16x8ExtMulLowI8x16SName, body: vv2v(wasm.OpcodeVecI16x8ExtMulLowI8x16S),
2422 needDropBeforeReturn: true,
2423 expected: NewOperationV128ExtMul(ShapeI8x16, true, true),
2424 },
2425 {
2426 name: wasm.OpcodeVecI16x8ExtMulHighI8x16SName, body: vv2v(wasm.OpcodeVecI16x8ExtMulHighI8x16S),
2427 needDropBeforeReturn: true,
2428 expected: NewOperationV128ExtMul(ShapeI8x16, true, false),
2429 },
2430 {
2431 name: wasm.OpcodeVecI16x8ExtMulLowI8x16UName, body: vv2v(wasm.OpcodeVecI16x8ExtMulLowI8x16U),
2432 needDropBeforeReturn: true,
2433 expected: NewOperationV128ExtMul(ShapeI8x16, false, true),
2434 },
2435 {
2436 name: wasm.OpcodeVecI16x8ExtMulHighI8x16UName, body: vv2v(wasm.OpcodeVecI16x8ExtMulHighI8x16U),
2437 needDropBeforeReturn: true,
2438 expected: NewOperationV128ExtMul(ShapeI8x16, false, false),
2439 },
2440 {
2441 name: wasm.OpcodeVecI32x4ExtMulLowI16x8SName, body: vv2v(wasm.OpcodeVecI32x4ExtMulLowI16x8S),
2442 needDropBeforeReturn: true,
2443 expected: NewOperationV128ExtMul(ShapeI16x8, true, true),
2444 },
2445 {
2446 name: wasm.OpcodeVecI32x4ExtMulHighI16x8SName, body: vv2v(wasm.OpcodeVecI32x4ExtMulHighI16x8S),
2447 needDropBeforeReturn: true,
2448 expected: NewOperationV128ExtMul(ShapeI16x8, true, false),
2449 },
2450 {
2451 name: wasm.OpcodeVecI32x4ExtMulLowI16x8UName, body: vv2v(wasm.OpcodeVecI32x4ExtMulLowI16x8U),
2452 needDropBeforeReturn: true,
2453 expected: NewOperationV128ExtMul(ShapeI16x8, false, true),
2454 },
2455 {
2456 name: wasm.OpcodeVecI32x4ExtMulHighI16x8UName, body: vv2v(wasm.OpcodeVecI32x4ExtMulHighI16x8U),
2457 needDropBeforeReturn: true,
2458 expected: NewOperationV128ExtMul(ShapeI16x8, false, false),
2459 },
2460 {
2461 name: wasm.OpcodeVecI64x2ExtMulLowI32x4SName, body: vv2v(wasm.OpcodeVecI64x2ExtMulLowI32x4S),
2462 needDropBeforeReturn: true,
2463 expected: NewOperationV128ExtMul(ShapeI32x4, true, true),
2464 },
2465 {
2466 name: wasm.OpcodeVecI64x2ExtMulHighI32x4SName, body: vv2v(wasm.OpcodeVecI64x2ExtMulHighI32x4S),
2467 needDropBeforeReturn: true,
2468 expected: NewOperationV128ExtMul(ShapeI32x4, true, false),
2469 },
2470 {
2471 name: wasm.OpcodeVecI64x2ExtMulLowI32x4UName, body: vv2v(wasm.OpcodeVecI64x2ExtMulLowI32x4U),
2472 needDropBeforeReturn: true,
2473 expected: NewOperationV128ExtMul(ShapeI32x4, false, true),
2474 },
2475 {
2476 name: wasm.OpcodeVecI64x2ExtMulHighI32x4UName, body: vv2v(wasm.OpcodeVecI64x2ExtMulHighI32x4U),
2477 needDropBeforeReturn: true,
2478 expected: NewOperationV128ExtMul(ShapeI32x4, false, false),
2479 },
2480 {
2481 name: wasm.OpcodeVecI16x8ExtendLowI8x16SName, body: v2v(wasm.OpcodeVecI16x8ExtendLowI8x16S),
2482 needDropBeforeReturn: true,
2483 expected: NewOperationV128Extend(ShapeI8x16, true, true),
2484 },
2485 {
2486 name: wasm.OpcodeVecI16x8ExtendHighI8x16SName, body: v2v(wasm.OpcodeVecI16x8ExtendHighI8x16S),
2487 needDropBeforeReturn: true,
2488 expected: NewOperationV128Extend(ShapeI8x16, true, false),
2489 },
2490 {
2491 name: wasm.OpcodeVecI16x8ExtendLowI8x16UName, body: v2v(wasm.OpcodeVecI16x8ExtendLowI8x16U),
2492 needDropBeforeReturn: true,
2493 expected: NewOperationV128Extend(ShapeI8x16, false, true),
2494 },
2495 {
2496 name: wasm.OpcodeVecI16x8ExtendHighI8x16UName, body: v2v(wasm.OpcodeVecI16x8ExtendHighI8x16U),
2497 needDropBeforeReturn: true,
2498 expected: NewOperationV128Extend(ShapeI8x16, false, false),
2499 },
2500 {
2501 name: wasm.OpcodeVecI32x4ExtendLowI16x8SName, body: v2v(wasm.OpcodeVecI32x4ExtendLowI16x8S),
2502 needDropBeforeReturn: true,
2503 expected: NewOperationV128Extend(ShapeI16x8, true, true),
2504 },
2505 {
2506 name: wasm.OpcodeVecI32x4ExtendHighI16x8SName, body: v2v(wasm.OpcodeVecI32x4ExtendHighI16x8S),
2507 needDropBeforeReturn: true,
2508 expected: NewOperationV128Extend(ShapeI16x8, true, false),
2509 },
2510 {
2511 name: wasm.OpcodeVecI32x4ExtendLowI16x8UName, body: v2v(wasm.OpcodeVecI32x4ExtendLowI16x8U),
2512 needDropBeforeReturn: true,
2513 expected: NewOperationV128Extend(ShapeI16x8, false, true),
2514 },
2515 {
2516 name: wasm.OpcodeVecI32x4ExtendHighI16x8UName, body: v2v(wasm.OpcodeVecI32x4ExtendHighI16x8U),
2517 needDropBeforeReturn: true,
2518 expected: NewOperationV128Extend(ShapeI16x8, false, false),
2519 },
2520 {
2521 name: wasm.OpcodeVecI64x2ExtendLowI32x4SName, body: v2v(wasm.OpcodeVecI64x2ExtendLowI32x4S),
2522 needDropBeforeReturn: true,
2523 expected: NewOperationV128Extend(ShapeI32x4, true, true),
2524 },
2525 {
2526 name: wasm.OpcodeVecI64x2ExtendHighI32x4SName, body: v2v(wasm.OpcodeVecI64x2ExtendHighI32x4S),
2527 needDropBeforeReturn: true,
2528 expected: NewOperationV128Extend(ShapeI32x4, true, false),
2529 },
2530 {
2531 name: wasm.OpcodeVecI64x2ExtendLowI32x4UName, body: v2v(wasm.OpcodeVecI64x2ExtendLowI32x4U),
2532 needDropBeforeReturn: true,
2533 expected: NewOperationV128Extend(ShapeI32x4, false, true),
2534 },
2535 {
2536 name: wasm.OpcodeVecI64x2ExtendHighI32x4UName, body: v2v(wasm.OpcodeVecI64x2ExtendHighI32x4U),
2537 needDropBeforeReturn: true,
2538 expected: NewOperationV128Extend(ShapeI32x4, false, false),
2539 },
2540
2541 {
2542 name: wasm.OpcodeVecI16x8ExtaddPairwiseI8x16SName, body: v2v(wasm.OpcodeVecI16x8ExtaddPairwiseI8x16S),
2543 needDropBeforeReturn: true,
2544 expected: NewOperationV128ExtAddPairwise(ShapeI8x16, true),
2545 },
2546 {
2547 name: wasm.OpcodeVecI16x8ExtaddPairwiseI8x16UName, body: v2v(wasm.OpcodeVecI16x8ExtaddPairwiseI8x16U),
2548 needDropBeforeReturn: true,
2549 expected: NewOperationV128ExtAddPairwise(ShapeI8x16, false),
2550 },
2551 {
2552 name: wasm.OpcodeVecI32x4ExtaddPairwiseI16x8SName, body: v2v(wasm.OpcodeVecI32x4ExtaddPairwiseI16x8S),
2553 needDropBeforeReturn: true,
2554 expected: NewOperationV128ExtAddPairwise(ShapeI16x8, true),
2555 },
2556 {
2557 name: wasm.OpcodeVecI32x4ExtaddPairwiseI16x8UName, body: v2v(wasm.OpcodeVecI32x4ExtaddPairwiseI16x8U),
2558 needDropBeforeReturn: true,
2559 expected: NewOperationV128ExtAddPairwise(ShapeI16x8, false),
2560 },
2561 {
2562 name: wasm.OpcodeVecF64x2PromoteLowF32x4ZeroName, body: v2v(wasm.OpcodeVecF64x2PromoteLowF32x4Zero),
2563 needDropBeforeReturn: true,
2564 expected: NewOperationV128FloatPromote(),
2565 },
2566 {
2567 name: wasm.OpcodeVecF32x4DemoteF64x2ZeroName, body: v2v(wasm.OpcodeVecF32x4DemoteF64x2Zero),
2568 needDropBeforeReturn: true,
2569 expected: NewOperationV128FloatDemote(),
2570 },
2571 {
2572 name: wasm.OpcodeVecF32x4ConvertI32x4SName, body: v2v(wasm.OpcodeVecF32x4ConvertI32x4S),
2573 needDropBeforeReturn: true,
2574 expected: NewOperationV128FConvertFromI(ShapeF32x4, true),
2575 },
2576 {
2577 name: wasm.OpcodeVecF32x4ConvertI32x4UName, body: v2v(wasm.OpcodeVecF32x4ConvertI32x4U),
2578 needDropBeforeReturn: true,
2579 expected: NewOperationV128FConvertFromI(ShapeF32x4, false),
2580 },
2581 {
2582 name: wasm.OpcodeVecF64x2ConvertLowI32x4SName, body: v2v(wasm.OpcodeVecF64x2ConvertLowI32x4S),
2583 needDropBeforeReturn: true,
2584 expected: NewOperationV128FConvertFromI(ShapeF64x2, true),
2585 },
2586 {
2587 name: wasm.OpcodeVecF64x2ConvertLowI32x4UName, body: v2v(wasm.OpcodeVecF64x2ConvertLowI32x4U),
2588 needDropBeforeReturn: true,
2589 expected: NewOperationV128FConvertFromI(ShapeF64x2, false),
2590 },
2591 {
2592 name: wasm.OpcodeVecI32x4DotI16x8SName, body: vv2v(wasm.OpcodeVecI32x4DotI16x8S),
2593 needDropBeforeReturn: true,
2594 expected: NewOperationV128Dot(),
2595 },
2596 {
2597 name: wasm.OpcodeVecI8x16NarrowI16x8SName, body: vv2v(wasm.OpcodeVecI8x16NarrowI16x8S),
2598 needDropBeforeReturn: true,
2599 expected: NewOperationV128Narrow(ShapeI16x8, true),
2600 },
2601 {
2602 name: wasm.OpcodeVecI8x16NarrowI16x8UName, body: vv2v(wasm.OpcodeVecI8x16NarrowI16x8U),
2603 needDropBeforeReturn: true,
2604 expected: NewOperationV128Narrow(ShapeI16x8, false),
2605 },
2606 {
2607 name: wasm.OpcodeVecI16x8NarrowI32x4SName, body: vv2v(wasm.OpcodeVecI16x8NarrowI32x4S),
2608 needDropBeforeReturn: true,
2609 expected: NewOperationV128Narrow(ShapeI32x4, true),
2610 },
2611 {
2612 name: wasm.OpcodeVecI16x8NarrowI32x4UName, body: vv2v(wasm.OpcodeVecI16x8NarrowI32x4U),
2613 needDropBeforeReturn: true,
2614 expected: NewOperationV128Narrow(ShapeI32x4, false),
2615 },
2616 {
2617 name: wasm.OpcodeVecI32x4TruncSatF32x4SName, body: v2v(wasm.OpcodeVecI32x4TruncSatF32x4S),
2618 needDropBeforeReturn: true,
2619 expected: NewOperationV128ITruncSatFromF(ShapeF32x4, true),
2620 },
2621 {
2622 name: wasm.OpcodeVecI32x4TruncSatF32x4UName, body: v2v(wasm.OpcodeVecI32x4TruncSatF32x4U),
2623 needDropBeforeReturn: true,
2624 expected: NewOperationV128ITruncSatFromF(ShapeF32x4, false),
2625 },
2626 {
2627 name: wasm.OpcodeVecI32x4TruncSatF64x2SZeroName, body: v2v(wasm.OpcodeVecI32x4TruncSatF64x2SZero),
2628 needDropBeforeReturn: true,
2629 expected: NewOperationV128ITruncSatFromF(ShapeF64x2, true),
2630 },
2631 {
2632 name: wasm.OpcodeVecI32x4TruncSatF64x2UZeroName, body: v2v(wasm.OpcodeVecI32x4TruncSatF64x2UZero),
2633 needDropBeforeReturn: true,
2634 expected: NewOperationV128ITruncSatFromF(ShapeF64x2, false),
2635 },
2636 }
2637
2638 for _, tt := range tests {
2639 tc := tt
2640 t.Run(tc.name, func(t *testing.T) {
2641 module := &wasm.Module{
2642 TypeSection: []wasm.FunctionType{v_v},
2643 FunctionSection: []wasm.Index{0},
2644 MemorySection: &wasm.Memory{},
2645 CodeSection: []wasm.Code{{Body: tc.body}},
2646 }
2647 c, err := NewCompiler(api.CoreFeaturesV2, 0, module, false)
2648 require.NoError(t, err)
2649
2650 res, err := c.Next()
2651 require.NoError(t, err)
2652
2653 var actual UnionOperation
2654 if tc.needDropBeforeReturn {
2655
2656
2657 actual = res.Operations[len(res.Operations)-3]
2658 } else {
2659
2660
2661 actual = res.Operations[len(res.Operations)-2]
2662 }
2663
2664 require.Equal(t, tc.expected, actual)
2665 })
2666 }
2667 }
2668
2669
2670 func TestCompile_unreachable_Br_BrIf_BrTable(t *testing.T) {
2671 tests := []struct {
2672 name string
2673 mod *wasm.Module
2674 expected []UnionOperation
2675 }{
2676 {
2677 name: "br",
2678 mod: &wasm.Module{
2679 TypeSection: []wasm.FunctionType{v_v},
2680 FunctionSection: []wasm.Index{0},
2681 CodeSection: []wasm.Code{{Body: []byte{
2682 wasm.OpcodeBr, 0,
2683 wasm.OpcodeBlock, 0,
2684 wasm.OpcodeBr, 1,
2685 wasm.OpcodeEnd,
2686 wasm.OpcodeEnd,
2687 }}},
2688 },
2689 expected: []UnionOperation{NewOperationBr(NewLabel(LabelKindReturn, 0))},
2690 },
2691 {
2692 name: "br_if",
2693 mod: &wasm.Module{
2694 TypeSection: []wasm.FunctionType{v_v},
2695 FunctionSection: []wasm.Index{0},
2696 CodeSection: []wasm.Code{{Body: []byte{
2697 wasm.OpcodeBr, 0,
2698 wasm.OpcodeBlock, 0,
2699 wasm.OpcodeI32Const, 1,
2700 wasm.OpcodeBrIf, 1,
2701 wasm.OpcodeEnd,
2702 wasm.OpcodeEnd,
2703 }}},
2704 },
2705 expected: []UnionOperation{NewOperationBr(NewLabel(LabelKindReturn, 0))},
2706 },
2707 {
2708 name: "br_table",
2709 mod: &wasm.Module{
2710 TypeSection: []wasm.FunctionType{v_v},
2711 FunctionSection: []wasm.Index{0},
2712 CodeSection: []wasm.Code{{Body: []byte{
2713 wasm.OpcodeBr, 0,
2714 wasm.OpcodeBlock, 0,
2715 wasm.OpcodeBrTable, 2, 2, 3,
2716 wasm.OpcodeEnd,
2717 wasm.OpcodeEnd,
2718 }}},
2719 },
2720 expected: []UnionOperation{NewOperationBr(NewLabel(LabelKindReturn, 0))},
2721 },
2722 }
2723
2724 for _, tt := range tests {
2725 tc := tt
2726 t.Run(tc.name, func(t *testing.T) {
2727 c, err := NewCompiler(api.CoreFeaturesV2, 0, tc.mod, false)
2728 require.NoError(t, err)
2729
2730 actual, err := c.Next()
2731 require.NoError(t, err)
2732 require.Equal(t, tc.expected, actual.Operations)
2733 })
2734 }
2735 }
2736
2737
2738
2739 func TestCompile_drop_vectors(t *testing.T) {
2740 tests := []struct {
2741 name string
2742 mod *wasm.Module
2743 expected []UnionOperation
2744 }{
2745 {
2746 name: "basic",
2747 mod: &wasm.Module{
2748 TypeSection: []wasm.FunctionType{v_v},
2749 FunctionSection: []wasm.Index{0},
2750 CodeSection: []wasm.Code{{Body: []byte{
2751 wasm.OpcodeVecPrefix,
2752 wasm.OpcodeVecV128Const, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
2753 wasm.OpcodeDrop,
2754 wasm.OpcodeEnd,
2755 }}},
2756 },
2757 expected: []UnionOperation{
2758 NewOperationV128Const(0x1, 0x2),
2759
2760
2761 NewOperationDrop(InclusiveRange{Start: 0, End: 1}),
2762 NewOperationBr(NewLabel(LabelKindReturn, 0)),
2763 },
2764 },
2765 }
2766
2767 for _, tt := range tests {
2768 tc := tt
2769 t.Run(tc.name, func(t *testing.T) {
2770 c, err := NewCompiler(api.CoreFeaturesV2, 0, tc.mod, false)
2771 require.NoError(t, err)
2772
2773 actual, err := c.Next()
2774 require.NoError(t, err)
2775 require.Equal(t, tc.expected, actual.Operations)
2776 })
2777 }
2778 }
2779
2780 func TestCompile_select_vectors(t *testing.T) {
2781 tests := []struct {
2782 name string
2783 mod *wasm.Module
2784 expected []UnionOperation
2785 }{
2786 {
2787 name: "non typed",
2788 mod: &wasm.Module{
2789 TypeSection: []wasm.FunctionType{v_v},
2790 FunctionSection: []wasm.Index{0},
2791 CodeSection: []wasm.Code{{Body: []byte{
2792 wasm.OpcodeVecPrefix,
2793 wasm.OpcodeVecV128Const, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
2794 wasm.OpcodeVecPrefix,
2795 wasm.OpcodeVecV128Const, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
2796 wasm.OpcodeI32Const, 0,
2797 wasm.OpcodeSelect,
2798 wasm.OpcodeDrop,
2799 wasm.OpcodeEnd,
2800 }}},
2801 FunctionDefinitionSection: []wasm.FunctionDefinition{{}},
2802 },
2803 expected: []UnionOperation{
2804 NewOperationV128Const(0x1, 0x2),
2805 NewOperationV128Const(0x3, 0x4),
2806 NewOperationConstI32(0),
2807 NewOperationSelect(true),
2808 NewOperationDrop(InclusiveRange{Start: 0, End: 1}),
2809 NewOperationBr(NewLabel(LabelKindReturn, 0)),
2810 },
2811 },
2812 {
2813 name: "typed",
2814 mod: &wasm.Module{
2815 TypeSection: []wasm.FunctionType{v_v},
2816 FunctionSection: []wasm.Index{0},
2817 CodeSection: []wasm.Code{{Body: []byte{
2818 wasm.OpcodeVecPrefix,
2819 wasm.OpcodeVecV128Const, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
2820 wasm.OpcodeVecPrefix,
2821 wasm.OpcodeVecV128Const, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
2822 wasm.OpcodeI32Const, 0,
2823 wasm.OpcodeTypedSelect, 0x1, wasm.ValueTypeV128,
2824 wasm.OpcodeDrop,
2825 wasm.OpcodeEnd,
2826 }}},
2827 FunctionDefinitionSection: []wasm.FunctionDefinition{{}},
2828 },
2829 expected: []UnionOperation{
2830 NewOperationV128Const(0x1, 0x2),
2831 NewOperationV128Const(0x3, 0x4),
2832 NewOperationConstI32(0),
2833 NewOperationSelect(true),
2834 NewOperationDrop(InclusiveRange{Start: 0, End: 1}),
2835 NewOperationBr(NewLabel(LabelKindReturn, 0)),
2836 },
2837 },
2838 }
2839
2840 for _, tt := range tests {
2841 tc := tt
2842 t.Run(tc.name, func(t *testing.T) {
2843 c, err := NewCompiler(api.CoreFeaturesV2, 0, tc.mod, false)
2844 require.NoError(t, err)
2845
2846 actual, err := c.Next()
2847 require.NoError(t, err)
2848 require.Equal(t, tc.expected, actual.Operations)
2849 })
2850 }
2851 }
2852
2853 func TestCompiler_initializeStack(t *testing.T) {
2854 const v128 = wasm.ValueTypeV128
2855 tests := []struct {
2856 name string
2857 sig *wasm.FunctionType
2858 functionLocalTypes []wasm.ValueType
2859 callFrameStackSizeInUint64 int
2860 expLocalIndexToStackHeightInUint64 []int
2861 }{
2862 {
2863 name: "no function local, args>results",
2864 sig: &wasm.FunctionType{
2865 Params: []wasm.ValueType{i32, f32},
2866 Results: []wasm.ValueType{i32},
2867 ParamNumInUint64: 2,
2868 ResultNumInUint64: 1,
2869 },
2870 expLocalIndexToStackHeightInUint64: []int{0, 1},
2871 },
2872 {
2873 name: "no function local, args=results",
2874 sig: &wasm.FunctionType{
2875 Params: []wasm.ValueType{i32},
2876 Results: []wasm.ValueType{i32},
2877 ParamNumInUint64: 1,
2878 ResultNumInUint64: 1,
2879 },
2880 expLocalIndexToStackHeightInUint64: []int{0},
2881 },
2882 {
2883 name: "no function local, args>results, with vector",
2884 sig: &wasm.FunctionType{
2885 Params: []wasm.ValueType{i32, v128, f32},
2886 Results: []wasm.ValueType{i32},
2887 ParamNumInUint64: 4,
2888 ResultNumInUint64: 1,
2889 },
2890 expLocalIndexToStackHeightInUint64: []int{0, 1, 3},
2891 },
2892 {
2893 name: "no function local, args<results",
2894 sig: &wasm.FunctionType{
2895 Params: []wasm.ValueType{},
2896 Results: []wasm.ValueType{i32},
2897 ParamNumInUint64: 0,
2898 ResultNumInUint64: 1,
2899 },
2900 callFrameStackSizeInUint64: 4,
2901 expLocalIndexToStackHeightInUint64: nil,
2902 },
2903 {
2904 name: "no function local, args<results",
2905 sig: &wasm.FunctionType{
2906 Params: []wasm.ValueType{i32},
2907 Results: []wasm.ValueType{i32, f32},
2908 ParamNumInUint64: 1,
2909 ResultNumInUint64: 2,
2910 },
2911 callFrameStackSizeInUint64: 4,
2912 expLocalIndexToStackHeightInUint64: []int{0},
2913 },
2914 {
2915 name: "no function local, args<results, with vector",
2916 sig: &wasm.FunctionType{
2917 Params: []wasm.ValueType{i32},
2918 Results: []wasm.ValueType{i32, v128, f32},
2919 ParamNumInUint64: 1,
2920 ResultNumInUint64: 4,
2921 },
2922 callFrameStackSizeInUint64: 4,
2923 expLocalIndexToStackHeightInUint64: []int{0},
2924 },
2925
2926
2927 {
2928 name: "function locals, args>results",
2929 sig: &wasm.FunctionType{
2930 Params: []wasm.ValueType{i32, f32},
2931 Results: []wasm.ValueType{i32},
2932 ParamNumInUint64: 2,
2933 ResultNumInUint64: 1,
2934 },
2935 functionLocalTypes: []wasm.ValueType{f64},
2936 callFrameStackSizeInUint64: 4,
2937
2938 expLocalIndexToStackHeightInUint64: []int{
2939 0,
2940 1,
2941
2942 6,
2943 },
2944 },
2945 {
2946 name: "function locals, args>results, with vector",
2947 sig: &wasm.FunctionType{
2948 Params: []wasm.ValueType{i32, v128, f32},
2949 Results: []wasm.ValueType{i32},
2950 ParamNumInUint64: 4,
2951 ResultNumInUint64: 1,
2952 },
2953 functionLocalTypes: []wasm.ValueType{v128, v128},
2954 callFrameStackSizeInUint64: 4,
2955
2956 expLocalIndexToStackHeightInUint64: []int{
2957 0,
2958 1,
2959 3,
2960
2961 8,
2962 10,
2963 },
2964 },
2965 {
2966 name: "function locals, args<results",
2967 sig: &wasm.FunctionType{
2968 Params: []wasm.ValueType{i32},
2969 Results: []wasm.ValueType{i32, i32, i32, i32},
2970 ParamNumInUint64: 1,
2971 ResultNumInUint64: 4,
2972 },
2973 functionLocalTypes: []wasm.ValueType{f64},
2974 callFrameStackSizeInUint64: 4,
2975
2976 expLocalIndexToStackHeightInUint64: []int{0, 8},
2977 },
2978 {
2979 name: "function locals, args<results with vector",
2980 sig: &wasm.FunctionType{
2981 Params: []wasm.ValueType{v128, f64},
2982 Results: []wasm.ValueType{v128, i32, i32, v128},
2983 ParamNumInUint64: 3,
2984 ResultNumInUint64: 6,
2985 },
2986 functionLocalTypes: []wasm.ValueType{f64},
2987 callFrameStackSizeInUint64: 4,
2988
2989 expLocalIndexToStackHeightInUint64: []int{0, 2, 10},
2990 },
2991 }
2992
2993 for _, tc := range tests {
2994 tc := tc
2995 t.Run(tc.name, func(t *testing.T) {
2996 c := &Compiler{
2997 sig: tc.sig, localTypes: tc.functionLocalTypes,
2998 callFrameStackSizeInUint64: tc.callFrameStackSizeInUint64,
2999 }
3000
3001 c.initializeStack()
3002 require.Equal(t, tc.expLocalIndexToStackHeightInUint64, c.localIndexToStackHeightInUint64)
3003 })
3004 }
3005 }
3006
3007 func Test_ensureTermination(t *testing.T) {
3008 for _, tc := range []struct {
3009 ensureTermination bool
3010 exp string
3011 }{
3012 {
3013 ensureTermination: true,
3014 exp: `.entrypoint
3015 ConstI32 0x0
3016 Br .L2
3017 .L2
3018 BuiltinFunctionCheckExitCode
3019 ConstI32 0x1
3020 BrIf .L2, .L3
3021 .L3
3022 ConstI32 0x1
3023 Br .L4
3024 .L4
3025 BuiltinFunctionCheckExitCode
3026 i32.Add
3027 Drop 0..0
3028 Br .return
3029 `,
3030 },
3031 {
3032 ensureTermination: false,
3033 exp: `.entrypoint
3034 ConstI32 0x0
3035 Br .L2
3036 .L2
3037 ConstI32 0x1
3038 BrIf .L2, .L3
3039 .L3
3040 ConstI32 0x1
3041 Br .L4
3042 .L4
3043 i32.Add
3044 Drop 0..0
3045 Br .return
3046 `,
3047 },
3048 } {
3049 t.Run(fmt.Sprintf("%v", tc.ensureTermination), func(t *testing.T) {
3050 mod := &wasm.Module{
3051 TypeSection: []wasm.FunctionType{v_v},
3052 FunctionSection: []wasm.Index{0},
3053 CodeSection: []wasm.Code{{
3054 Body: []byte{
3055 wasm.OpcodeI32Const, 0,
3056 wasm.OpcodeLoop, 0, wasm.OpcodeI32Const, 1, wasm.OpcodeBrIf, 0, wasm.OpcodeEnd,
3057 wasm.OpcodeI32Const, 1,
3058 wasm.OpcodeLoop, 0, wasm.OpcodeEnd,
3059 wasm.OpcodeI32Add,
3060 wasm.OpcodeDrop,
3061 wasm.OpcodeEnd,
3062 },
3063 }},
3064 }
3065 c, err := NewCompiler(api.CoreFeaturesV2, 0, mod, tc.ensureTermination)
3066 require.NoError(t, err)
3067
3068 actual, err := c.Next()
3069 require.NoError(t, err)
3070 require.Equal(t, tc.exp, Format(actual.Operations))
3071 })
3072 }
3073 }
3074
View as plain text