1 package spectest
2
3 import (
4 "encoding/json"
5 "math"
6 "testing"
7
8 "github.com/tetratelabs/wazero/internal/moremath"
9 "github.com/tetratelabs/wazero/internal/testing/require"
10 "github.com/tetratelabs/wazero/internal/wasm"
11 )
12
13 func Test_f32Equal(t *testing.T) {
14 tests := []struct {
15 f1, f2 float32
16 exp bool
17 }{
18 {f1: 1.1, f2: 1.1, exp: true},
19 {f1: float32(math.NaN()), f2: float32(math.NaN()), exp: true},
20 {f1: float32(math.Inf(1)), f2: float32(math.Inf(1)), exp: true},
21 {f1: float32(math.Inf(-1)), f2: float32(math.Inf(-1)), exp: true},
22 {f1: 1.1, f2: -1.1, exp: false},
23 {f1: float32(math.NaN()), f2: -1.1, exp: false},
24 {f1: -1.1, f2: float32(math.NaN()), exp: false},
25 {f1: float32(math.NaN()), f2: float32(math.Inf(1)), exp: false},
26 {f1: float32(math.Inf(1)), f2: float32(math.NaN()), exp: false},
27 {f1: float32(math.NaN()), f2: float32(math.Inf(-1)), exp: false},
28 {f1: float32(math.Inf(-1)), f2: float32(math.NaN()), exp: false},
29 {
30 f1: math.Float32frombits(moremath.F32CanonicalNaNBits),
31 f2: math.Float32frombits(moremath.F32CanonicalNaNBits),
32 exp: true,
33 },
34 {
35 f1: math.Float32frombits(moremath.F32CanonicalNaNBits),
36 f2: math.Float32frombits(moremath.F32ArithmeticNaNBits),
37 exp: false,
38 },
39 {
40 f1: math.Float32frombits(moremath.F32ArithmeticNaNBits),
41 f2: math.Float32frombits(moremath.F32ArithmeticNaNBits),
42 exp: true,
43 },
44 {
45 f1: math.Float32frombits(moremath.F32ArithmeticNaNBits),
46 f2: math.Float32frombits(moremath.F32ArithmeticNaNBits | 1<<2),
47
48 exp: true,
49 },
50 {
51 f1: math.Float32frombits(moremath.F32CanonicalNaNBits),
52 f2: math.Float32frombits(moremath.F32CanonicalNaNBits | 1<<2),
53
54 exp: false,
55 },
56 }
57
58 for i, tc := range tests {
59 require.Equal(t, tc.exp, f32Equal(tc.f1, tc.f2), i)
60 }
61 }
62
63 func Test_f64Equal(t *testing.T) {
64 tests := []struct {
65 f1, f2 float64
66 exp bool
67 }{
68 {f1: 1.1, f2: 1.1, exp: true},
69 {f1: math.NaN(), f2: math.NaN(), exp: true},
70 {f1: math.Inf(1), f2: math.Inf(1), exp: true},
71 {f1: math.Inf(-1), f2: math.Inf(-1), exp: true},
72 {f1: 1.1, f2: -1.1, exp: false},
73 {f1: math.NaN(), f2: -1.1, exp: false},
74 {f1: -1.1, f2: math.NaN(), exp: false},
75 {f1: math.NaN(), f2: math.Inf(1), exp: false},
76 {f1: math.Inf(1), f2: math.NaN(), exp: false},
77 {f1: math.NaN(), f2: math.Inf(-1), exp: false},
78 {f1: math.Inf(-1), f2: math.NaN(), exp: false},
79 {
80 f1: math.Float64frombits(moremath.F64CanonicalNaNBits),
81 f2: math.Float64frombits(moremath.F64CanonicalNaNBits),
82 exp: true,
83 },
84 {
85 f1: math.Float64frombits(moremath.F64CanonicalNaNBits),
86 f2: math.Float64frombits(moremath.F64ArithmeticNaNBits),
87 exp: false,
88 },
89 {
90 f1: math.Float64frombits(moremath.F64ArithmeticNaNBits),
91 f2: math.Float64frombits(moremath.F64ArithmeticNaNBits),
92 exp: true,
93 },
94 {
95 f1: math.Float64frombits(moremath.F64ArithmeticNaNBits),
96 f2: math.Float64frombits(moremath.F64ArithmeticNaNBits | 1<<2),
97
98 exp: true,
99 },
100 {
101 f1: math.Float64frombits(moremath.F64CanonicalNaNBits),
102 f2: math.Float64frombits(moremath.F64CanonicalNaNBits | 1<<2),
103
104 exp: false,
105 },
106 }
107
108 for i, tc := range tests {
109 require.Equal(t, tc.exp, f64Equal(tc.f1, tc.f2), i)
110 }
111 }
112
113 func Test_valuesEq(t *testing.T) {
114 i32, i64, f32, f64, v128 := wasm.ValueTypeI32, wasm.ValueTypeI64, wasm.ValueTypeF32, wasm.ValueTypeF64, wasm.ValueTypeV128
115 tests := []struct {
116 name string
117 exps, actual []uint64
118 valueTypes []wasm.ValueType
119 laneTypes map[int]laneType
120 expMatched bool
121 expValuesMsg string
122 }{
123 {
124 name: "matched/i32",
125 exps: []uint64{0},
126 actual: []uint64{0},
127 valueTypes: []wasm.ValueType{i32},
128 expMatched: true,
129 },
130 {
131 name: "unmatched/i32",
132 exps: []uint64{1},
133 actual: []uint64{0},
134 valueTypes: []wasm.ValueType{i32},
135 expMatched: false,
136 expValuesMsg: ` have [0]
137 want [1]`,
138 },
139 {
140 name: "unmatched/i32",
141 exps: []uint64{math.MaxUint32},
142 actual: []uint64{1123},
143 valueTypes: []wasm.ValueType{i32},
144 expMatched: false,
145 expValuesMsg: ` have [1123]
146 want [4294967295]`,
147 },
148 {
149 name: "matched/i64",
150 exps: []uint64{0},
151 actual: []uint64{0},
152 valueTypes: []wasm.ValueType{i64},
153 expMatched: true,
154 },
155 {
156 name: "unmatched/i64",
157 exps: []uint64{1},
158 actual: []uint64{0},
159 valueTypes: []wasm.ValueType{i64},
160 expMatched: false,
161 expValuesMsg: ` have [0]
162 want [1]`,
163 },
164 {
165 name: "unmatched/i64",
166 exps: []uint64{math.MaxUint64},
167 actual: []uint64{1123},
168 valueTypes: []wasm.ValueType{i64},
169 expMatched: false,
170 expValuesMsg: ` have [1123]
171 want [18446744073709551615]`,
172 },
173 {
174 name: "matched/f32",
175 exps: []uint64{0},
176 actual: []uint64{0},
177 valueTypes: []wasm.ValueType{f32},
178 expMatched: true,
179 },
180 {
181 name: "unmatched/f32",
182 exps: []uint64{uint64(math.Float32bits(-13123.1))},
183 actual: []uint64{0},
184 valueTypes: []wasm.ValueType{f32},
185 expMatched: false,
186 expValuesMsg: ` have [0.000000]
187 want [-13123.099609]`,
188 },
189 {
190 name: "matched/f64",
191 exps: []uint64{0},
192 actual: []uint64{0},
193 valueTypes: []wasm.ValueType{f64},
194 expMatched: true,
195 },
196 {
197 name: "unmatched/f64",
198 exps: []uint64{math.Float64bits(1.0)},
199 actual: []uint64{0},
200 valueTypes: []wasm.ValueType{f64},
201 expMatched: false,
202 expValuesMsg: ` have [0.000000]
203 want [1.000000]`,
204 },
205 {
206 name: "unmatched/f64",
207 actual: []uint64{math.Float64bits(-1231231.0)},
208 exps: []uint64{0},
209 valueTypes: []wasm.ValueType{f64},
210 expMatched: false,
211 expValuesMsg: ` have [-1231231.000000]
212 want [0.000000]`,
213 },
214 {
215 name: "matched/i8x16",
216 exps: []uint64{math.MaxUint64, 123},
217 actual: []uint64{math.MaxUint64, 123},
218 laneTypes: map[int]laneType{0: laneTypeI8},
219 valueTypes: []wasm.ValueType{v128},
220 expMatched: true,
221 },
222 {
223 name: "unmatched/i8x16",
224 exps: []uint64{0, 0xff<<56 | 0xaa},
225 actual: []uint64{math.MaxUint64, 0xff<<48 | 0xcc},
226 laneTypes: map[int]laneType{0: laneTypeI8},
227 valueTypes: []wasm.ValueType{v128},
228 expMatched: false,
229 expValuesMsg: ` have [i8x16(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0)]
230 want [i8x16(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff)]`,
231 },
232 {
233 name: "matched/i16x8",
234 exps: []uint64{math.MaxUint64, 123},
235 actual: []uint64{math.MaxUint64, 123},
236 laneTypes: map[int]laneType{0: laneTypeI16},
237 valueTypes: []wasm.ValueType{v128},
238 expMatched: true,
239 },
240 {
241 name: "unmatched/i16x8",
242 exps: []uint64{0xffff << 32, 0},
243 actual: []uint64{0xaabb << 16, ^uint64(0)},
244 laneTypes: map[int]laneType{0: laneTypeI16},
245 valueTypes: []wasm.ValueType{v128},
246 expMatched: false,
247 expValuesMsg: ` have [i16x8(0x0, 0xaabb, 0x0, 0x0, 0xffff, 0xffff, 0xffff, 0xffff)]
248 want [i16x8(0x0, 0x0, 0xffff, 0x0, 0x0, 0x0, 0x0, 0x0)]`,
249 },
250 {
251 name: "matched/i32x4",
252 exps: []uint64{math.MaxUint64, 123},
253 actual: []uint64{math.MaxUint64, 123},
254 laneTypes: map[int]laneType{0: laneTypeI32},
255 valueTypes: []wasm.ValueType{v128},
256 expMatched: true,
257 },
258 {
259 name: "matched/i32x4",
260 exps: []uint64{0xffff_ffff<<32 | 0xa, 123},
261 actual: []uint64{0x1a1a_1a1a<<32 | 0xa, 123},
262 laneTypes: map[int]laneType{0: laneTypeI32},
263 valueTypes: []wasm.ValueType{v128},
264 expMatched: false,
265 expValuesMsg: ` have [i32x4(0xa, 0x1a1a1a1a, 0x7b, 0x0)]
266 want [i32x4(0xa, 0xffffffff, 0x7b, 0x0)]`,
267 },
268 {
269 name: "matched/i64x2",
270 exps: []uint64{math.MaxUint64, 123},
271 actual: []uint64{math.MaxUint64, 123},
272 laneTypes: map[int]laneType{0: laneTypeI64},
273 valueTypes: []wasm.ValueType{v128},
274 expMatched: true,
275 },
276 {
277 name: "unmatched/i64x2",
278 exps: []uint64{math.MaxUint64, 123},
279 actual: []uint64{math.MaxUint64, 0},
280 laneTypes: map[int]laneType{0: laneTypeI64},
281 valueTypes: []wasm.ValueType{v128},
282 expMatched: false,
283 expValuesMsg: ` have [i64x2(0xffffffffffffffff, 0x0)]
284 want [i64x2(0xffffffffffffffff, 0x7b)]`,
285 },
286 {
287 name: "matched/f32x4",
288 exps: []uint64{
289 (uint64(math.Float32bits(float32(math.NaN()))) << 32) | uint64(math.Float32bits(float32(math.NaN()))),
290 (uint64(math.Float32bits(float32(math.NaN()))) << 32) | uint64(math.Float32bits(float32(math.NaN()))),
291 },
292 actual: []uint64{
293 (uint64(math.Float32bits(float32(math.NaN()))) << 32) | uint64(math.Float32bits(float32(math.NaN()))),
294 (uint64(math.Float32bits(float32(math.NaN()))) << 32) | uint64(math.Float32bits(float32(math.NaN()))),
295 },
296 valueTypes: []wasm.ValueType{v128},
297 laneTypes: map[int]laneType{0: laneTypeF32},
298 expMatched: true,
299 },
300 {
301 name: "unmatched/f32x4",
302 exps: []uint64{
303 (uint64(math.Float32bits(float32(1.213))) << 32) | uint64(math.Float32bits(float32(math.NaN()))),
304 (uint64(math.Float32bits(float32(math.NaN()))) << 32) | uint64(math.Float32bits(float32(math.NaN()))),
305 },
306 actual: []uint64{
307 (uint64(math.Float32bits(float32(math.NaN()))) << 32) | uint64(math.Float32bits(float32(math.Inf(1)))),
308 (uint64(math.Float32bits(float32(math.Inf(-1)))) << 32) | uint64(math.Float32bits(float32(math.NaN()))),
309 },
310 valueTypes: []wasm.ValueType{v128},
311 laneTypes: map[int]laneType{0: laneTypeF32},
312 expMatched: false,
313 expValuesMsg: ` have [f32x4(+Inf, NaN, NaN, -Inf)]
314 want [f32x4(NaN, 1.213000, NaN, NaN)]`,
315 },
316 {
317 name: "matched/f64x2",
318 exps: []uint64{math.Float64bits(1.0), math.Float64bits(math.NaN())},
319 actual: []uint64{math.Float64bits(1.0), math.Float64bits(math.NaN())},
320 valueTypes: []wasm.ValueType{v128},
321 laneTypes: map[int]laneType{0: laneTypeF64},
322 expMatched: true,
323 },
324 {
325 name: "unmatched/f64x2",
326 exps: []uint64{math.Float64bits(1.0), math.Float64bits(math.NaN())},
327 actual: []uint64{math.Float64bits(-1.0), math.Float64bits(math.Inf(1))},
328 valueTypes: []wasm.ValueType{v128},
329 laneTypes: map[int]laneType{0: laneTypeF64},
330 expMatched: false,
331 expValuesMsg: ` have [f64x2(-1.000000, +Inf)]
332 want [f64x2(1.000000, NaN)]`,
333 },
334 {
335 name: "unmatched/f64x2",
336 exps: []uint64{math.Float64bits(math.Inf(1)), math.Float64bits(math.NaN())},
337 actual: []uint64{math.Float64bits(math.Inf(-1)), math.Float64bits(math.NaN())},
338 valueTypes: []wasm.ValueType{v128},
339 laneTypes: map[int]laneType{0: laneTypeF64},
340 expMatched: false,
341 expValuesMsg: ` have [f64x2(-Inf, NaN)]
342 want [f64x2(+Inf, NaN)]`,
343 },
344 {
345 name: "matched/[i32,f64x2]",
346 exps: []uint64{1, math.Float64bits(1.0), math.Float64bits(math.NaN())},
347 actual: []uint64{1, math.Float64bits(1.0), math.Float64bits(math.NaN())},
348 valueTypes: []wasm.ValueType{i32, v128},
349 laneTypes: map[int]laneType{1: laneTypeF64},
350 expMatched: true,
351 },
352 {
353 name: "unmatched/[i32,f64x2]",
354 exps: []uint64{123, math.Float64bits(math.Inf(1)), math.Float64bits(math.NaN())},
355 actual: []uint64{123, math.Float64bits(math.Inf(-1)), math.Float64bits(math.NaN())},
356 valueTypes: []wasm.ValueType{i32, v128},
357 laneTypes: map[int]laneType{1: laneTypeF64},
358 expMatched: false,
359 expValuesMsg: ` have [123, f64x2(-Inf, NaN)]
360 want [123, f64x2(+Inf, NaN)]`,
361 },
362 {
363 name: "matched/[i32,f64x2]",
364 exps: []uint64{math.Float64bits(1.0), math.Float64bits(math.NaN()), 1},
365 actual: []uint64{math.Float64bits(1.0), math.Float64bits(math.NaN()), 1},
366 valueTypes: []wasm.ValueType{v128, i32},
367 laneTypes: map[int]laneType{0: laneTypeF64},
368 expMatched: true,
369 },
370 {
371 name: "unmatched/[f64x2,i32]",
372 exps: []uint64{math.Float64bits(math.Inf(1)), math.Float64bits(math.NaN()), 123},
373 actual: []uint64{math.Float64bits(math.Inf(-1)), math.Float64bits(math.NaN()), 123},
374 valueTypes: []wasm.ValueType{v128, i32},
375 laneTypes: map[int]laneType{0: laneTypeF64},
376 expMatched: false,
377 expValuesMsg: ` have [f64x2(-Inf, NaN), 123]
378 want [f64x2(+Inf, NaN), 123]`,
379 },
380 {
381 name: "matched/[f32,i32,f64x2]",
382 exps: []uint64{uint64(math.Float32bits(float32(math.NaN()))), math.Float64bits(1.0), math.Float64bits(math.NaN()), 1},
383 actual: []uint64{uint64(math.Float32bits(float32(math.NaN()))), math.Float64bits(1.0), math.Float64bits(math.NaN()), 1},
384 valueTypes: []wasm.ValueType{f32, v128, i32},
385 laneTypes: map[int]laneType{1: laneTypeF64},
386 expMatched: true,
387 },
388 {
389 name: "unmatched/[f32,f64x2,i32]",
390 exps: []uint64{uint64(math.Float32bits(1.0)), math.Float64bits(math.Inf(1)), math.Float64bits(math.NaN()), 123},
391 actual: []uint64{uint64(math.Float32bits(1.0)), math.Float64bits(math.Inf(-1)), math.Float64bits(math.NaN()), 123},
392 valueTypes: []wasm.ValueType{f32, v128, i32},
393 laneTypes: map[int]laneType{1: laneTypeF64},
394 expMatched: false,
395 expValuesMsg: ` have [1.000000, f64x2(-Inf, NaN), 123]
396 want [1.000000, f64x2(+Inf, NaN), 123]`,
397 },
398 {
399 name: "matched/[i8x16,f64x2]",
400 exps: []uint64{0, 0, math.Float64bits(1.0), math.Float64bits(math.NaN())},
401 actual: []uint64{0, 0, math.Float64bits(1.0), math.Float64bits(math.NaN())},
402 valueTypes: []wasm.ValueType{v128, v128},
403 laneTypes: map[int]laneType{0: laneTypeI8, 1: laneTypeF64},
404 expMatched: true,
405 },
406 {
407 name: "unmatched/[i8x16,f64x2]",
408 exps: []uint64{0, 0xff << 56, math.Float64bits(1.0), math.Float64bits(math.NaN())},
409 actual: []uint64{0, 0xaa << 56, math.Float64bits(1.0), math.Float64bits(math.NaN())},
410 valueTypes: []wasm.ValueType{v128, v128},
411 laneTypes: map[int]laneType{0: laneTypeI8, 1: laneTypeF64},
412 expMatched: false,
413 expValuesMsg: ` have [i8x16(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaa), f64x2(1.000000, NaN)]
414 want [i8x16(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff), f64x2(1.000000, NaN)]`,
415 },
416 {
417 name: "unmatched/[i8x16,f64x2]",
418 exps: []uint64{0, 0xff << 56, math.Float64bits(1.0), math.Float64bits(math.NaN())},
419 actual: []uint64{0, 0xff << 56, math.Float64bits(1.0), math.Float64bits(math.Inf(1))},
420 valueTypes: []wasm.ValueType{v128, v128},
421 laneTypes: map[int]laneType{0: laneTypeI8, 1: laneTypeF64},
422 expMatched: false,
423 expValuesMsg: ` have [i8x16(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff), f64x2(1.000000, +Inf)]
424 want [i8x16(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff), f64x2(1.000000, NaN)]`,
425 },
426 {
427 name: "matched/[i8x16,i32,f64x2]",
428 exps: []uint64{0, 0, math.MaxUint32, math.Float64bits(1.0), math.Float64bits(math.NaN())},
429 actual: []uint64{0, 0, math.MaxUint32, math.Float64bits(1.0), math.Float64bits(math.NaN())},
430 valueTypes: []wasm.ValueType{v128, i32, v128},
431 laneTypes: map[int]laneType{0: laneTypeI8, 2: laneTypeF64},
432 expMatched: true,
433 },
434 {
435 name: "matched/[i8x16,i32,f64x2]",
436 exps: []uint64{0, 0, math.MaxUint32, math.Float64bits(1.0), math.Float64bits(math.NaN())},
437 actual: []uint64{0, 0, math.MaxUint32 - 1, math.Float64bits(1.0), math.Float64bits(math.NaN())},
438 valueTypes: []wasm.ValueType{v128, i32, v128},
439 laneTypes: map[int]laneType{0: laneTypeI8, 2: laneTypeF64},
440 expMatched: false,
441 expValuesMsg: ` have [i8x16(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0), 4294967294, f64x2(1.000000, NaN)]
442 want [i8x16(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0), 4294967295, f64x2(1.000000, NaN)]`,
443 },
444 {
445 name: "matched/[i8x16,i32,f64x2]",
446 exps: []uint64{0, 0, math.MaxUint32, math.Float64bits(1.0), math.Float64bits(math.NaN())},
447 actual: []uint64{0, 0xff << 16, math.MaxUint32, math.Float64bits(1.0), math.Float64bits(math.NaN())},
448 valueTypes: []wasm.ValueType{v128, i32, v128},
449 laneTypes: map[int]laneType{0: laneTypeI8, 2: laneTypeF64},
450 expMatched: false,
451 expValuesMsg: ` have [i8x16(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0), 4294967295, f64x2(1.000000, NaN)]
452 want [i8x16(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0), 4294967295, f64x2(1.000000, NaN)]`,
453 },
454 }
455
456 for _, tc := range tests {
457 tc := tc
458 t.Run(tc.name, func(t *testing.T) {
459 actualMatched, actualValuesMsg := valuesEq(tc.actual, tc.exps, tc.valueTypes, tc.laneTypes)
460 require.Equal(t, tc.expMatched, actualMatched)
461 require.Equal(t, tc.expValuesMsg, actualValuesMsg)
462 })
463 }
464 }
465
466 func TestCommandActionVal_toUint64s(t *testing.T) {
467 tests := []struct {
468 name string
469 rawCommandActionVal string
470 exp []uint64
471 }{
472 {
473 name: "i32",
474 rawCommandActionVal: `{"type": "i32", "value": "0"}`,
475 exp: []uint64{0},
476 },
477 {
478 name: "i32",
479 rawCommandActionVal: `{"type": "i32", "value": "4294967295"}`,
480 exp: []uint64{4294967295},
481 },
482 {
483 name: "i64",
484 rawCommandActionVal: `{"type": "i64", "value": "0"}`,
485 exp: []uint64{0},
486 },
487 {
488 name: "i64",
489 rawCommandActionVal: `{"type": "i64", "value": "7034535277573963776"}`,
490 exp: []uint64{7034535277573963776},
491 },
492 {
493 name: "f32",
494 rawCommandActionVal: `{"type": "f32", "value": "0"}`,
495 exp: []uint64{0},
496 },
497 {
498 name: "f32",
499 rawCommandActionVal: `{"type": "f32", "value": "2147483648"}`,
500 exp: []uint64{2147483648},
501 },
502 {
503 name: "f64",
504 rawCommandActionVal: `{"type": "f64", "value": "0"}`,
505 exp: []uint64{0},
506 },
507 {
508 name: "f64",
509 rawCommandActionVal: `{"type": "f64", "value": "4616189618054758400"}`,
510 exp: []uint64{4616189618054758400},
511 },
512 {
513 name: "f32x4",
514 rawCommandActionVal: `{"type": "v128", "lane_type": "f32", "value": ["645922816", "645922816", "645922816", "645922816"]}`,
515 exp: []uint64{645922816<<32 | 645922816, 645922816<<32 | 645922816},
516 },
517 {
518 name: "f32x4",
519 rawCommandActionVal: `{"type": "v128", "lane_type": "f32", "value": ["nan:canonical", "nan:arithmetic", "nan:canonical", "nan:arithmetic"]}`,
520 exp: []uint64{
521 uint64(moremath.F32CanonicalNaNBits) | (uint64(moremath.F32ArithmeticNaNBits) << 32),
522 uint64(moremath.F32CanonicalNaNBits) | (uint64(moremath.F32ArithmeticNaNBits) << 32),
523 },
524 },
525 {
526 name: "f64x2",
527 rawCommandActionVal: `{"type": "v128", "lane_type": "f64", "value": ["9223372036854775808", "9223372036854775808"]}`,
528 exp: []uint64{9223372036854775808, 9223372036854775808},
529 },
530 {
531 name: "f64x2",
532 rawCommandActionVal: `{"type": "v128", "lane_type": "f64", "value": ["nan:canonical", "nan:arithmetic"]}`,
533 exp: []uint64{moremath.F64CanonicalNaNBits, moremath.F64ArithmeticNaNBits},
534 },
535 {
536 name: "i8x16",
537 rawCommandActionVal: `{"type": "v128", "lane_type": "i8", "value": ["128", "129", "130", "131", "253", "254", "255", "0", "0", "1", "2", "127", "128", "253", "254", "255"]}`,
538 exp: []uint64{
539 128 | (129 << 8) | (130 << 16) | (131 << 24) | (253 << 32) | (254 << 40) | (255 << 48),
540 1<<8 | 2<<16 | 127<<24 | 128<<32 | 253<<40 | 254<<48 | 255<<56,
541 },
542 },
543 {
544 name: "i16x8",
545 rawCommandActionVal: `{"type": "v128", "lane_type": "i16", "value": ["256", "770", "1284", "1798", "2312", "2826", "3340", "3854"]}`,
546 exp: []uint64{
547 256 | 770<<16 | 1284<<32 | 1798<<48,
548 2312 | 2826<<16 | 3340<<32 | 3854<<48,
549 },
550 },
551 {
552 name: "i32x4",
553 rawCommandActionVal: `{"type": "v128", "lane_type": "i32", "value": ["123", "32766", "32766", "40000"]}`,
554 exp: []uint64{
555 123 | 32766<<32,
556 32766 | 40000<<32,
557 },
558 },
559 {
560 name: "i64x2",
561 rawCommandActionVal: `{"type": "v128", "lane_type": "i64", "value": ["18446744073709551615", "123124"]}`,
562 exp: []uint64{
563 18446744073709551615,
564 123124,
565 },
566 },
567 }
568
569 for _, tc := range tests {
570 tc := tc
571 t.Run(tc.name, func(t *testing.T) {
572 var c commandActionVal
573 err := json.Unmarshal([]byte(tc.rawCommandActionVal), &c)
574 require.NoError(t, err)
575 actual := c.toUint64s()
576 require.Equal(t, tc.exp, actual)
577 })
578 }
579 }
580
581 func TestCommand_getAssertReturnArgsExps(t *testing.T) {
582 tests := []struct {
583 name string
584 rawCommand string
585 args, exps []uint64
586 }{
587 {
588 name: "1",
589 rawCommand: `
590 {
591 "type": "assert_return",
592 "line": 148,
593 "action": {
594 "type": "invoke", "field": "f32x4.min",
595 "args": [
596 {"type": "v128", "lane_type": "f32", "value": ["2147483648", "123", "2147483648", "1"]},
597 {"type": "v128", "lane_type": "i8", "value": ["128", "129", "130", "131", "253", "254", "255", "0", "0", "1", "2", "127", "128", "253", "254", "255"]}
598 ]
599 },
600 "expected": [
601 {"type": "v128", "lane_type": "f32", "value": ["2147483648", "0", "0", "2147483648"]}
602 ]
603 }`,
604 args: []uint64{
605 123<<32 | 2147483648,
606 1<<32 | 2147483648,
607 128 | (129 << 8) | (130 << 16) | (131 << 24) | (253 << 32) | (254 << 40) | (255 << 48),
608 1<<8 | 2<<16 | 127<<24 | 128<<32 | 253<<40 | 254<<48 | 255<<56,
609 },
610 exps: []uint64{
611 2147483648,
612 2147483648 << 32,
613 },
614 },
615 }
616
617 for _, tc := range tests {
618 tc := tc
619 t.Run(tc.name, func(t *testing.T) {
620 var c command
621 err := json.Unmarshal([]byte(tc.rawCommand), &c)
622 require.NoError(t, err)
623 actualArgs, actualExps := c.getAssertReturnArgsExps()
624 require.Equal(t, tc.args, actualArgs)
625 require.Equal(t, tc.exps, actualExps)
626 })
627 }
628 }
629
View as plain text