github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/integration_test/fuzzcases/fuzzcases_test.go (about) 1 package fuzzcases 2 3 import ( 4 "context" 5 "embed" 6 "fmt" 7 "math" 8 "runtime" 9 "testing" 10 11 wazero "github.com/wasilibs/wazerox" 12 "github.com/wasilibs/wazerox/api" 13 "github.com/wasilibs/wazerox/experimental/opt" 14 "github.com/wasilibs/wazerox/internal/platform" 15 "github.com/wasilibs/wazerox/internal/testing/binaryencoding" 16 "github.com/wasilibs/wazerox/internal/testing/require" 17 "github.com/wasilibs/wazerox/internal/wasm" 18 ) 19 20 var ctx = context.Background() 21 22 // Note: the name of the test is the PR number. It may be followed by a letter 23 // if the PR includes more than one test (e.g. "1234a", "1234b"). 24 // 25 //go:embed testdata/*.wasm 26 var testcases embed.FS 27 28 func getWasmBinary(t *testing.T, testId string) []byte { 29 ret, err := testcases.ReadFile(fmt.Sprintf("testdata/%s.wasm", testId)) 30 require.NoError(t, err) 31 return ret 32 } 33 34 func runWithCompiler(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) { 35 if !platform.CompilerSupported() { 36 return 37 } 38 t.Run("compiler", func(t *testing.T) { 39 r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigCompiler()) 40 defer r.Close(ctx) 41 runner(t, r) 42 }) 43 } 44 45 func runWithInterpreter(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) { 46 t.Run("interpreter", func(t *testing.T) { 47 r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter()) 48 defer r.Close(ctx) 49 runner(t, r) 50 }) 51 } 52 53 func runWithWazevo(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) { 54 t.Run("wazevo", func(t *testing.T) { 55 config := opt.NewRuntimeConfigOptimizingCompiler() 56 r := wazero.NewRuntimeWithConfig(ctx, config) 57 defer r.Close(ctx) 58 runner(t, r) 59 }) 60 } 61 62 func run(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) { 63 runWithInterpreter(t, runner) 64 runWithCompiler(t, runner) 65 if runtime.GOARCH == "arm64" { 66 runWithWazevo(t, runner) 67 } 68 } 69 70 // Test695 requires two functions to exit with "out of bounds memory access" consistently across the implementations. 71 func Test695(t *testing.T) { 72 run(t, func(t *testing.T, r wazero.Runtime) { 73 module, err := r.Instantiate(ctx, getWasmBinary(t, "695")) 74 require.NoError(t, err) 75 76 _, err = module.ExportedFunction("i8x16s").Call(ctx) 77 require.NotNil(t, err) 78 require.Contains(t, err.Error(), "out of bounds memory access") 79 80 _, err = module.ExportedFunction("i16x8s").Call(ctx) 81 require.NotNil(t, err) 82 require.Contains(t, err.Error(), "out of bounds memory access") 83 }) 84 } 85 86 func Test696(t *testing.T) { 87 run(t, func(t *testing.T, r wazero.Runtime) { 88 module, err := r.Instantiate(ctx, getWasmBinary(t, "696")) 89 require.NoError(t, err) 90 for _, tc := range []struct { 91 fnName string 92 in uint64 93 exp [2]uint64 94 }{ 95 {fnName: "select", in: 1 << 5, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}}, 96 {fnName: "select", in: 1, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}}, 97 {fnName: "select", in: 0, exp: [2]uint64{0x1111111111111111, 0x2222222222222222}}, 98 {fnName: "select", in: 0xffffff, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}}, 99 {fnName: "select", in: 0xffff00, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}}, 100 {fnName: "select", in: 0x000000, exp: [2]uint64{0x1111111111111111, 0x2222222222222222}}, 101 {fnName: "typed select", in: 1, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}}, 102 {fnName: "typed select", in: 0, exp: [2]uint64{0x1111111111111111, 0x2222222222222222}}, 103 } { 104 res, err := module.ExportedFunction(tc.fnName).Call(ctx, tc.in) 105 require.NoError(t, err) 106 require.Equal(t, tc.exp[:], res) 107 } 108 }) 109 } 110 111 // Test699 ensures that accessing element instances and data instances works 112 // without crash even when the access happens in the nested function call. 113 func Test699(t *testing.T) { 114 run(t, func(t *testing.T, r wazero.Runtime) { 115 defer r.Close(ctx) 116 _, err := r.Instantiate(ctx, getWasmBinary(t, "699")) 117 require.NoError(t, err) 118 }) 119 } 120 121 // Test701 requires two functions to exit with "out of bounds memory access" consistently across the implementations. 122 func Test701(t *testing.T) { 123 run(t, func(t *testing.T, r wazero.Runtime) { 124 module, err := r.Instantiate(ctx, getWasmBinary(t, "701")) 125 require.NoError(t, err) 126 127 _, err = module.ExportedFunction("i32.extend16_s").Call(ctx) 128 require.NotNil(t, err) 129 require.Contains(t, err.Error(), "out of bounds memory access") 130 131 _, err = module.ExportedFunction("i32.extend8_s").Call(ctx) 132 require.NotNil(t, err) 133 require.Contains(t, err.Error(), "out of bounds memory access") 134 }) 135 } 136 137 func Test704(t *testing.T) { 138 run(t, func(t *testing.T, r wazero.Runtime) { 139 _, err := r.Instantiate(ctx, getWasmBinary(t, "704")) 140 require.NoError(t, err) 141 }) 142 } 143 144 func Test708(t *testing.T) { 145 run(t, func(t *testing.T, r wazero.Runtime) { 146 _, err := r.Instantiate(ctx, getWasmBinary(t, "708")) 147 require.NotNil(t, err) 148 require.Contains(t, err.Error(), "out of bounds memory access") 149 }) 150 } 151 152 func Test709(t *testing.T) { 153 run(t, func(t *testing.T, r wazero.Runtime) { 154 mod, err := r.Instantiate(ctx, getWasmBinary(t, "709")) 155 require.NoError(t, err) 156 157 f := mod.ExportedFunction("f64x2.promote_low_f32x4") 158 require.NotNil(t, f) 159 res, err := f.Call(ctx) 160 require.NoError(t, err) 161 162 require.NotEqual(t, uint64(0), res[0]) 163 require.NotEqual(t, uint64(0), res[1]) 164 }) 165 } 166 167 func Test715(t *testing.T) { 168 run(t, func(t *testing.T, r wazero.Runtime) { 169 mod, err := r.Instantiate(ctx, getWasmBinary(t, "715")) 170 require.NoError(t, err) 171 172 f := mod.ExportedFunction("select on conditional value after table.size") 173 require.NotNil(t, f) 174 res, err := f.Call(ctx) 175 require.NoError(t, err) 176 177 require.Equal(t, uint64(1), res[0]) 178 }) 179 } 180 181 func Test716(t *testing.T) { 182 run(t, func(t *testing.T, r wazero.Runtime) { 183 mod, err := r.Instantiate(ctx, getWasmBinary(t, "716")) 184 require.NoError(t, err) 185 186 f := mod.ExportedFunction("select on ref.func") 187 require.NotNil(t, f) 188 res, err := f.Call(ctx) 189 require.NoError(t, err) 190 191 require.Equal(t, uint64(1), res[0]) 192 }) 193 } 194 195 func Test717(t *testing.T) { 196 run(t, func(t *testing.T, r wazero.Runtime) { 197 mod, err := r.Instantiate(ctx, getWasmBinary(t, "717")) 198 require.NoError(t, err) 199 200 f := mod.ExportedFunction("vectors") 201 require.NotNil(t, f) 202 res, err := f.Call(ctx) 203 require.NoError(t, err) 204 205 const expectedLen = 35 206 require.Equal(t, expectedLen, len(res)) 207 for i := 0; i < expectedLen; i++ { 208 require.Equal(t, uint64(i), res[i]) 209 } 210 }) 211 } 212 213 func Test718(t *testing.T) { 214 run(t, func(t *testing.T, r wazero.Runtime) { 215 mod, err := r.Instantiate(ctx, getWasmBinary(t, "718")) 216 require.NoError(t, err) 217 218 f := mod.ExportedFunction("v128.load_zero on the ceil") 219 require.NotNil(t, f) 220 _, err = f.Call(ctx) 221 require.NoError(t, err) 222 }) 223 } 224 225 func Test719(t *testing.T) { 226 run(t, func(t *testing.T, r wazero.Runtime) { 227 mod, err := r.Instantiate(ctx, getWasmBinary(t, "719")) 228 require.NoError(t, err) 229 230 f := mod.ExportedFunction("require unreachable") 231 require.NotNil(t, f) 232 _, err = f.Call(ctx) 233 require.Error(t, err) 234 require.Contains(t, err.Error(), "wasm error: unreachable\nwasm stack trace:") 235 }) 236 } 237 238 func Test720(t *testing.T) { 239 run(t, func(t *testing.T, r wazero.Runtime) { 240 mod, err := r.Instantiate(ctx, getWasmBinary(t, "720")) 241 require.NoError(t, err) 242 243 f := mod.ExportedFunction("access memory after table.grow") 244 require.NotNil(t, f) 245 res, err := f.Call(ctx) 246 require.NoError(t, err) 247 require.Equal(t, uint32(0xffffffff), uint32(res[0])) 248 }) 249 } 250 251 func Test721(t *testing.T) { 252 run(t, func(t *testing.T, r wazero.Runtime) { 253 mod, err := r.Instantiate(ctx, getWasmBinary(t, "721")) 254 require.NoError(t, err) 255 256 f := mod.ExportedFunction("conditional before elem.drop") 257 require.NotNil(t, f) 258 ret, err := f.Call(ctx) 259 require.NoError(t, err) 260 261 require.Equal(t, uint64(1), ret[0]) 262 }) 263 } 264 265 func Test722(t *testing.T) { 266 run(t, func(t *testing.T, r wazero.Runtime) { 267 mod, err := r.Instantiate(ctx, getWasmBinary(t, "722")) 268 require.NoError(t, err) 269 270 f := mod.ExportedFunction("conditional before data.drop") 271 require.NotNil(t, f) 272 ret, err := f.Call(ctx) 273 require.NoError(t, err) 274 275 require.Equal(t, uint64(1), ret[0]) 276 }) 277 } 278 279 func Test725(t *testing.T) { 280 functions := []string{"i32.load8_s", "i32.load16_s"} 281 run(t, func(t *testing.T, r wazero.Runtime) { 282 mod, err := r.Instantiate(ctx, getWasmBinary(t, "725")) 283 require.NoError(t, err) 284 285 for _, fn := range functions { 286 f := mod.ExportedFunction(fn) 287 require.NotNil(t, f) 288 _, err := f.Call(ctx) 289 require.Error(t, err) 290 require.Contains(t, err.Error(), "out of bounds memory") 291 } 292 }) 293 } 294 295 // Test730 ensures that the vector min/max operations comply with the spec wrt sign bits of zeros: 296 // 297 // - min(0, 0) = 0, min(-0, 0) = -0, min(0, -0) = -0, min(-0, -0) = -0 298 // - max(0, 0) = 0, max(-0, 0) = 0, max(0, -0) = 0, max(-0, -0) = -0 299 func Test730(t *testing.T) { 300 tests := []struct { 301 name string 302 exp [2]uint64 303 }{ 304 {name: "f32x4.max", exp: [2]uint64{0x80000000 << 32, 0x00000000}}, 305 {name: "f32x4.min", exp: [2]uint64{0x80000000, 0x80000000<<32 | 0x80000000}}, 306 {name: "f64x2.max", exp: [2]uint64{0, 0}}, 307 {name: "f64x2.min", exp: [2]uint64{1 << 63, 1 << 63}}, 308 {name: "f64x2.max/mix", exp: [2]uint64{0, 1 << 63}}, 309 {name: "f64x2.min/mix", exp: [2]uint64{1 << 63, 0}}, 310 } 311 312 run(t, func(t *testing.T, r wazero.Runtime) { 313 mod, err := r.Instantiate(ctx, getWasmBinary(t, "730")) 314 require.NoError(t, err) 315 316 for _, tc := range tests { 317 t.Run(tc.name, func(t *testing.T) { 318 f := mod.ExportedFunction(tc.name) 319 require.NotNil(t, f) 320 actual, err := f.Call(ctx) 321 require.NoError(t, err) 322 require.Equal(t, tc.exp[:], actual) 323 }) 324 } 325 }) 326 } 327 328 func Test733(t *testing.T) { 329 run(t, func(t *testing.T, r wazero.Runtime) { 330 mod, err := r.Instantiate(ctx, getWasmBinary(t, "733")) 331 require.NoError(t, err) 332 333 name := "out of bounds" 334 t.Run(name, func(t *testing.T) { 335 f := mod.ExportedFunction(name) 336 require.NotNil(t, f) 337 _, err = f.Call(ctx) 338 require.Error(t, err) 339 require.Contains(t, err.Error(), "out of bounds memory") 340 }) 341 342 name = "store higher offset" 343 t.Run(name, func(t *testing.T) { 344 if testing.Short() { 345 // Note: this case uses large memory space, so can be slow like 1 to 2 seconds even without -race. 346 // The reason is that this test requires roughly 2GB of in-Wasm memory. 347 t.SkipNow() 348 } 349 f := mod.ExportedFunction(name) 350 require.NotNil(t, f) 351 _, err = f.Call(ctx) 352 require.NoError(t, err) 353 354 mem := mod.Memory() 355 require.NotNil(t, mem) 356 357 v, ok := mem.ReadUint64Le(0x80000100) 358 require.True(t, ok) 359 require.Equal(t, uint64(0xffffffffffffffff), v) 360 }) 361 }) 362 } 363 364 func Test873(t *testing.T) { 365 run(t, func(t *testing.T, r wazero.Runtime) { 366 _, err := r.Instantiate(ctx, getWasmBinary(t, "873")) 367 require.NoError(t, err) 368 }) 369 } 370 371 func Test874(t *testing.T) { 372 run(t, func(t *testing.T, r wazero.Runtime) { 373 _, err := r.Instantiate(ctx, getWasmBinary(t, "874")) 374 require.NoError(t, err) 375 }) 376 } 377 378 func Test888(t *testing.T) { 379 // This tests that importing FuncRef type globals and using it as an initialization of the locally-defined 380 // FuncRef global works fine. 381 run(t, func(t *testing.T, r wazero.Runtime) { 382 imported := binaryencoding.EncodeModule(&wasm.Module{ 383 MemorySection: &wasm.Memory{Min: 0, Max: 5, IsMaxEncoded: true}, 384 GlobalSection: []wasm.Global{ 385 { 386 Type: wasm.GlobalType{ 387 ValType: wasm.ValueTypeFuncref, 388 Mutable: false, 389 }, 390 Init: wasm.ConstantExpression{ 391 Opcode: wasm.OpcodeRefNull, 392 Data: []byte{wasm.ValueTypeFuncref}, 393 }, 394 }, 395 }, 396 ExportSection: []wasm.Export{ 397 {Name: "", Type: wasm.ExternTypeGlobal, Index: 0}, 398 {Name: "s", Type: wasm.ExternTypeMemory, Index: 0}, 399 }, 400 }) 401 402 _, err := r.InstantiateWithConfig(ctx, imported, wazero.NewModuleConfig().WithName("host")) 403 require.NoError(t, err) 404 405 _, err = r.InstantiateWithConfig(ctx, getWasmBinary(t, "888"), 406 wazero.NewModuleConfig().WithName("test")) 407 require.NoError(t, err) 408 }) 409 } 410 411 func Test1054(t *testing.T) { 412 if !platform.CompilerSupported() { 413 return 414 } 415 416 modules := make([]api.Module, 0, 3) 417 run(t, func(t *testing.T, r wazero.Runtime) { 418 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1054")) 419 require.NoError(t, err) 420 modules = append(modules, mod) 421 }) 422 423 // Checks if the memory state is the same between engines. 424 exp := modules[0].Memory().(*wasm.MemoryInstance).Buffer 425 for i := 1; i < len(modules); i++ { 426 actual := modules[i].Memory().(*wasm.MemoryInstance).Buffer 427 require.Equal(t, exp, actual) 428 } 429 } 430 431 // Test1777 tests that br_table with multiple args works fine even if 432 // there might be phi eliminations. 433 func Test1777(t *testing.T) { 434 if !platform.CompilerSupported() { 435 return 436 } 437 438 run(t, func(t *testing.T, r wazero.Runtime) { 439 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1777")) 440 require.NoError(t, err) 441 f := mod.ExportedFunction("") 442 require.NotNil(t, f) 443 res, err := f.Call(ctx) 444 require.NoError(t, err) 445 require.Equal(t, []uint64{18446626425965379583, 4607736361554183979}, res) 446 }) 447 } 448 449 // Test1792a tests that v128.const i32x4 is not skipped when state is unreachable. 450 // This test fails at build-time. 451 func Test1792a(t *testing.T) { 452 if !platform.CompilerSupported() { 453 return 454 } 455 run(t, func(t *testing.T, r wazero.Runtime) { 456 _, err := r.Instantiate(ctx, getWasmBinary(t, "1792a")) 457 require.NoError(t, err) 458 }) 459 } 460 461 // Test1792b tests that OpcodeVhighBits (v128.Bitmask) is typed as V128. 462 // This test fails at build-time. 463 func Test1792b(t *testing.T) { 464 if !platform.CompilerSupported() { 465 return 466 } 467 run(t, func(t *testing.T, r wazero.Runtime) { 468 _, err := r.Instantiate(ctx, getWasmBinary(t, "1792b")) 469 require.NoError(t, err) 470 }) 471 } 472 473 // Test1792c tests that OpcodeVFcmp (f32x4.eq) is typed as V128. 474 func Test1792c(t *testing.T) { 475 if !platform.CompilerSupported() { 476 return 477 } 478 run(t, func(t *testing.T, r wazero.Runtime) { 479 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1792c")) 480 require.NoError(t, err) 481 f := mod.ExportedFunction("") 482 require.NotNil(t, f) 483 _, err = f.Call(ctx, 0, 0, 0) 484 require.NoError(t, err) 485 m := mod.(*wasm.ModuleInstance) 486 require.Equal(t, uint64(5044022786561933312), m.Globals[0].Val) 487 require.Equal(t, uint64(9205357640488583168), m.Globals[0].ValHi) 488 }) 489 } 490 491 // Test1793a tests that OpcodeVAllTrue is lowered to the right registers. 492 func Test1793a(t *testing.T) { 493 if !platform.CompilerSupported() { 494 return 495 } 496 run(t, func(t *testing.T, r wazero.Runtime) { 497 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1793a")) 498 require.NoError(t, err) 499 m := mod.(*wasm.ModuleInstance) 500 _, err = m.ExportedFunction("").Call(ctx) 501 require.NoError(t, err) 502 require.Equal(t, uint64(2531906066518671488), m.Globals[2].Val) 503 require.Equal(t, uint64(18446744073709551615), m.Globals[2].ValHi) 504 }) 505 } 506 507 // Test1793b tests that OpcodeVIcmp, OpcodeVFcmp are lowered to the right registers. 508 func Test1793b(t *testing.T) { 509 if !platform.CompilerSupported() { 510 return 511 } 512 run(t, func(t *testing.T, r wazero.Runtime) { 513 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1793b")) 514 require.NoError(t, err) 515 m := mod.(*wasm.ModuleInstance) 516 _, err = m.ExportedFunction("").Call(ctx, 0, 0, 0, 0) 517 require.NoError(t, err) 518 require.Equal(t, uint64(18374967954648334335), m.Globals[1].Val) 519 require.Equal(t, uint64(18446744073709551615), m.Globals[1].ValHi) 520 }) 521 } 522 523 // Test1793c tests that OpcodeVIcmp is lowered to the right registers. 524 func Test1793c(t *testing.T) { 525 if !platform.CompilerSupported() { 526 return 527 } 528 run(t, func(t *testing.T, r wazero.Runtime) { 529 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1793c")) 530 require.NoError(t, err) 531 m := mod.(*wasm.ModuleInstance) 532 _, err = m.ExportedFunction("").Call(ctx, 0, 0) 533 require.NoError(t, err) 534 require.Equal(t, uint64(18446744073709551615), m.Globals[0].Val) 535 require.Equal(t, uint64(18446744073709551615), m.Globals[0].ValHi) 536 }) 537 } 538 539 // Test1793c tests that OpcodeVShift is lowered to the right registers. 540 func Test1793d(t *testing.T) { 541 if !platform.CompilerSupported() { 542 return 543 } 544 run(t, func(t *testing.T, r wazero.Runtime) { 545 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1793d")) 546 require.NoError(t, err) 547 m := mod.(*wasm.ModuleInstance) 548 _, err = m.ExportedFunction("").Call(ctx) 549 require.NoError(t, err) 550 require.Equal(t, uint64(0), m.Globals[1].Val) 551 }) 552 } 553 554 // Test1797a tests that i8x16.shl uses the right register types when lowered. 555 func Test1797a(t *testing.T) { 556 if !platform.CompilerSupported() { 557 return 558 } 559 run(t, func(t *testing.T, r wazero.Runtime) { 560 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1797a")) 561 require.NoError(t, err) 562 m := mod.(*wasm.ModuleInstance) 563 res, err := m.ExportedFunction("").Call(ctx) 564 require.NoError(t, err) 565 require.Equal(t, uint64(0), res[0]) 566 }) 567 } 568 569 // Test1797a tests that i16x8.shr_u uses the right register types when lowered. 570 func Test1797b(t *testing.T) { 571 if !platform.CompilerSupported() { 572 return 573 } 574 run(t, func(t *testing.T, r wazero.Runtime) { 575 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1797b")) 576 require.NoError(t, err) 577 m := mod.(*wasm.ModuleInstance) 578 _, err = m.ExportedFunction("\x00\x00\x00\x00\x00").Call(ctx, 0, 0, 0, 0, 0, 0) 579 require.NoError(t, err) 580 require.Equal(t, uint64(2666130977255796624), m.Globals[0].Val) 581 require.Equal(t, uint64(9223142857682330634), m.Globals[0].ValHi) 582 }) 583 } 584 585 // Test1797c tests that the program counter for V128*Shuffle is advanced correctly 586 // even when an unreachable instruction is present. 587 func Test1797c(t *testing.T) { 588 if !platform.CompilerSupported() { 589 return 590 } 591 run(t, func(t *testing.T, r wazero.Runtime) { 592 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1797c")) 593 require.NoError(t, err) 594 m := mod.(*wasm.ModuleInstance) 595 params := make([]uint64, 20) 596 _, err = m.ExportedFunction("~zz\x00E1E\x00EE\x00$").Call(ctx, params...) 597 require.Error(t, err, "wasm error: unreachable") 598 }) 599 } 600 601 // Test1797d tests that the registers are allocated correctly in Vbitselect. 602 func Test1797d(t *testing.T) { 603 if !platform.CompilerSupported() { 604 return 605 } 606 run(t, func(t *testing.T, r wazero.Runtime) { 607 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1797d")) 608 require.NoError(t, err) 609 m := mod.(*wasm.ModuleInstance) 610 params := make([]uint64, 20) 611 _, err = m.ExportedFunction("p").Call(ctx, params...) 612 require.NoError(t, err) 613 require.Equal(t, uint64(15092115255309870764), m.Globals[2].Val) 614 require.Equal(t, uint64(9241386435284803069), m.Globals[2].ValHi) 615 }) 616 } 617 618 // Test1802 tests that load32_splat computes the load from the right offset 619 // when a nonzero value is on the stack. 620 func Test1802(t *testing.T) { 621 if !platform.CompilerSupported() { 622 return 623 } 624 run(t, func(t *testing.T, r wazero.Runtime) { 625 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1802")) 626 require.NoError(t, err, "wasm binary should build successfully") 627 m := mod.(*wasm.ModuleInstance) 628 _, err = m.ExportedFunction("").Call(ctx) 629 require.Contains(t, err.Error(), "wasm error: unreachable") 630 }) 631 } 632 633 // Test1812 tests that many constant block params work fine. 634 func Test1812(t *testing.T) { 635 if !platform.CompilerSupported() { 636 return 637 } 638 run(t, func(t *testing.T, r wazero.Runtime) { 639 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1812")) 640 require.NoError(t, err) 641 m := mod.(*wasm.ModuleInstance) 642 res, err := m.ExportedFunction("").Call(ctx) 643 require.NoError(t, err) 644 require.Equal(t, 645 []uint64{ 646 0x8301fd00, 0xfd838783, 0x87878383, 0x9b000087, 0x170001fd, 647 0xfd8383fd, 0x87838301, 0x878787, 0x83fd9b00, 0x201fd83, 0x878783, 648 0x83fd9b00, 0x9b00fd83, 0xfd8383fd, 0x87838301, 0x87878787, 649 0xfd9b0000, 0x87878383, 0x1fd8383, 650 }, res) 651 }) 652 } 653 654 // Test1817 tests that v128.store uses the right memory layout. 655 func Test1817(t *testing.T) { 656 if !platform.CompilerSupported() { 657 return 658 } 659 run(t, func(t *testing.T, r wazero.Runtime) { 660 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1817")) 661 require.NoError(t, err) 662 m := mod.(*wasm.ModuleInstance) 663 _, err = m.ExportedFunction("").Call(ctx) 664 require.NoError(t, err) 665 buf, ok := m.Memory().Read(15616, 16) 666 require.True(t, ok) 667 require.Equal(t, []uint8{0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, buf) 668 require.Equal(t, uint64(0x8000000080000000), m.Globals[0].Val) 669 require.Equal(t, uint64(0x8000000080000000), m.Globals[0].ValHi) 670 }) 671 } 672 673 // Test1820 tests that i16x8.narrow_i32x4_u assigns the dest register correctly. 674 func Test1820(t *testing.T) { 675 if !platform.CompilerSupported() { 676 return 677 } 678 run(t, func(t *testing.T, r wazero.Runtime) { 679 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1820")) 680 require.NoError(t, err) 681 m := mod.(*wasm.ModuleInstance) 682 _, err = m.ExportedFunction("").Call(ctx) 683 require.NoError(t, err) 684 require.Equal(t, uint64(0xFFFFFFFFFFFF0000), m.Globals[1].Val) 685 require.Equal(t, uint64(0xFFFF), m.Globals[1].ValHi) 686 }) 687 } 688 689 // Test1823 tests that f64x2.pmin lowers to BSL with the right register usage 690 // (condition register gets overwritten). 691 func Test1823(t *testing.T) { 692 if !platform.CompilerSupported() { 693 return 694 } 695 run(t, func(t *testing.T, r wazero.Runtime) { 696 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1823")) 697 require.NoError(t, err) 698 m := mod.(*wasm.ModuleInstance) 699 _, err = m.ExportedFunction("").Call(ctx) 700 require.NoError(t, err) 701 require.Equal(t, uint64(17282609607625994159), m.Globals[0].Val) 702 require.Equal(t, uint64(4671060543367625455), m.Globals[0].ValHi) 703 }) 704 } 705 706 // Test1825 tests that OpcodeInsertlane allocates correctly the temporary registers. 707 func Test1825(t *testing.T) { 708 if !platform.CompilerSupported() { 709 return 710 } 711 run(t, func(t *testing.T, r wazero.Runtime) { 712 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1825")) 713 require.NoError(t, err) 714 m := mod.(*wasm.ModuleInstance) 715 _, err = m.ExportedFunction("").Call(ctx) 716 require.NoError(t, err) 717 require.Equal(t, uint64(1099511627775), m.Globals[6].Val) 718 require.Equal(t, uint64(18446744073709551615), m.Globals[6].ValHi) 719 }) 720 } 721 722 // Test1826 tests that lowerFcopysignImpl allocates correctly the temporary registers. 723 func Test1826(t *testing.T) { 724 if !platform.CompilerSupported() { 725 return 726 } 727 run(t, func(t *testing.T, r wazero.Runtime) { 728 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1826")) 729 require.NoError(t, err) 730 m := mod.(*wasm.ModuleInstance) 731 _, err = m.ExportedFunction("3").Call(ctx, 0, 0) 732 require.NoError(t, err) 733 require.Equal(t, uint64(1608723901141126568), m.Globals[0].Val) 734 require.Equal(t, uint64(0), m.Globals[0].ValHi) 735 }) 736 } 737 738 func Test1846(t *testing.T) { 739 if !platform.CompilerSupported() { 740 return 741 } 742 run(t, func(t *testing.T, r wazero.Runtime) { 743 mod, err := r.Instantiate(ctx, getWasmBinary(t, "1846")) 744 require.NoError(t, err) 745 m := mod.(*wasm.ModuleInstance) 746 _, err = m.ExportedFunction("").Call(ctx) 747 require.NoError(t, err) 748 require.Equal(t, math.Float64bits(2), m.Globals[0].Val) 749 require.Equal(t, uint64(0), m.Globals[0].ValHi) 750 }) 751 }