github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/integration_test/spectest/spectest_test.go (about) 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 // The Wasm spec doesn't differentiate different arithmetic nans. 48 exp: true, 49 }, 50 { 51 f1: math.Float32frombits(moremath.F32CanonicalNaNBits), 52 f2: math.Float32frombits(moremath.F32CanonicalNaNBits | 1<<2), 53 // Canonical NaN is unique. 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 // The Wasm spec doesn't differentiate different arithmetic nans. 98 exp: true, 99 }, 100 { 101 f1: math.Float64frombits(moremath.F64CanonicalNaNBits), 102 f2: math.Float64frombits(moremath.F64CanonicalNaNBits | 1<<2), 103 // Canonical NaN is unique. 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 }