github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/engine/wazevo/testcases/testcases.go (about) 1 package testcases 2 3 import ( 4 "math" 5 6 "github.com/tetratelabs/wazero/internal/leb128" 7 "github.com/tetratelabs/wazero/internal/wasm" 8 ) 9 10 const ExportedFunctionName = "f" 11 12 var ( 13 Empty = TestCase{Name: "empty", Module: SingleFunctionModule(vv, []byte{wasm.OpcodeEnd}, nil)} 14 Constants = TestCase{Name: "consts", Module: SingleFunctionModule(wasm.FunctionType{ 15 Results: []wasm.ValueType{i32, i64, f32, f64}, 16 }, []byte{ 17 wasm.OpcodeI32Const, 1, 18 wasm.OpcodeI64Const, 2, 19 wasm.OpcodeF32Const, 20 byte(math.Float32bits(32.0)), 21 byte(math.Float32bits(32.0) >> 8), 22 byte(math.Float32bits(32.0) >> 16), 23 byte(math.Float32bits(32.0) >> 24), 24 wasm.OpcodeF64Const, 25 byte(math.Float64bits(64.0)), 26 byte(math.Float64bits(64.0) >> 8), 27 byte(math.Float64bits(64.0) >> 16), 28 byte(math.Float64bits(64.0) >> 24), 29 byte(math.Float64bits(64.0) >> 32), 30 byte(math.Float64bits(64.0) >> 40), 31 byte(math.Float64bits(64.0) >> 48), 32 byte(math.Float64bits(64.0) >> 56), 33 wasm.OpcodeEnd, 34 }, nil)} 35 Unreachable = TestCase{Name: "unreachable", Module: SingleFunctionModule(vv, []byte{wasm.OpcodeUnreachable, wasm.OpcodeEnd}, nil)} 36 OnlyReturn = TestCase{Name: "only_return", Module: SingleFunctionModule(vv, []byte{wasm.OpcodeReturn, wasm.OpcodeEnd}, nil)} 37 Params = TestCase{Name: "params", Module: SingleFunctionModule(i32f32f64_v, []byte{wasm.OpcodeReturn, wasm.OpcodeEnd}, nil)} 38 AddSubReturn = TestCase{ 39 Name: "add_sub_params_return_const", 40 Module: SingleFunctionModule(wasm.FunctionType{Results: []wasm.ValueType{i32, i32, i64, i64}}, []byte{ 41 // Small i32 constants should be inlined on arm64, amd64. 42 wasm.OpcodeI32Const, 4, 43 wasm.OpcodeI32Const, 5, 44 wasm.OpcodeI32Add, 45 wasm.OpcodeI32Const, 6, 46 wasm.OpcodeI32Sub, 47 48 // Large i32 constants should be inlined on amd4, load from register on arm64. 49 wasm.OpcodeI32Const, 3, 50 wasm.OpcodeI32Const, 0xff, 0xff, 0xff, 0xff, 0, 51 wasm.OpcodeI32Add, 52 wasm.OpcodeI32Const, 0xff, 0xff, 0xff, 0xff, 0, 53 wasm.OpcodeI32Sub, 54 55 // Small i64 constants should be inlined on arm64, amd64. 56 wasm.OpcodeI64Const, 4, 57 wasm.OpcodeI64Const, 5, 58 wasm.OpcodeI64Add, 59 wasm.OpcodeI64Const, 6, 60 wasm.OpcodeI64Sub, 61 62 // Large i64 constants are loaded from register on arm64, amd64. 63 wasm.OpcodeI64Const, 3, 64 wasm.OpcodeI64Const, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 65 wasm.OpcodeI64Add, 66 wasm.OpcodeI64Const, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 67 wasm.OpcodeI64Sub, 68 69 wasm.OpcodeEnd, 70 }, nil), 71 } 72 AddSubParamsReturn = TestCase{ 73 Name: "add_sub_params_return", 74 Module: SingleFunctionModule(i32i32_i32, []byte{ 75 wasm.OpcodeLocalGet, 0, 76 wasm.OpcodeLocalGet, 1, 77 wasm.OpcodeI32Add, 78 wasm.OpcodeLocalGet, 0, 79 wasm.OpcodeI32Sub, 80 wasm.OpcodeEnd, 81 }, nil), 82 } 83 ArithmReturn = TestCase{ 84 Name: "arithm return", 85 Module: SingleFunctionModule( 86 wasm.FunctionType{ 87 Params: []wasm.ValueType{i32, i32, i32, i64, i64, i64}, 88 Results: []wasm.ValueType{ 89 i32, i32, i32, i32, 90 i32, i32, i32, 91 i32, i32, 92 93 i64, i64, i64, i64, 94 i64, i64, i64, 95 i64, i64, 96 }, 97 }, 98 []byte{ 99 wasm.OpcodeLocalGet, 0, 100 wasm.OpcodeLocalGet, 1, 101 wasm.OpcodeI32Mul, 102 wasm.OpcodeLocalGet, 0, 103 wasm.OpcodeLocalGet, 1, 104 wasm.OpcodeI32And, 105 wasm.OpcodeLocalGet, 0, 106 wasm.OpcodeLocalGet, 1, 107 wasm.OpcodeI32Or, 108 wasm.OpcodeLocalGet, 0, 109 wasm.OpcodeLocalGet, 1, 110 wasm.OpcodeI32Xor, 111 112 wasm.OpcodeLocalGet, 0, 113 wasm.OpcodeLocalGet, 1, 114 wasm.OpcodeI32Shl, 115 wasm.OpcodeLocalGet, 0, 116 wasm.OpcodeLocalGet, 2, 117 wasm.OpcodeI32ShrS, 118 wasm.OpcodeLocalGet, 0, 119 wasm.OpcodeLocalGet, 1, 120 wasm.OpcodeI32ShrU, 121 122 wasm.OpcodeLocalGet, 0, 123 wasm.OpcodeLocalGet, 1, 124 wasm.OpcodeI32Rotr, 125 // Exercise the case where the amount is an immediate. 126 wasm.OpcodeI32Const, 10, 127 wasm.OpcodeLocalGet, 0, 128 wasm.OpcodeI32Rotl, 129 130 // i64 131 132 wasm.OpcodeLocalGet, 3, 133 wasm.OpcodeLocalGet, 4, 134 wasm.OpcodeI64Mul, 135 wasm.OpcodeLocalGet, 3, 136 wasm.OpcodeLocalGet, 4, 137 wasm.OpcodeI64And, 138 wasm.OpcodeLocalGet, 3, 139 wasm.OpcodeLocalGet, 4, 140 wasm.OpcodeI64Or, 141 wasm.OpcodeLocalGet, 3, 142 wasm.OpcodeLocalGet, 4, 143 wasm.OpcodeI64Xor, 144 145 wasm.OpcodeLocalGet, 3, 146 wasm.OpcodeLocalGet, 4, 147 wasm.OpcodeI64Shl, 148 wasm.OpcodeLocalGet, 5, 149 wasm.OpcodeLocalGet, 4, 150 wasm.OpcodeI64ShrS, 151 wasm.OpcodeLocalGet, 3, 152 wasm.OpcodeLocalGet, 4, 153 wasm.OpcodeI64ShrU, 154 155 wasm.OpcodeLocalGet, 3, 156 wasm.OpcodeLocalGet, 4, 157 wasm.OpcodeI64Rotr, 158 // Exercise the case where the amount is an immediate. 159 wasm.OpcodeI64Const, 10, 160 wasm.OpcodeLocalGet, 3, 161 wasm.OpcodeI64Rotl, 162 163 wasm.OpcodeEnd, 164 }, nil), 165 } 166 DivUReturn32 = TestCase{ 167 Name: "div return unsigned 32", 168 Module: SingleFunctionModule( 169 wasm.FunctionType{ 170 Params: []wasm.ValueType{i32, i32, i32, i32}, 171 Results: []wasm.ValueType{i32, i32}, 172 }, 173 []byte{ 174 wasm.OpcodeLocalGet, 0, 175 wasm.OpcodeLocalGet, 1, 176 wasm.OpcodeI32DivU, 177 178 wasm.OpcodeLocalGet, 2, 179 wasm.OpcodeLocalGet, 3, 180 wasm.OpcodeI32RemU, 181 182 wasm.OpcodeEnd, 183 }, nil), 184 } 185 DivUReturn64 = TestCase{ 186 Name: "div return unsigned 64", 187 Module: SingleFunctionModule( 188 wasm.FunctionType{ 189 Params: []wasm.ValueType{i64, i64, i64, i64}, 190 Results: []wasm.ValueType{i64, i64}, 191 }, 192 []byte{ 193 wasm.OpcodeLocalGet, 0, 194 wasm.OpcodeLocalGet, 1, 195 wasm.OpcodeI64DivU, 196 197 wasm.OpcodeLocalGet, 2, 198 wasm.OpcodeLocalGet, 3, 199 wasm.OpcodeI64RemU, 200 201 wasm.OpcodeEnd, 202 }, nil), 203 } 204 DivSReturn32 = TestCase{ 205 Name: "div return signed 32", 206 Module: SingleFunctionModule( 207 wasm.FunctionType{ 208 Params: []wasm.ValueType{i32, i32, i32, i32}, 209 Results: []wasm.ValueType{i32, i32}, 210 }, 211 []byte{ 212 wasm.OpcodeLocalGet, 0, 213 wasm.OpcodeLocalGet, 1, 214 wasm.OpcodeI32DivS, 215 216 wasm.OpcodeLocalGet, 2, 217 wasm.OpcodeLocalGet, 3, 218 wasm.OpcodeI32RemS, 219 220 wasm.OpcodeEnd, 221 }, nil), 222 } 223 DivSReturn32_weird = TestCase{ 224 Name: "div return signed 32", 225 Module: SingleFunctionModule( 226 wasm.FunctionType{ 227 Params: []wasm.ValueType{i32, i32, i32, i32}, 228 Results: []wasm.ValueType{i32, i32}, 229 }, 230 []byte{ 231 wasm.OpcodeLocalGet, 2, 232 wasm.OpcodeLocalGet, 3, 233 wasm.OpcodeI32RemS, 234 235 wasm.OpcodeLocalGet, 0, 236 wasm.OpcodeLocalGet, 1, 237 wasm.OpcodeI32DivS, 238 239 wasm.OpcodeEnd, 240 }, nil), 241 } 242 243 DivSReturn64 = TestCase{ 244 Name: "div return signed 64", 245 Module: SingleFunctionModule( 246 wasm.FunctionType{ 247 Params: []wasm.ValueType{i64, i64, i64, i64}, 248 Results: []wasm.ValueType{i64, i64}, 249 }, 250 []byte{ 251 wasm.OpcodeLocalGet, 0, 252 wasm.OpcodeLocalGet, 1, 253 wasm.OpcodeI64DivS, 254 255 wasm.OpcodeLocalGet, 2, 256 wasm.OpcodeLocalGet, 3, 257 wasm.OpcodeI64RemS, 258 259 wasm.OpcodeEnd, 260 }, nil), 261 } 262 Locals = TestCase{Name: "locals", Module: SingleFunctionModule(vv, []byte{wasm.OpcodeEnd}, []wasm.ValueType{i32, i64, f32, f64})} 263 LocalsParams = TestCase{ 264 Name: "locals_params", 265 Module: SingleFunctionModule( 266 i64f32f64_i64f32f64, 267 []byte{ 268 wasm.OpcodeLocalGet, 0, 269 wasm.OpcodeLocalGet, 0, 270 wasm.OpcodeI64Add, 271 wasm.OpcodeLocalGet, 0, 272 wasm.OpcodeI64Sub, 273 274 wasm.OpcodeLocalGet, 1, 275 wasm.OpcodeLocalGet, 1, 276 wasm.OpcodeF32Add, 277 wasm.OpcodeLocalGet, 1, 278 wasm.OpcodeF32Sub, 279 wasm.OpcodeLocalGet, 1, 280 wasm.OpcodeF32Mul, 281 wasm.OpcodeLocalGet, 1, 282 wasm.OpcodeF32Div, 283 wasm.OpcodeLocalGet, 1, 284 wasm.OpcodeF32Max, 285 wasm.OpcodeLocalGet, 1, 286 wasm.OpcodeF32Min, 287 288 wasm.OpcodeLocalGet, 2, 289 wasm.OpcodeLocalGet, 2, 290 wasm.OpcodeF64Add, 291 wasm.OpcodeLocalGet, 2, 292 wasm.OpcodeF64Sub, 293 wasm.OpcodeLocalGet, 2, 294 wasm.OpcodeF64Mul, 295 wasm.OpcodeLocalGet, 2, 296 wasm.OpcodeF64Div, 297 wasm.OpcodeLocalGet, 2, 298 wasm.OpcodeF64Max, 299 wasm.OpcodeLocalGet, 2, 300 wasm.OpcodeF64Min, 301 302 wasm.OpcodeEnd, 303 }, []wasm.ValueType{i32, i64, f32, f64}, 304 ), 305 } 306 LocalParamReturn = TestCase{ 307 Name: "local_param_return", 308 Module: SingleFunctionModule(i32_i32i32, []byte{ 309 wasm.OpcodeLocalGet, 0, 310 wasm.OpcodeLocalGet, 1, 311 wasm.OpcodeEnd, 312 }, []wasm.ValueType{i32}), 313 } 314 LocalParamTeeReturn = TestCase{ 315 Name: "local_param_tee_return", 316 Module: SingleFunctionModule(i32_i32i32, []byte{ 317 wasm.OpcodeLocalGet, 0, 318 wasm.OpcodeLocalTee, 1, 319 wasm.OpcodeLocalGet, 1, 320 wasm.OpcodeEnd, 321 }, []wasm.ValueType{i32}), 322 } 323 SwapParamAndReturn = TestCase{ 324 Name: "swap_param_and_return", 325 Module: SingleFunctionModule(i32i32_i32i32, []byte{ 326 wasm.OpcodeLocalGet, 1, 327 wasm.OpcodeLocalGet, 0, 328 wasm.OpcodeEnd, 329 }, nil), 330 } 331 Selects = TestCase{ 332 Name: "swap_param_and_return", 333 Module: SingleFunctionModule(i32i32i64i64f32f32f64f64_i32i64, []byte{ 334 // i32 select. 335 wasm.OpcodeLocalGet, 0, // x 336 wasm.OpcodeLocalGet, 1, // y 337 // cond 338 wasm.OpcodeLocalGet, 2, 339 wasm.OpcodeLocalGet, 3, 340 wasm.OpcodeI64Eq, 341 wasm.OpcodeSelect, 342 343 // i64 select. 344 wasm.OpcodeLocalGet, 2, // x 345 wasm.OpcodeLocalGet, 3, // y 346 wasm.OpcodeLocalGet, 1, // cond 347 wasm.OpcodeTypedSelect, 1, wasm.ValueTypeI64, 348 349 // f32 select. 350 wasm.OpcodeLocalGet, 4, // x 351 wasm.OpcodeLocalGet, 5, // y 352 // cond 353 wasm.OpcodeLocalGet, 6, 354 wasm.OpcodeLocalGet, 7, 355 wasm.OpcodeF64Gt, 356 wasm.OpcodeTypedSelect, 1, wasm.ValueTypeF32, 357 358 // f64 select. 359 wasm.OpcodeLocalGet, 6, // x 360 wasm.OpcodeLocalGet, 7, // y 361 // cond 362 wasm.OpcodeLocalGet, 4, 363 wasm.OpcodeLocalGet, 5, 364 wasm.OpcodeF32Ne, 365 wasm.OpcodeTypedSelect, 1, wasm.ValueTypeF64, 366 367 wasm.OpcodeEnd, 368 }, nil), 369 } 370 SwapParamsAndReturn = TestCase{ 371 Name: "swap_params_and_return", 372 Module: SingleFunctionModule(i32i32_i32i32, []byte{ 373 wasm.OpcodeLocalGet, 1, 374 wasm.OpcodeLocalGet, 0, 375 wasm.OpcodeLocalSet, 1, 376 wasm.OpcodeLocalSet, 0, 377 wasm.OpcodeBlock, blockSignature_vv, 378 wasm.OpcodeEnd, 379 wasm.OpcodeLocalGet, 0, 380 wasm.OpcodeLocalGet, 1, 381 wasm.OpcodeEnd, 382 }, nil), 383 } 384 BlockBr = TestCase{ 385 Name: "block_br", 386 Module: SingleFunctionModule(vv, []byte{ 387 wasm.OpcodeBlock, 0, 388 wasm.OpcodeBr, 0, 389 wasm.OpcodeEnd, 390 wasm.OpcodeEnd, 391 }, []wasm.ValueType{i32, i64, f32, f64}), 392 } 393 BlockBrIf = TestCase{ 394 Name: "block_br_if", 395 Module: SingleFunctionModule(vv, []byte{ 396 wasm.OpcodeBlock, 0, 397 wasm.OpcodeLocalGet, 0, 398 wasm.OpcodeBrIf, 0, 399 wasm.OpcodeUnreachable, 400 wasm.OpcodeEnd, 401 wasm.OpcodeEnd, 402 }, []wasm.ValueType{i32}), 403 } 404 LoopBr = TestCase{ 405 Name: "loop_br", 406 Module: SingleFunctionModule(vv, []byte{ 407 wasm.OpcodeLoop, 0, 408 wasm.OpcodeBr, 0, 409 wasm.OpcodeEnd, 410 wasm.OpcodeEnd, 411 }, []wasm.ValueType{}), 412 } 413 LoopBrWithParamResults = TestCase{ 414 Name: "loop_with_param_results", 415 Module: SingleFunctionModule(i32i32_i32, []byte{ 416 wasm.OpcodeLocalGet, 0, 417 wasm.OpcodeLocalGet, 1, 418 wasm.OpcodeLoop, 0, 419 wasm.OpcodeI32Const, 1, 420 wasm.OpcodeBrIf, 0, 421 wasm.OpcodeDrop, 422 wasm.OpcodeEnd, 423 wasm.OpcodeEnd, 424 }, []wasm.ValueType{}), 425 } 426 LoopBrIf = TestCase{ 427 Name: "loop_br_if", 428 Module: SingleFunctionModule(vv, []byte{ 429 wasm.OpcodeLoop, 0, 430 wasm.OpcodeI32Const, 1, 431 wasm.OpcodeBrIf, 0, 432 wasm.OpcodeReturn, 433 wasm.OpcodeEnd, 434 wasm.OpcodeEnd, 435 }, []wasm.ValueType{}), 436 } 437 BlockBlockBr = TestCase{ 438 Name: "block_block_br", 439 Module: SingleFunctionModule(vv, []byte{ 440 wasm.OpcodeBlock, 0, 441 wasm.OpcodeBlock, 0, 442 wasm.OpcodeBr, 1, 443 wasm.OpcodeEnd, 444 wasm.OpcodeEnd, 445 wasm.OpcodeEnd, 446 }, []wasm.ValueType{i32, i64, f32, f64}), 447 } 448 IfWithoutElse = TestCase{ 449 Name: "if_without_else", 450 Module: SingleFunctionModule(vv, []byte{ 451 wasm.OpcodeLocalGet, 0, 452 wasm.OpcodeIf, 0, 453 wasm.OpcodeEnd, 454 wasm.OpcodeEnd, 455 }, []wasm.ValueType{i32}), 456 } 457 IfElse = TestCase{ 458 Name: "if_else", 459 Module: SingleFunctionModule(vv, []byte{ 460 wasm.OpcodeLocalGet, 0, 461 wasm.OpcodeIf, 0, 462 wasm.OpcodeElse, 463 wasm.OpcodeBr, 1, 464 wasm.OpcodeEnd, 465 wasm.OpcodeEnd, 466 }, []wasm.ValueType{i32}), 467 } 468 SinglePredecessorLocalRefs = TestCase{ 469 Name: "single_predecessor_local_refs", 470 Module: &wasm.Module{ 471 TypeSection: []wasm.FunctionType{vv, v_i32}, 472 FunctionSection: []wasm.Index{1}, 473 CodeSection: []wasm.Code{{ 474 LocalTypes: []wasm.ValueType{i32, i32, i32}, 475 Body: []byte{ 476 wasm.OpcodeLocalGet, 0, 477 wasm.OpcodeIf, 0, 478 // This is defined in the first block which is the sole predecessor of If. 479 wasm.OpcodeLocalGet, 2, 480 wasm.OpcodeReturn, 481 wasm.OpcodeElse, 482 wasm.OpcodeEnd, 483 // This is defined in the first block which is the sole predecessor of this block. 484 // Note that If block will never reach here because it's returning early. 485 wasm.OpcodeLocalGet, 0, 486 wasm.OpcodeEnd, 487 }, 488 }}, 489 }, 490 } 491 MultiPredecessorLocalRef = TestCase{ 492 Name: "multi_predecessor_local_ref", 493 Module: SingleFunctionModule(i32i32_i32, []byte{ 494 wasm.OpcodeLocalGet, 0, 495 wasm.OpcodeIf, blockSignature_vv, 496 // Set the first param to the local. 497 wasm.OpcodeLocalGet, 0, 498 wasm.OpcodeLocalSet, 2, 499 wasm.OpcodeElse, 500 // Set the second param to the local. 501 wasm.OpcodeLocalGet, 1, 502 wasm.OpcodeLocalSet, 2, 503 wasm.OpcodeEnd, 504 505 // Return the local as a result which has multiple definitions in predecessors (Then and Else). 506 wasm.OpcodeLocalGet, 2, 507 wasm.OpcodeEnd, 508 }, []wasm.ValueType{i32}), 509 } 510 ReferenceValueFromUnsealedBlock = TestCase{ 511 Name: "reference_value_from_unsealed_block", 512 Module: SingleFunctionModule(i32_i32, []byte{ 513 wasm.OpcodeLoop, blockSignature_vv, 514 // Loop will not be sealed until we reach the end, 515 // so this will result in referencing the unsealed definition search. 516 wasm.OpcodeLocalGet, 0, 517 wasm.OpcodeReturn, 518 wasm.OpcodeEnd, 519 wasm.OpcodeLocalGet, 0, 520 wasm.OpcodeEnd, 521 }, []wasm.ValueType{i32}), 522 } 523 ReferenceValueFromUnsealedBlock2 = TestCase{ 524 Name: "reference_value_from_unsealed_block2", 525 Module: SingleFunctionModule(i32_i32, []byte{ 526 wasm.OpcodeLoop, blockSignature_vv, 527 wasm.OpcodeBlock, blockSignature_vv, 528 529 wasm.OpcodeLocalGet, 0, 530 wasm.OpcodeBrIf, 1, 531 wasm.OpcodeEnd, 532 533 wasm.OpcodeEnd, 534 wasm.OpcodeI32Const, 0, 535 wasm.OpcodeEnd, 536 }, []wasm.ValueType{}), 537 } 538 ReferenceValueFromUnsealedBlock3 = TestCase{ 539 Name: "reference_value_from_unsealed_block3", 540 Module: SingleFunctionModule(i32_v, []byte{ 541 wasm.OpcodeLoop, blockSignature_vv, 542 wasm.OpcodeBlock, blockSignature_vv, 543 wasm.OpcodeLocalGet, 0, 544 wasm.OpcodeBrIf, 2, 545 wasm.OpcodeEnd, 546 wasm.OpcodeI32Const, 1, 547 wasm.OpcodeLocalSet, 0, 548 wasm.OpcodeBr, 0, 549 wasm.OpcodeEnd, 550 wasm.OpcodeEnd, 551 }, []wasm.ValueType{}), 552 } 553 CallSimple = TestCase{ 554 Name: "call_simple", 555 Module: &wasm.Module{ 556 TypeSection: []wasm.FunctionType{v_i32, v_i32}, 557 FunctionSection: []wasm.Index{0, 1}, 558 CodeSection: []wasm.Code{ 559 {Body: []byte{ 560 // Call v_i32. 561 wasm.OpcodeCall, 1, 562 wasm.OpcodeEnd, 563 }}, 564 // v_i32: return 40. 565 {Body: []byte{wasm.OpcodeI32Const, 40, wasm.OpcodeEnd}}, 566 }, 567 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Index: 0, Type: wasm.ExternTypeFunc}}, 568 }, 569 } 570 Call = TestCase{ 571 Name: "call", 572 Module: &wasm.Module{ 573 TypeSection: []wasm.FunctionType{v_i32i32, v_i32, i32i32_i32, i32_i32i32}, 574 FunctionSection: []wasm.Index{0, 1, 2, 3}, 575 CodeSection: []wasm.Code{ 576 {Body: []byte{ 577 // Call v_i32. 578 wasm.OpcodeCall, 1, 579 // Call i32i32_i32. 580 wasm.OpcodeI32Const, 5, 581 wasm.OpcodeCall, 2, 582 // Call i32_i32i32. 583 wasm.OpcodeCall, 3, 584 wasm.OpcodeEnd, 585 }}, 586 // v_i32: return 100. 587 {Body: []byte{wasm.OpcodeI32Const, 40, wasm.OpcodeEnd}}, 588 // i32i32_i32: adds. 589 {Body: []byte{wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeI32Add, wasm.OpcodeEnd}}, 590 // i32_i32i32: duplicates. 591 {Body: []byte{wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 0, wasm.OpcodeEnd}}, 592 }, 593 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Index: 0, Type: wasm.ExternTypeFunc}}, 594 }, 595 } 596 ManyMiddleValues = TestCase{ 597 Name: "many_middle_values", 598 Module: SingleFunctionModule(wasm.FunctionType{ 599 Params: []wasm.ValueType{i32, f32}, 600 Results: []wasm.ValueType{i32, f32}, 601 }, []byte{ 602 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 1, wasm.OpcodeI32Mul, 603 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 2, wasm.OpcodeI32Mul, 604 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 3, wasm.OpcodeI32Mul, 605 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 4, wasm.OpcodeI32Mul, 606 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 5, wasm.OpcodeI32Mul, 607 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 6, wasm.OpcodeI32Mul, 608 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 7, wasm.OpcodeI32Mul, 609 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 8, wasm.OpcodeI32Mul, 610 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 9, wasm.OpcodeI32Mul, 611 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 10, wasm.OpcodeI32Mul, 612 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 11, wasm.OpcodeI32Mul, 613 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 12, wasm.OpcodeI32Mul, 614 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 13, wasm.OpcodeI32Mul, 615 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 14, wasm.OpcodeI32Mul, 616 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 15, wasm.OpcodeI32Mul, 617 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 16, wasm.OpcodeI32Mul, 618 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 17, wasm.OpcodeI32Mul, 619 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 18, wasm.OpcodeI32Mul, 620 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 19, wasm.OpcodeI32Mul, 621 wasm.OpcodeLocalGet, 0, wasm.OpcodeI32Const, 20, wasm.OpcodeI32Mul, 622 623 wasm.OpcodeI32Add, wasm.OpcodeI32Add, wasm.OpcodeI32Add, wasm.OpcodeI32Add, wasm.OpcodeI32Add, 624 wasm.OpcodeI32Add, wasm.OpcodeI32Add, wasm.OpcodeI32Add, wasm.OpcodeI32Add, wasm.OpcodeI32Add, 625 wasm.OpcodeI32Add, wasm.OpcodeI32Add, wasm.OpcodeI32Add, wasm.OpcodeI32Add, wasm.OpcodeI32Add, 626 wasm.OpcodeI32Add, wasm.OpcodeI32Add, wasm.OpcodeI32Add, wasm.OpcodeI32Add, 627 628 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x80, 0x3f, wasm.OpcodeF32Mul, 629 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0, 0x40, wasm.OpcodeF32Mul, 630 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x40, 0x40, wasm.OpcodeF32Mul, 631 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x80, 0x40, wasm.OpcodeF32Mul, 632 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0xa0, 0x40, wasm.OpcodeF32Mul, 633 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0xc0, 0x40, wasm.OpcodeF32Mul, 634 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0xe0, 0x40, wasm.OpcodeF32Mul, 635 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0, 0x41, wasm.OpcodeF32Mul, 636 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x10, 0x41, wasm.OpcodeF32Mul, 637 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x20, 0x41, wasm.OpcodeF32Mul, 638 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x30, 0x41, wasm.OpcodeF32Mul, 639 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x40, 0x41, wasm.OpcodeF32Mul, 640 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x50, 0x41, wasm.OpcodeF32Mul, 641 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x60, 0x41, wasm.OpcodeF32Mul, 642 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x70, 0x41, wasm.OpcodeF32Mul, 643 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x80, 0x41, wasm.OpcodeF32Mul, 644 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x88, 0x41, wasm.OpcodeF32Mul, 645 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x90, 0x41, wasm.OpcodeF32Mul, 646 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0x98, 0x41, wasm.OpcodeF32Mul, 647 wasm.OpcodeLocalGet, 1, wasm.OpcodeF32Const, 0, 0, 0xa0, 0x41, wasm.OpcodeF32Mul, 648 649 wasm.OpcodeF32Add, wasm.OpcodeF32Add, wasm.OpcodeF32Add, wasm.OpcodeF32Add, wasm.OpcodeF32Add, 650 wasm.OpcodeF32Add, wasm.OpcodeF32Add, wasm.OpcodeF32Add, wasm.OpcodeF32Add, wasm.OpcodeF32Add, 651 wasm.OpcodeF32Add, wasm.OpcodeF32Add, wasm.OpcodeF32Add, wasm.OpcodeF32Add, wasm.OpcodeF32Add, 652 wasm.OpcodeF32Add, wasm.OpcodeF32Add, wasm.OpcodeF32Add, wasm.OpcodeF32Add, 653 654 wasm.OpcodeEnd, 655 }, nil), 656 } 657 CallManyParams = TestCase{ 658 Name: "call_many_params", 659 Module: &wasm.Module{ 660 TypeSection: []wasm.FunctionType{ 661 {Params: []wasm.ValueType{i32, i64, f32, f64}}, 662 { 663 Params: []wasm.ValueType{ 664 i32, i64, f32, f64, i32, i64, f32, f64, 665 i32, i64, f32, f64, i32, i64, f32, f64, 666 i32, i64, f32, f64, i32, i64, f32, f64, 667 i32, i64, f32, f64, i32, i64, f32, f64, 668 i32, i64, f32, f64, i32, i64, f32, f64, 669 }, 670 }, 671 }, 672 FunctionSection: []wasm.Index{0, 1}, 673 CodeSection: []wasm.Code{ 674 { 675 Body: []byte{ 676 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 677 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 678 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 679 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 680 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 681 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 682 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 683 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 684 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 685 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 686 wasm.OpcodeCall, 1, 687 wasm.OpcodeEnd, 688 }, 689 }, 690 {Body: []byte{wasm.OpcodeEnd}}, 691 }, 692 }, 693 } 694 CallManyReturns = TestCase{ 695 Name: "call_many_returns", 696 Module: &wasm.Module{ 697 TypeSection: []wasm.FunctionType{ 698 { 699 Params: []wasm.ValueType{i32, i64, f32, f64}, 700 Results: []wasm.ValueType{ 701 i32, i64, f32, f64, i32, i64, f32, f64, 702 i32, i64, f32, f64, i32, i64, f32, f64, 703 i32, i64, f32, f64, i32, i64, f32, f64, 704 i32, i64, f32, f64, i32, i64, f32, f64, 705 i32, i64, f32, f64, i32, i64, f32, f64, 706 }, 707 }, 708 }, 709 FunctionSection: []wasm.Index{0, 0}, 710 CodeSection: []wasm.Code{ 711 { 712 Body: []byte{ 713 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 714 wasm.OpcodeCall, 1, 715 wasm.OpcodeEnd, 716 }, 717 }, 718 {Body: []byte{ 719 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 720 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 721 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 722 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 723 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 724 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 725 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 726 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 727 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 728 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 729 wasm.OpcodeEnd, 730 }}, 731 }, 732 }, 733 } 734 ManyParamsSmallResults = TestCase{ 735 Name: "many_params_small_results", 736 Module: SingleFunctionModule(wasm.FunctionType{ 737 Params: []wasm.ValueType{ 738 i32, i64, f32, f64, i32, i64, f32, f64, 739 i32, i64, f32, f64, i32, i64, f32, f64, 740 i32, i64, f32, f64, i32, i64, f32, f64, 741 i32, i64, f32, f64, i32, i64, f32, f64, 742 i32, i64, f32, f64, i32, i64, f32, f64, 743 }, 744 Results: []wasm.ValueType{ 745 i32, i64, f32, f64, 746 }, 747 }, []byte{ 748 wasm.OpcodeLocalGet, 0, 749 wasm.OpcodeLocalGet, 9, 750 wasm.OpcodeLocalGet, 18, 751 wasm.OpcodeLocalGet, 27, 752 wasm.OpcodeEnd, 753 }, nil), 754 } 755 SmallParamsManyResults = TestCase{ 756 Name: "small_params_many_results", 757 Module: SingleFunctionModule(wasm.FunctionType{ 758 Params: []wasm.ValueType{i32, i64, f32, f64}, 759 Results: []wasm.ValueType{ 760 i32, i64, f32, f64, i32, i64, f32, f64, 761 i32, i64, f32, f64, i32, i64, f32, f64, 762 i32, i64, f32, f64, i32, i64, f32, f64, 763 i32, i64, f32, f64, i32, i64, f32, f64, 764 i32, i64, f32, f64, i32, i64, f32, f64, 765 }, 766 }, []byte{ 767 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 768 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 769 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 770 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 771 wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 3, 772 wasm.OpcodeEnd, 773 }, nil), 774 } 775 ManyParamsManyResults = TestCase{ 776 Name: "many_params_many_results", 777 Module: SingleFunctionModule(wasm.FunctionType{ 778 Params: []wasm.ValueType{ 779 i32, i64, f32, f64, i32, i64, f32, f64, 780 i32, i64, f32, f64, i32, i64, f32, f64, 781 i32, i64, f32, f64, i32, i64, f32, f64, 782 i32, i64, f32, f64, i32, i64, f32, f64, 783 i32, i64, f32, f64, i32, i64, f32, f64, 784 }, 785 Results: []wasm.ValueType{ 786 f64, f32, i64, i32, f64, f32, i64, i32, 787 f64, f32, i64, i32, f64, f32, i64, i32, 788 f64, f32, i64, i32, f64, f32, i64, i32, 789 f64, f32, i64, i32, f64, f32, i64, i32, 790 f64, f32, i64, i32, f64, f32, i64, i32, 791 }, 792 }, []byte{ 793 wasm.OpcodeLocalGet, 39, wasm.OpcodeLocalGet, 38, wasm.OpcodeLocalGet, 37, wasm.OpcodeLocalGet, 36, 794 wasm.OpcodeLocalGet, 35, wasm.OpcodeLocalGet, 34, wasm.OpcodeLocalGet, 33, wasm.OpcodeLocalGet, 32, 795 wasm.OpcodeLocalGet, 31, wasm.OpcodeLocalGet, 30, wasm.OpcodeLocalGet, 29, wasm.OpcodeLocalGet, 28, 796 wasm.OpcodeLocalGet, 27, wasm.OpcodeLocalGet, 26, wasm.OpcodeLocalGet, 25, wasm.OpcodeLocalGet, 24, 797 wasm.OpcodeLocalGet, 23, wasm.OpcodeLocalGet, 22, wasm.OpcodeLocalGet, 21, wasm.OpcodeLocalGet, 20, 798 wasm.OpcodeLocalGet, 19, wasm.OpcodeLocalGet, 18, wasm.OpcodeLocalGet, 17, wasm.OpcodeLocalGet, 16, 799 wasm.OpcodeLocalGet, 15, wasm.OpcodeLocalGet, 14, wasm.OpcodeLocalGet, 13, wasm.OpcodeLocalGet, 12, 800 wasm.OpcodeLocalGet, 11, wasm.OpcodeLocalGet, 10, wasm.OpcodeLocalGet, 9, wasm.OpcodeLocalGet, 8, 801 wasm.OpcodeLocalGet, 7, wasm.OpcodeLocalGet, 6, wasm.OpcodeLocalGet, 5, wasm.OpcodeLocalGet, 4, 802 wasm.OpcodeLocalGet, 3, wasm.OpcodeLocalGet, 2, wasm.OpcodeLocalGet, 1, wasm.OpcodeLocalGet, 0, 803 wasm.OpcodeEnd, 804 }, nil), 805 } 806 IntegerComparisons = TestCase{ 807 Name: "integer_comparisons", 808 Module: SingleFunctionModule(wasm.FunctionType{ 809 Params: []wasm.ValueType{i32, i32, i64, i64}, 810 Results: []wasm.ValueType{i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32}, 811 }, []byte{ 812 // eq. 813 wasm.OpcodeLocalGet, 0, 814 wasm.OpcodeLocalGet, 1, 815 wasm.OpcodeI32Eq, 816 wasm.OpcodeLocalGet, 2, 817 wasm.OpcodeLocalGet, 3, 818 wasm.OpcodeI64Eq, 819 // neq. 820 wasm.OpcodeLocalGet, 0, 821 wasm.OpcodeLocalGet, 1, 822 wasm.OpcodeI32Ne, 823 wasm.OpcodeLocalGet, 2, 824 wasm.OpcodeLocalGet, 3, 825 wasm.OpcodeI64Ne, 826 // LtS. 827 wasm.OpcodeLocalGet, 0, 828 wasm.OpcodeLocalGet, 1, 829 wasm.OpcodeI32LtS, 830 wasm.OpcodeLocalGet, 2, 831 wasm.OpcodeLocalGet, 3, 832 wasm.OpcodeI64LtS, 833 // LtU. 834 wasm.OpcodeLocalGet, 0, 835 wasm.OpcodeLocalGet, 1, 836 wasm.OpcodeI32LtU, 837 wasm.OpcodeLocalGet, 2, 838 wasm.OpcodeLocalGet, 3, 839 wasm.OpcodeI64LtU, 840 // GtS. 841 wasm.OpcodeLocalGet, 0, 842 wasm.OpcodeLocalGet, 1, 843 wasm.OpcodeI32GtS, 844 wasm.OpcodeLocalGet, 2, 845 wasm.OpcodeLocalGet, 3, 846 wasm.OpcodeI64GtS, 847 // GtU. 848 wasm.OpcodeLocalGet, 0, 849 wasm.OpcodeLocalGet, 1, 850 wasm.OpcodeI32GtU, 851 wasm.OpcodeLocalGet, 2, 852 wasm.OpcodeLocalGet, 3, 853 wasm.OpcodeI64GtU, 854 // LeS. 855 wasm.OpcodeLocalGet, 0, 856 wasm.OpcodeLocalGet, 1, 857 wasm.OpcodeI32LeS, 858 wasm.OpcodeLocalGet, 2, 859 wasm.OpcodeLocalGet, 3, 860 wasm.OpcodeI64LeS, 861 // LeU. 862 wasm.OpcodeLocalGet, 0, 863 wasm.OpcodeLocalGet, 1, 864 wasm.OpcodeI32LeU, 865 wasm.OpcodeLocalGet, 2, 866 wasm.OpcodeLocalGet, 3, 867 wasm.OpcodeI64LeU, 868 // GeS. 869 wasm.OpcodeLocalGet, 0, 870 wasm.OpcodeLocalGet, 1, 871 wasm.OpcodeI32GeS, 872 wasm.OpcodeLocalGet, 2, 873 wasm.OpcodeLocalGet, 3, 874 wasm.OpcodeI64GeS, 875 // GeU. 876 wasm.OpcodeLocalGet, 0, 877 wasm.OpcodeLocalGet, 1, 878 wasm.OpcodeI32GeU, 879 wasm.OpcodeLocalGet, 2, 880 wasm.OpcodeLocalGet, 3, 881 wasm.OpcodeI64GeU, 882 wasm.OpcodeEnd, 883 }, []wasm.ValueType{}), 884 } 885 IntegerBitwise = TestCase{ 886 Name: "integer_bitwise", 887 Module: SingleFunctionModule(wasm.FunctionType{ 888 Params: []wasm.ValueType{i32, i32, i64, i64}, 889 Results: []wasm.ValueType{i32, i32, i32, i32, i64, i64, i64, i64, i64, i64}, 890 }, []byte{ 891 wasm.OpcodeLocalGet, 0, 892 wasm.OpcodeLocalGet, 1, 893 wasm.OpcodeI32And, 894 895 wasm.OpcodeLocalGet, 0, 896 wasm.OpcodeLocalGet, 1, 897 wasm.OpcodeI32Or, 898 899 wasm.OpcodeLocalGet, 0, 900 wasm.OpcodeLocalGet, 1, 901 wasm.OpcodeI32Xor, 902 903 wasm.OpcodeLocalGet, 0, 904 wasm.OpcodeLocalGet, 1, 905 wasm.OpcodeI32Rotr, 906 907 wasm.OpcodeLocalGet, 2, 908 wasm.OpcodeLocalGet, 3, 909 wasm.OpcodeI64And, 910 911 wasm.OpcodeLocalGet, 2, 912 wasm.OpcodeLocalGet, 3, 913 wasm.OpcodeI64Or, 914 915 wasm.OpcodeLocalGet, 2, 916 wasm.OpcodeLocalGet, 3, 917 wasm.OpcodeI64Xor, 918 919 wasm.OpcodeLocalGet, 2, 920 wasm.OpcodeLocalGet, 3, 921 wasm.OpcodeI64Const, 8, 922 wasm.OpcodeI64Shl, 923 wasm.OpcodeI64Xor, 924 925 wasm.OpcodeLocalGet, 2, 926 wasm.OpcodeLocalGet, 3, 927 wasm.OpcodeI64Rotl, 928 929 wasm.OpcodeLocalGet, 2, 930 wasm.OpcodeLocalGet, 3, 931 wasm.OpcodeI64Rotr, 932 933 wasm.OpcodeEnd, 934 }, []wasm.ValueType{}), 935 } 936 IntegerShift = TestCase{ 937 Name: "integer_shift", 938 Module: SingleFunctionModule(wasm.FunctionType{ 939 Params: []wasm.ValueType{i32, i32, i64, i64}, 940 Results: []wasm.ValueType{i32, i32, i64, i64, i32, i32, i64, i64, i32, i32, i64, i64}, 941 }, []byte{ 942 // logical left. 943 wasm.OpcodeLocalGet, 0, 944 wasm.OpcodeLocalGet, 1, 945 wasm.OpcodeI32Shl, 946 wasm.OpcodeLocalGet, 0, 947 wasm.OpcodeI32Const, 31, 948 wasm.OpcodeI32Shl, 949 wasm.OpcodeLocalGet, 2, 950 wasm.OpcodeLocalGet, 3, 951 wasm.OpcodeI64Shl, 952 wasm.OpcodeLocalGet, 2, 953 wasm.OpcodeI64Const, 32, 954 wasm.OpcodeI64Shl, 955 // logical right. 956 wasm.OpcodeLocalGet, 0, 957 wasm.OpcodeLocalGet, 1, 958 wasm.OpcodeI32ShrU, 959 wasm.OpcodeLocalGet, 0, 960 wasm.OpcodeI32Const, 31, 961 wasm.OpcodeI32ShrU, 962 wasm.OpcodeLocalGet, 2, 963 wasm.OpcodeLocalGet, 3, 964 wasm.OpcodeI64ShrU, 965 wasm.OpcodeLocalGet, 2, 966 wasm.OpcodeI64Const, 32, 967 wasm.OpcodeI64ShrU, 968 // arithmetic right. 969 wasm.OpcodeLocalGet, 0, 970 wasm.OpcodeLocalGet, 1, 971 wasm.OpcodeI32ShrS, 972 wasm.OpcodeLocalGet, 0, 973 wasm.OpcodeI32Const, 31, 974 wasm.OpcodeI32ShrS, 975 wasm.OpcodeLocalGet, 2, 976 wasm.OpcodeLocalGet, 3, 977 wasm.OpcodeI64ShrS, 978 wasm.OpcodeLocalGet, 2, 979 wasm.OpcodeI64Const, 32, 980 wasm.OpcodeI64ShrS, 981 wasm.OpcodeEnd, 982 }, []wasm.ValueType{}), 983 } 984 IntegerExtensions = TestCase{ 985 Name: "integer_extensions", 986 Module: SingleFunctionModule(wasm.FunctionType{ 987 Params: []wasm.ValueType{i32, i64}, 988 Results: []wasm.ValueType{i64, i64, i64, i64, i64, i32, i32}, 989 }, []byte{ 990 wasm.OpcodeLocalGet, 0, 991 wasm.OpcodeI64ExtendI32S, 992 993 wasm.OpcodeLocalGet, 0, 994 wasm.OpcodeI64ExtendI32U, 995 996 wasm.OpcodeLocalGet, 1, 997 wasm.OpcodeI64Extend8S, 998 999 wasm.OpcodeLocalGet, 1, 1000 wasm.OpcodeI64Extend16S, 1001 1002 wasm.OpcodeLocalGet, 1, 1003 wasm.OpcodeI64Extend32S, 1004 1005 wasm.OpcodeLocalGet, 0, 1006 wasm.OpcodeI32Extend8S, 1007 1008 wasm.OpcodeLocalGet, 0, 1009 wasm.OpcodeI32Extend16S, 1010 1011 wasm.OpcodeEnd, 1012 }, []wasm.ValueType{}), 1013 } 1014 IntegerBitCounts = TestCase{ 1015 Name: "integer_bit_counts", 1016 Module: SingleFunctionModule(wasm.FunctionType{ 1017 Params: []wasm.ValueType{i32, i64}, 1018 Results: []wasm.ValueType{i32, i32, i32, i64, i64, i64}, 1019 }, []byte{ 1020 wasm.OpcodeLocalGet, 0, 1021 wasm.OpcodeI32Clz, 1022 1023 wasm.OpcodeLocalGet, 0, 1024 wasm.OpcodeI32Ctz, 1025 1026 wasm.OpcodeLocalGet, 0, 1027 wasm.OpcodeI32Popcnt, 1028 1029 wasm.OpcodeLocalGet, 1, 1030 wasm.OpcodeI64Clz, 1031 1032 wasm.OpcodeLocalGet, 1, 1033 wasm.OpcodeI64Ctz, 1034 1035 wasm.OpcodeLocalGet, 1, 1036 wasm.OpcodeI64Popcnt, 1037 1038 wasm.OpcodeEnd, 1039 }, []wasm.ValueType{}), 1040 } 1041 FloatComparisons = TestCase{ 1042 Name: "float_comparisons", 1043 Module: SingleFunctionModule(wasm.FunctionType{ 1044 Params: []wasm.ValueType{f32, f32, f64, f64}, 1045 Results: []wasm.ValueType{i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32}, 1046 }, []byte{ 1047 wasm.OpcodeLocalGet, 0, 1048 wasm.OpcodeLocalGet, 1, 1049 wasm.OpcodeF32Eq, 1050 wasm.OpcodeLocalGet, 0, 1051 wasm.OpcodeLocalGet, 1, 1052 wasm.OpcodeF32Ne, 1053 wasm.OpcodeLocalGet, 0, 1054 wasm.OpcodeLocalGet, 1, 1055 wasm.OpcodeF32Lt, 1056 wasm.OpcodeLocalGet, 0, 1057 wasm.OpcodeLocalGet, 1, 1058 wasm.OpcodeF32Gt, 1059 wasm.OpcodeLocalGet, 0, 1060 wasm.OpcodeLocalGet, 1, 1061 wasm.OpcodeF32Le, 1062 wasm.OpcodeLocalGet, 0, 1063 wasm.OpcodeLocalGet, 1, 1064 wasm.OpcodeF32Ge, 1065 1066 wasm.OpcodeLocalGet, 2, 1067 wasm.OpcodeLocalGet, 3, 1068 wasm.OpcodeF64Eq, 1069 wasm.OpcodeLocalGet, 2, 1070 wasm.OpcodeLocalGet, 3, 1071 wasm.OpcodeF64Ne, 1072 wasm.OpcodeLocalGet, 2, 1073 wasm.OpcodeLocalGet, 3, 1074 wasm.OpcodeF64Lt, 1075 wasm.OpcodeLocalGet, 2, 1076 wasm.OpcodeLocalGet, 3, 1077 wasm.OpcodeF64Gt, 1078 wasm.OpcodeLocalGet, 2, 1079 wasm.OpcodeLocalGet, 3, 1080 wasm.OpcodeF64Le, 1081 wasm.OpcodeLocalGet, 2, 1082 wasm.OpcodeLocalGet, 3, 1083 wasm.OpcodeF64Ge, 1084 1085 wasm.OpcodeEnd, 1086 }, []wasm.ValueType{}), 1087 } 1088 FloatArithm = TestCase{ 1089 Name: "float_arithm", 1090 Module: SingleFunctionModule(wasm.FunctionType{ 1091 Params: []wasm.ValueType{f64, f64, f64, f32, f32, f32}, 1092 Results: []wasm.ValueType{ 1093 f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, 1094 f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, 1095 }, 1096 }, []byte{ 1097 wasm.OpcodeLocalGet, 0, 1098 wasm.OpcodeF64Neg, 1099 1100 wasm.OpcodeLocalGet, 0, 1101 wasm.OpcodeF64Neg, 1102 wasm.OpcodeF64Abs, 1103 1104 wasm.OpcodeLocalGet, 0, 1105 wasm.OpcodeF64Sqrt, 1106 1107 wasm.OpcodeLocalGet, 0, 1108 wasm.OpcodeLocalGet, 1, 1109 wasm.OpcodeF64Add, 1110 1111 wasm.OpcodeLocalGet, 0, 1112 wasm.OpcodeLocalGet, 1, 1113 wasm.OpcodeF64Sub, 1114 1115 wasm.OpcodeLocalGet, 0, 1116 wasm.OpcodeLocalGet, 1, 1117 wasm.OpcodeF64Mul, 1118 1119 wasm.OpcodeLocalGet, 0, 1120 wasm.OpcodeLocalGet, 1, 1121 wasm.OpcodeF64Div, 1122 1123 wasm.OpcodeLocalGet, 2, 1124 wasm.OpcodeF64Nearest, 1125 1126 wasm.OpcodeLocalGet, 2, 1127 wasm.OpcodeF64Floor, 1128 1129 wasm.OpcodeLocalGet, 2, 1130 wasm.OpcodeF64Ceil, 1131 1132 wasm.OpcodeLocalGet, 2, 1133 wasm.OpcodeF64Trunc, 1134 1135 wasm.OpcodeLocalGet, 0, 1136 wasm.OpcodeLocalGet, 1, 1137 wasm.OpcodeF64Neg, 1138 wasm.OpcodeF64Copysign, 1139 1140 // 32-bit floats. 1141 wasm.OpcodeLocalGet, 3, 1142 wasm.OpcodeF32Neg, 1143 1144 wasm.OpcodeLocalGet, 3, 1145 wasm.OpcodeF32Neg, 1146 wasm.OpcodeF32Abs, 1147 1148 wasm.OpcodeLocalGet, 3, 1149 wasm.OpcodeF32Sqrt, 1150 1151 wasm.OpcodeLocalGet, 3, 1152 wasm.OpcodeLocalGet, 4, 1153 wasm.OpcodeF32Add, 1154 1155 wasm.OpcodeLocalGet, 3, 1156 wasm.OpcodeLocalGet, 4, 1157 wasm.OpcodeF32Sub, 1158 1159 wasm.OpcodeLocalGet, 3, 1160 wasm.OpcodeLocalGet, 4, 1161 wasm.OpcodeF32Mul, 1162 1163 wasm.OpcodeLocalGet, 3, 1164 wasm.OpcodeLocalGet, 4, 1165 wasm.OpcodeF32Div, 1166 1167 wasm.OpcodeLocalGet, 5, 1168 wasm.OpcodeF32Nearest, 1169 1170 wasm.OpcodeLocalGet, 5, 1171 wasm.OpcodeF32Floor, 1172 1173 wasm.OpcodeLocalGet, 5, 1174 wasm.OpcodeF32Ceil, 1175 1176 wasm.OpcodeLocalGet, 5, 1177 wasm.OpcodeF32Trunc, 1178 1179 wasm.OpcodeLocalGet, 3, 1180 wasm.OpcodeLocalGet, 4, 1181 wasm.OpcodeF32Neg, 1182 wasm.OpcodeF32Copysign, 1183 1184 wasm.OpcodeEnd, 1185 }, []wasm.ValueType{}), 1186 } 1187 FloatLe = TestCase{ 1188 Name: "float_le", 1189 Module: SingleFunctionModule(wasm.FunctionType{ 1190 Params: []wasm.ValueType{f64}, 1191 Results: []wasm.ValueType{i64, i64}, 1192 }, []byte{ 1193 wasm.OpcodeLocalGet, 0, 1194 wasm.OpcodeF64Const, 0, 0, 0, 0, 0, 0, 240, 63, // 1.0 1195 wasm.OpcodeF64Le, 1196 wasm.OpcodeIf, blockSignature_vv, 1197 wasm.OpcodeI64Const, 1, 1198 wasm.OpcodeLocalGet, 0, 1199 wasm.OpcodeF64Const, 0, 0, 0, 0, 0, 0, 240, 63, // 1.0 1200 wasm.OpcodeF64Le, 1201 wasm.OpcodeI64ExtendI32U, 1202 wasm.OpcodeReturn, 1203 wasm.OpcodeElse, 1204 wasm.OpcodeI64Const, 0, 1205 wasm.OpcodeLocalGet, 0, 1206 wasm.OpcodeF64Const, 0, 0, 0, 0, 0, 0, 240, 63, // 1.0 1207 wasm.OpcodeF64Le, 1208 wasm.OpcodeI64ExtendI32U, 1209 wasm.OpcodeReturn, 1210 wasm.OpcodeEnd, 1211 wasm.OpcodeUnreachable, 1212 wasm.OpcodeEnd, 1213 }, []wasm.ValueType{}), 1214 } 1215 MinMaxFloat = TestCase{ 1216 Name: "min_max_float", 1217 Module: SingleFunctionModule(wasm.FunctionType{ 1218 Params: []wasm.ValueType{f64, f64, f32, f32}, 1219 Results: []wasm.ValueType{ 1220 f64, f64, 1221 f32, f32, 1222 }, 1223 }, []byte{ 1224 wasm.OpcodeLocalGet, 0, 1225 wasm.OpcodeLocalGet, 1, 1226 wasm.OpcodeF64Min, 1227 1228 wasm.OpcodeLocalGet, 0, 1229 wasm.OpcodeLocalGet, 1, 1230 wasm.OpcodeF64Max, 1231 1232 // 32-bit floats. 1233 wasm.OpcodeLocalGet, 2, 1234 wasm.OpcodeLocalGet, 3, 1235 wasm.OpcodeF32Min, 1236 1237 wasm.OpcodeLocalGet, 2, 1238 wasm.OpcodeLocalGet, 3, 1239 wasm.OpcodeF32Max, 1240 1241 wasm.OpcodeEnd, 1242 }, []wasm.ValueType{}), 1243 } 1244 FloatConversions = TestCase{ 1245 Name: "float_conversions", 1246 Module: SingleFunctionModule(wasm.FunctionType{ 1247 Params: []wasm.ValueType{f64, f32}, 1248 Results: []wasm.ValueType{i64, i64, i32, i32, i64, i64, i32, i32, f32, f64}, 1249 }, []byte{ 1250 wasm.OpcodeLocalGet, 0, 1251 wasm.OpcodeI64TruncF64S, 1252 1253 wasm.OpcodeLocalGet, 1, 1254 wasm.OpcodeI64TruncF32S, 1255 1256 wasm.OpcodeLocalGet, 0, 1257 wasm.OpcodeI32TruncF64S, 1258 1259 wasm.OpcodeLocalGet, 1, 1260 wasm.OpcodeI32TruncF32S, 1261 1262 wasm.OpcodeLocalGet, 0, 1263 wasm.OpcodeI64TruncF64U, 1264 1265 wasm.OpcodeLocalGet, 1, 1266 wasm.OpcodeI64TruncF32U, 1267 1268 wasm.OpcodeLocalGet, 0, 1269 wasm.OpcodeI32TruncF64U, 1270 1271 wasm.OpcodeLocalGet, 1, 1272 wasm.OpcodeI32TruncF32U, 1273 1274 wasm.OpcodeLocalGet, 0, 1275 wasm.OpcodeF32DemoteF64, 1276 1277 wasm.OpcodeLocalGet, 1, 1278 wasm.OpcodeF64PromoteF32, 1279 1280 wasm.OpcodeEnd, 1281 }, []wasm.ValueType{}), 1282 } 1283 NonTrappingFloatConversions = TestCase{ 1284 Name: "float_conversions", 1285 Module: SingleFunctionModule(wasm.FunctionType{ 1286 Params: []wasm.ValueType{f64, f32}, 1287 Results: []wasm.ValueType{i64, i64, i32, i32, i64, i64, i32, i32}, 1288 }, []byte{ 1289 wasm.OpcodeLocalGet, 0, 1290 wasm.OpcodeMiscPrefix, wasm.OpcodeMiscI64TruncSatF64S, 1291 1292 wasm.OpcodeLocalGet, 1, 1293 wasm.OpcodeMiscPrefix, wasm.OpcodeMiscI64TruncSatF32S, 1294 1295 wasm.OpcodeLocalGet, 0, 1296 wasm.OpcodeMiscPrefix, wasm.OpcodeMiscI32TruncSatF64S, 1297 1298 wasm.OpcodeLocalGet, 1, 1299 wasm.OpcodeMiscPrefix, wasm.OpcodeMiscI32TruncSatF32S, 1300 1301 wasm.OpcodeLocalGet, 0, 1302 wasm.OpcodeMiscPrefix, wasm.OpcodeMiscI64TruncSatF64U, 1303 1304 wasm.OpcodeLocalGet, 1, 1305 wasm.OpcodeMiscPrefix, wasm.OpcodeMiscI64TruncSatF32U, 1306 1307 wasm.OpcodeLocalGet, 0, 1308 wasm.OpcodeMiscPrefix, wasm.OpcodeMiscI32TruncSatF64U, 1309 1310 wasm.OpcodeLocalGet, 1, 1311 wasm.OpcodeMiscPrefix, wasm.OpcodeMiscI32TruncSatF32U, 1312 1313 wasm.OpcodeEnd, 1314 }, []wasm.ValueType{}), 1315 } 1316 FibonacciRecursive = TestCase{ 1317 Name: "recursive_fibonacci", 1318 Module: SingleFunctionModule(i32_i32, []byte{ 1319 wasm.OpcodeLocalGet, 0, 1320 wasm.OpcodeI32Const, 2, 1321 wasm.OpcodeI32LtS, 1322 wasm.OpcodeIf, blockSignature_vv, 1323 wasm.OpcodeLocalGet, 0, 1324 wasm.OpcodeReturn, 1325 wasm.OpcodeEnd, 1326 wasm.OpcodeLocalGet, 0, 1327 wasm.OpcodeI32Const, 1, 1328 wasm.OpcodeI32Sub, 1329 wasm.OpcodeCall, 0, 1330 wasm.OpcodeLocalGet, 0, 1331 wasm.OpcodeI32Const, 2, 1332 wasm.OpcodeI32Sub, 1333 wasm.OpcodeCall, 0, 1334 wasm.OpcodeI32Add, 1335 wasm.OpcodeEnd, 1336 }, nil), 1337 } 1338 ImportedFunctionCall = TestCase{ 1339 Name: "imported_function_call", 1340 Imported: &wasm.Module{ 1341 ExportSection: []wasm.Export{{Name: "i32_i32", Type: wasm.ExternTypeFunc}}, 1342 TypeSection: []wasm.FunctionType{i32i32_i32}, 1343 FunctionSection: []wasm.Index{0}, 1344 CodeSection: []wasm.Code{{Body: []byte{ 1345 wasm.OpcodeLocalGet, 0, 1346 wasm.OpcodeLocalGet, 1, 1347 wasm.OpcodeI32Mul, 1348 wasm.OpcodeEnd, 1349 }}}, 1350 NameSection: &wasm.NameSection{ModuleName: "env"}, 1351 }, 1352 Module: &wasm.Module{ 1353 ImportFunctionCount: 1, 1354 TypeSection: []wasm.FunctionType{i32_i32, i32i32_i32}, 1355 ImportSection: []wasm.Import{{Type: wasm.ExternTypeFunc, Module: "env", Name: "i32_i32", DescFunc: 1}}, 1356 FunctionSection: []wasm.Index{0}, 1357 ExportSection: []wasm.Export{ 1358 {Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 1}, 1359 {Name: "imported_exported", Type: wasm.ExternTypeFunc, Index: 0 /* imported */}, 1360 }, 1361 CodeSection: []wasm.Code{{Body: []byte{ 1362 wasm.OpcodeLocalGet, 0, 1363 wasm.OpcodeLocalGet, 0, 1364 wasm.OpcodeCall, 0, 1365 wasm.OpcodeEnd, 1366 }}}, 1367 }, 1368 } 1369 1370 MemoryStoreBasic = TestCase{ 1371 Name: "memory_load_basic", 1372 Module: &wasm.Module{ 1373 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{i32, i32}, Results: []wasm.ValueType{i32}}}, 1374 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1375 MemorySection: &wasm.Memory{Min: 1}, 1376 FunctionSection: []wasm.Index{0}, 1377 CodeSection: []wasm.Code{{Body: []byte{ 1378 wasm.OpcodeLocalGet, 0, // offset 1379 wasm.OpcodeLocalGet, 1, // value 1380 wasm.OpcodeI32Store, 0x2, 0x0, // alignment=2 (natural alignment) staticOffset=0 1381 // Read back. 1382 wasm.OpcodeLocalGet, 0, // offset 1383 wasm.OpcodeI32Load, 0x2, 0x0, // alignment=2 (natural alignment) staticOffset=0 1384 wasm.OpcodeEnd, 1385 }}}, 1386 }, 1387 } 1388 1389 MemoryStores = TestCase{ 1390 Name: "memory_load_basic", 1391 Module: &wasm.Module{ 1392 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{i32, i64, f32, f64}}}, 1393 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1394 MemorySection: &wasm.Memory{Min: 1}, 1395 FunctionSection: []wasm.Index{0}, 1396 CodeSection: []wasm.Code{{Body: []byte{ 1397 wasm.OpcodeI32Const, 0, // offset 1398 wasm.OpcodeLocalGet, 0, // value 1399 wasm.OpcodeI32Store, 0x2, 0x0, 1400 1401 wasm.OpcodeI32Const, 8, // offset 1402 wasm.OpcodeLocalGet, 1, // value 1403 wasm.OpcodeI64Store, 0x3, 0x0, 1404 1405 wasm.OpcodeI32Const, 16, // offset 1406 wasm.OpcodeLocalGet, 2, // value 1407 wasm.OpcodeF32Store, 0x2, 0x0, 1408 1409 wasm.OpcodeI32Const, 24, // offset 1410 wasm.OpcodeLocalGet, 3, // value 1411 wasm.OpcodeF64Store, 0x3, 0x0, 1412 1413 wasm.OpcodeI32Const, 32, 1414 wasm.OpcodeLocalGet, 0, // value 1415 wasm.OpcodeI32Store8, 0x0, 0, 1416 1417 wasm.OpcodeI32Const, 40, 1418 wasm.OpcodeLocalGet, 0, // value 1419 wasm.OpcodeI32Store16, 0x1, 0, 1420 1421 wasm.OpcodeI32Const, 48, 1422 wasm.OpcodeLocalGet, 1, // value 1423 wasm.OpcodeI64Store8, 0x0, 0, 1424 1425 wasm.OpcodeI32Const, 56, 1426 wasm.OpcodeLocalGet, 1, // value 1427 wasm.OpcodeI64Store16, 0x1, 0, 1428 1429 wasm.OpcodeI32Const, 0xc0, 0, // 64 in leb128. 1430 wasm.OpcodeLocalGet, 1, // value 1431 wasm.OpcodeI64Store32, 0x2, 0, 1432 1433 wasm.OpcodeEnd, 1434 }}}, 1435 }, 1436 } 1437 1438 MemoryLoadBasic = TestCase{ 1439 Name: "memory_load_basic", 1440 Module: &wasm.Module{ 1441 TypeSection: []wasm.FunctionType{{ 1442 Params: []wasm.ValueType{i32}, 1443 Results: []wasm.ValueType{i32}, 1444 }}, 1445 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1446 MemorySection: &wasm.Memory{Min: 1}, 1447 FunctionSection: []wasm.Index{0}, 1448 CodeSection: []wasm.Code{{Body: []byte{ 1449 wasm.OpcodeLocalGet, 0, 1450 wasm.OpcodeI32Load, 0x2, 0x0, // alignment=2 (natural alignment) staticOffset=0 1451 wasm.OpcodeEnd, 1452 }}}, 1453 DataSection: []wasm.DataSegment{{OffsetExpression: constExprI32(0), Init: maskedBuf(int(wasm.MemoryPageSize))}}, 1454 }, 1455 } 1456 1457 MemorySizeGrow = TestCase{ 1458 Name: "memory_size_grow", 1459 Module: &wasm.Module{ 1460 TypeSection: []wasm.FunctionType{{Results: []wasm.ValueType{i32, i32, i32}}}, 1461 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1462 MemorySection: &wasm.Memory{Min: 1, Max: 2, IsMaxEncoded: true}, 1463 FunctionSection: []wasm.Index{0}, 1464 CodeSection: []wasm.Code{{Body: []byte{ 1465 wasm.OpcodeI32Const, 1, 1466 wasm.OpcodeMemoryGrow, 0, // return 1. 1467 wasm.OpcodeMemorySize, 0, // return 2. 1468 wasm.OpcodeI32Const, 1, 1469 wasm.OpcodeMemoryGrow, 0, // return -1 since already maximum size. 1470 wasm.OpcodeEnd, 1471 }}}, 1472 }, 1473 } 1474 1475 MemoryLoadBasic2 = TestCase{ 1476 Name: "memory_load_basic2", 1477 Module: &wasm.Module{ 1478 TypeSection: []wasm.FunctionType{i32_i32, {}}, 1479 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1480 MemorySection: &wasm.Memory{Min: 1}, 1481 FunctionSection: []wasm.Index{0, 1}, 1482 CodeSection: []wasm.Code{ 1483 {Body: []byte{ 1484 wasm.OpcodeLocalGet, 0, 1485 wasm.OpcodeI32Const, 0, 1486 wasm.OpcodeI32Eq, 1487 wasm.OpcodeIf, blockSignature_vv, 1488 wasm.OpcodeCall, 0x1, // After this the memory buf/size pointer reloads. 1489 wasm.OpcodeElse, // But in Else block, we do nothing, so not reloaded. 1490 wasm.OpcodeEnd, 1491 1492 // Therefore, this block should reload the memory buf/size pointer here. 1493 wasm.OpcodeLocalGet, 0, 1494 wasm.OpcodeI32Load, 0x2, 0x0, // alignment=2 (natural alignment) staticOffset=0 1495 1496 wasm.OpcodeEnd, 1497 }}, 1498 {Body: []byte{wasm.OpcodeEnd}}, 1499 }, 1500 DataSection: []wasm.DataSegment{{OffsetExpression: constExprI32(0), Init: maskedBuf(int(wasm.MemoryPageSize))}}, 1501 }, 1502 } 1503 1504 ImportedMemoryGrow = TestCase{ 1505 Name: "imported_memory_grow", 1506 Imported: &wasm.Module{ 1507 ExportSection: []wasm.Export{ 1508 {Name: "mem", Type: wasm.ExternTypeMemory, Index: 0}, 1509 {Name: "size", Type: wasm.ExternTypeFunc, Index: 0}, 1510 }, 1511 MemorySection: &wasm.Memory{Min: 1}, 1512 TypeSection: []wasm.FunctionType{v_i32}, 1513 FunctionSection: []wasm.Index{0}, 1514 CodeSection: []wasm.Code{{Body: []byte{wasm.OpcodeMemorySize, 0, wasm.OpcodeEnd}}}, 1515 DataSection: []wasm.DataSegment{{OffsetExpression: constExprI32(0), Init: maskedBuf(int(wasm.MemoryPageSize))}}, 1516 NameSection: &wasm.NameSection{ModuleName: "env"}, 1517 }, 1518 Module: &wasm.Module{ 1519 ImportMemoryCount: 1, 1520 ImportFunctionCount: 1, 1521 ImportSection: []wasm.Import{ 1522 {Module: "env", Name: "mem", Type: wasm.ExternTypeMemory, DescMem: &wasm.Memory{Min: 1}}, 1523 {Module: "env", Name: "size", Type: wasm.ExternTypeFunc, DescFunc: 0}, 1524 }, 1525 TypeSection: []wasm.FunctionType{v_i32, {Results: []wasm.ValueType{i32, i32, i32, i32}}}, 1526 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 1}}, 1527 FunctionSection: []wasm.Index{1}, 1528 CodeSection: []wasm.Code{ 1529 {Body: []byte{ 1530 wasm.OpcodeCall, 0, // Call imported size function. --> 1 1531 wasm.OpcodeMemorySize, 0, // --> 1. 1532 wasm.OpcodeI32Const, 10, 1533 wasm.OpcodeMemoryGrow, 0, 1534 wasm.OpcodeDrop, 1535 wasm.OpcodeCall, 0, // Call imported size function. --> 11. 1536 wasm.OpcodeMemorySize, 0, // --> 11. 1537 wasm.OpcodeEnd, 1538 }}, 1539 }, 1540 }, 1541 } 1542 1543 GlobalsGet = TestCase{ 1544 Name: "globals_get", 1545 Module: &wasm.Module{ 1546 TypeSection: []wasm.FunctionType{{Results: []wasm.ValueType{i32, i64, f32, f64, v128}}}, 1547 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1548 FunctionSection: []wasm.Index{0}, 1549 GlobalSection: []wasm.Global{ 1550 { 1551 Type: wasm.GlobalType{ValType: wasm.ValueTypeI32, Mutable: false}, 1552 Init: constExprI32(math.MinInt32), 1553 }, 1554 { 1555 Type: wasm.GlobalType{ValType: wasm.ValueTypeI64, Mutable: false}, 1556 Init: constExprI64(math.MinInt64), 1557 }, 1558 { 1559 Type: wasm.GlobalType{ValType: wasm.ValueTypeF32, Mutable: false}, 1560 Init: constExprF32(math.MaxFloat32), 1561 }, 1562 { 1563 Type: wasm.GlobalType{ValType: wasm.ValueTypeF64, Mutable: false}, 1564 Init: constExprF64(math.MaxFloat64), 1565 }, 1566 { 1567 Type: wasm.GlobalType{ValType: wasm.ValueTypeV128, Mutable: false}, 1568 Init: constExprV128(1234, 5678), 1569 }, 1570 }, 1571 CodeSection: []wasm.Code{ 1572 {Body: []byte{ 1573 wasm.OpcodeGlobalGet, 0, 1574 wasm.OpcodeGlobalGet, 1, 1575 wasm.OpcodeGlobalGet, 2, 1576 wasm.OpcodeGlobalGet, 3, 1577 wasm.OpcodeGlobalGet, 4, 1578 wasm.OpcodeEnd, 1579 }}, 1580 }, 1581 }, 1582 } 1583 1584 GlobalsSet = TestCase{ 1585 Name: "globals_set", 1586 Module: &wasm.Module{ 1587 TypeSection: []wasm.FunctionType{{Results: []wasm.ValueType{i32, i64, f32, f64, v128}}}, 1588 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1589 FunctionSection: []wasm.Index{0}, 1590 GlobalSection: []wasm.Global{ 1591 { 1592 Type: wasm.GlobalType{ValType: wasm.ValueTypeI32, Mutable: true}, 1593 Init: constExprI32(0), 1594 }, 1595 { 1596 Type: wasm.GlobalType{ValType: wasm.ValueTypeI64, Mutable: true}, 1597 Init: constExprI64(0), 1598 }, 1599 { 1600 Type: wasm.GlobalType{ValType: wasm.ValueTypeF32, Mutable: true}, 1601 Init: constExprF32(0), 1602 }, 1603 { 1604 Type: wasm.GlobalType{ValType: wasm.ValueTypeF64, Mutable: true}, 1605 Init: constExprF64(0), 1606 }, 1607 { 1608 Type: wasm.GlobalType{ValType: wasm.ValueTypeV128, Mutable: true}, 1609 Init: constExprV128(0, 0), 1610 }, 1611 }, 1612 CodeSection: []wasm.Code{ 1613 {Body: []byte{ 1614 wasm.OpcodeI32Const, 1, 1615 wasm.OpcodeGlobalSet, 0, 1616 wasm.OpcodeGlobalGet, 0, 1617 wasm.OpcodeI64Const, 2, 1618 wasm.OpcodeGlobalSet, 1, 1619 wasm.OpcodeGlobalGet, 1, 1620 wasm.OpcodeF32Const, 0, 0, 64, 64, // 3.0 1621 wasm.OpcodeGlobalSet, 2, 1622 wasm.OpcodeGlobalGet, 2, 1623 wasm.OpcodeF64Const, 0, 0, 0, 0, 0, 0, 16, 64, // 4.0 1624 wasm.OpcodeGlobalSet, 3, 1625 wasm.OpcodeGlobalGet, 3, 1626 wasm.OpcodeVecPrefix, wasm.OpcodeVecV128Const, 1627 10, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 1628 wasm.OpcodeGlobalSet, 4, 1629 wasm.OpcodeGlobalGet, 4, 1630 wasm.OpcodeEnd, 1631 }}, 1632 }, 1633 }, 1634 } 1635 1636 GlobalsMutable = TestCase{ 1637 Module: &wasm.Module{ 1638 TypeSection: []wasm.FunctionType{ 1639 {Results: []wasm.ValueType{i32, i64, f32, f64, i32, i64, f32, f64}}, 1640 {}, 1641 }, 1642 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1643 FunctionSection: []wasm.Index{0, 1}, 1644 GlobalSection: []wasm.Global{ 1645 { 1646 Type: wasm.GlobalType{ValType: wasm.ValueTypeI32, Mutable: true}, 1647 Init: constExprI32(100), 1648 }, 1649 { 1650 Type: wasm.GlobalType{ValType: wasm.ValueTypeI64, Mutable: true}, 1651 Init: constExprI64(200), 1652 }, 1653 { 1654 Type: wasm.GlobalType{ValType: wasm.ValueTypeF32, Mutable: true}, 1655 Init: constExprF32(300.0), 1656 }, 1657 { 1658 Type: wasm.GlobalType{ValType: wasm.ValueTypeF64, Mutable: true}, 1659 Init: constExprF64(400.0), 1660 }, 1661 }, 1662 CodeSection: []wasm.Code{ 1663 {Body: []byte{ 1664 wasm.OpcodeGlobalGet, 0, 1665 wasm.OpcodeGlobalGet, 1, 1666 wasm.OpcodeGlobalGet, 2, 1667 wasm.OpcodeGlobalGet, 3, 1668 wasm.OpcodeCall, 1, 1669 wasm.OpcodeGlobalGet, 0, 1670 wasm.OpcodeGlobalGet, 1, 1671 wasm.OpcodeGlobalGet, 2, 1672 wasm.OpcodeGlobalGet, 3, 1673 wasm.OpcodeEnd, 1674 }}, 1675 {Body: []byte{ 1676 wasm.OpcodeI32Const, 1, 1677 wasm.OpcodeGlobalSet, 0, 1678 wasm.OpcodeI64Const, 2, 1679 wasm.OpcodeGlobalSet, 1, 1680 wasm.OpcodeF32Const, 0, 0, 64, 64, // 3.0 1681 wasm.OpcodeGlobalSet, 2, 1682 wasm.OpcodeF64Const, 0, 0, 0, 0, 0, 0, 16, 64, // 4.0 1683 wasm.OpcodeGlobalSet, 3, 1684 wasm.OpcodeReturn, 1685 wasm.OpcodeEnd, 1686 }}, 1687 }, 1688 }, 1689 } 1690 1691 MemoryLoads = TestCase{ 1692 Name: "memory_loads", 1693 Module: &wasm.Module{ 1694 TypeSection: []wasm.FunctionType{{ 1695 Params: []wasm.ValueType{i32}, 1696 Results: []wasm.ValueType{ 1697 i32, i64, f32, f64, i32, i64, f32, f64, 1698 i32, i32, i32, i32, i32, i32, i32, i32, 1699 i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, 1700 }, 1701 }}, 1702 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1703 MemorySection: &wasm.Memory{Min: 1}, 1704 FunctionSection: []wasm.Index{0}, 1705 CodeSection: []wasm.Code{{Body: []byte{ 1706 // Basic loads (without extensions). 1707 wasm.OpcodeLocalGet, 0, // 0 1708 wasm.OpcodeI32Load, 0x2, 0x0, // alignment=2 (natural alignment) staticOffset=0 1709 wasm.OpcodeLocalGet, 0, // 1 1710 wasm.OpcodeI64Load, 0x3, 0x0, // alignment=3 (natural alignment) staticOffset=0 1711 wasm.OpcodeLocalGet, 0, // 2 1712 wasm.OpcodeF32Load, 0x2, 0x0, // alignment=2 (natural alignment) staticOffset=0 1713 wasm.OpcodeLocalGet, 0, // 3 1714 wasm.OpcodeF64Load, 0x3, 0x0, // alignment=3 (natural alignment) staticOffset=0 1715 wasm.OpcodeLocalGet, 0, // 4 1716 wasm.OpcodeI32Load, 0x2, 0xf, // alignment=2 (natural alignment) staticOffset=16 1717 wasm.OpcodeLocalGet, 0, // 5 1718 wasm.OpcodeI64Load, 0x3, 0xf, // alignment=3 (natural alignment) staticOffset=16 1719 wasm.OpcodeLocalGet, 0, // 6 1720 wasm.OpcodeF32Load, 0x2, 0xf, // alignment=2 (natural alignment) staticOffset=16 1721 wasm.OpcodeLocalGet, 0, // 7 1722 wasm.OpcodeF64Load, 0x3, 0xf, // alignment=3 (natural alignment) staticOffset=16 1723 1724 // Extension integer loads. 1725 wasm.OpcodeLocalGet, 0, // 8 1726 wasm.OpcodeI32Load8S, 0x0, 0x0, // alignment=0 (natural alignment) staticOffset=0 1727 wasm.OpcodeLocalGet, 0, // 9 1728 wasm.OpcodeI32Load8S, 0x0, 0xf, // alignment=0 (natural alignment) staticOffset=16 1729 1730 wasm.OpcodeLocalGet, 0, // 10 1731 wasm.OpcodeI32Load8U, 0x0, 0x0, // alignment=0 (natural alignment) staticOffset=0 1732 wasm.OpcodeLocalGet, 0, // 11 1733 wasm.OpcodeI32Load8U, 0x0, 0xf, // alignment=0 (natural alignment) staticOffset=16 1734 wasm.OpcodeLocalGet, 0, // 12 1735 wasm.OpcodeI32Load16S, 0x1, 0x0, // alignment=1 (natural alignment) staticOffset=0 1736 wasm.OpcodeLocalGet, 0, // 13 1737 wasm.OpcodeI32Load16S, 0x1, 0xf, // alignment=1 (natural alignment) staticOffset=16 1738 wasm.OpcodeLocalGet, 0, // 14 1739 wasm.OpcodeI32Load16U, 0x1, 0x0, // alignment=1 (natural alignment) staticOffset=0 1740 wasm.OpcodeLocalGet, 0, // 15 1741 wasm.OpcodeI32Load16U, 0x1, 0xf, // alignment=1 (natural alignment) staticOffset=16 1742 wasm.OpcodeLocalGet, 0, // 16 1743 wasm.OpcodeI64Load8S, 0x0, 0x0, // alignment=0 (natural alignment) staticOffset=0 1744 wasm.OpcodeLocalGet, 0, // 17 1745 wasm.OpcodeI64Load8S, 0x0, 0xf, // alignment=0 (natural alignment) staticOffset=16 1746 wasm.OpcodeLocalGet, 0, // 18 1747 wasm.OpcodeI64Load8U, 0x0, 0x0, // alignment=0 (natural alignment) staticOffset=0 1748 wasm.OpcodeLocalGet, 0, // 19 1749 1750 wasm.OpcodeI64Load8U, 0x0, 0xf, // alignment=0 (natural alignment) staticOffset=16 1751 wasm.OpcodeLocalGet, 0, // 20 1752 wasm.OpcodeI64Load16S, 0x1, 0x0, // alignment=1 (natural alignment) staticOffset=0 1753 wasm.OpcodeLocalGet, 0, // 21 1754 wasm.OpcodeI64Load16S, 0x1, 0xf, // alignment=1 (natural alignment) staticOffset=16 1755 wasm.OpcodeLocalGet, 0, // 22 1756 wasm.OpcodeI64Load16U, 0x1, 0x0, // alignment=1 (natural alignment) staticOffset=0 1757 wasm.OpcodeLocalGet, 0, // 23 1758 wasm.OpcodeI64Load16U, 0x1, 0xf, // alignment=1 (natural alignment) staticOffset=16 1759 wasm.OpcodeLocalGet, 0, // 24 1760 wasm.OpcodeI64Load32S, 0x2, 0x0, // alignment=2 (natural alignment) staticOffset=0 1761 wasm.OpcodeLocalGet, 0, // 25 1762 wasm.OpcodeI64Load32S, 0x2, 0xf, // alignment=2 (natural alignment) staticOffset=16 1763 wasm.OpcodeLocalGet, 0, // 26 1764 wasm.OpcodeI64Load32U, 0x2, 0x0, // alignment=2 (natural alignment) staticOffset=0 1765 wasm.OpcodeLocalGet, 0, // 27 1766 wasm.OpcodeI64Load32U, 0x2, 0xf, // alignment=2 (natural alignment) staticOffset=16 1767 1768 wasm.OpcodeEnd, 1769 }}}, 1770 DataSection: []wasm.DataSegment{{OffsetExpression: constExprI32(0), Init: maskedBuf(int(wasm.MemoryPageSize))}}, 1771 }, 1772 } 1773 1774 CallIndirect = TestCase{ 1775 Module: &wasm.Module{ 1776 TypeSection: []wasm.FunctionType{i32_i32, {}, v_i32, v_i32i32}, 1777 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1778 FunctionSection: []wasm.Index{0, 1, 2, 3}, 1779 TableSection: []wasm.Table{{Type: wasm.RefTypeFuncref, Min: 1000}}, 1780 ElementSection: []wasm.ElementSegment{ 1781 { 1782 OffsetExpr: constExprI32(0), TableIndex: 0, Type: wasm.RefTypeFuncref, Mode: wasm.ElementModeActive, 1783 // Set the function 1, 2, 3 at the beginning of the table. 1784 Init: []wasm.Index{1, 2, 3}, 1785 }, 1786 }, 1787 CodeSection: []wasm.Code{ 1788 {Body: []byte{ 1789 wasm.OpcodeLocalGet, 0, 1790 wasm.OpcodeCallIndirect, 2, 0, // Expecting type 2 (v_i32), in tables[0] 1791 wasm.OpcodeEnd, 1792 }}, 1793 {Body: []byte{wasm.OpcodeEnd}}, 1794 {Body: []byte{wasm.OpcodeI32Const, 10, wasm.OpcodeEnd}}, 1795 {Body: []byte{wasm.OpcodeI32Const, 1, wasm.OpcodeI32Const, 1, wasm.OpcodeEnd}}, 1796 }, 1797 }, 1798 } 1799 1800 BrTable = TestCase{ 1801 Module: &wasm.Module{ 1802 TypeSection: []wasm.FunctionType{i32_i32, {}}, 1803 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1804 FunctionSection: []wasm.Index{0}, 1805 CodeSection: []wasm.Code{ 1806 {Body: []byte{ 1807 wasm.OpcodeBlock, 1, // Signature v_v, 1808 wasm.OpcodeBlock, 1, // Signature v_v, 1809 wasm.OpcodeBlock, 1, // Signature v_v, 1810 wasm.OpcodeBlock, 1, // Signature v_v, 1811 wasm.OpcodeBlock, 1, // Signature v_v, 1812 wasm.OpcodeBlock, 1, // Signature v_v, 1813 wasm.OpcodeLocalGet, 0, 1814 wasm.OpcodeBrTable, 1815 6, // size of label vector 1816 0, 1, 2, 3, 4, 5, // labels. 1817 0, // default label 1818 wasm.OpcodeEnd, wasm.OpcodeI32Const, 11, wasm.OpcodeReturn, 1819 wasm.OpcodeEnd, wasm.OpcodeI32Const, 12, wasm.OpcodeReturn, 1820 wasm.OpcodeEnd, wasm.OpcodeI32Const, 13, wasm.OpcodeReturn, 1821 wasm.OpcodeEnd, wasm.OpcodeI32Const, 14, wasm.OpcodeReturn, 1822 wasm.OpcodeEnd, wasm.OpcodeI32Const, 15, wasm.OpcodeReturn, 1823 wasm.OpcodeEnd, wasm.OpcodeI32Const, 16, wasm.OpcodeReturn, 1824 wasm.OpcodeEnd, 1825 }}, 1826 }, 1827 }, 1828 } 1829 1830 BrTableWithArg = TestCase{ 1831 Name: "br_table_with_arg", 1832 Module: &wasm.Module{ 1833 TypeSection: []wasm.FunctionType{i32i32_i32, v_i32}, 1834 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1835 FunctionSection: []wasm.Index{0}, 1836 CodeSection: []wasm.Code{ 1837 {Body: []byte{ 1838 wasm.OpcodeBlock, 1, // Signature v_i32, 1839 wasm.OpcodeBlock, 1, // Signature v_i32, 1840 wasm.OpcodeBlock, 1, // Signature v_i32, 1841 wasm.OpcodeBlock, 1, // Signature v_i32, 1842 wasm.OpcodeBlock, 1, // Signature v_i32, 1843 wasm.OpcodeBlock, 1, // Signature v_i32, 1844 wasm.OpcodeLocalGet, 1, // Argument to each destination. 1845 wasm.OpcodeLocalGet, 0, 1846 wasm.OpcodeBrTable, 1847 6, // size of label vector 1848 0, 1, 2, 3, 4, 5, // labels. 1849 0, // default label 1850 wasm.OpcodeEnd, wasm.OpcodeI32Const, 11, wasm.OpcodeI32Add, wasm.OpcodeReturn, 1851 wasm.OpcodeEnd, wasm.OpcodeI32Const, 12, wasm.OpcodeI32Add, wasm.OpcodeReturn, 1852 wasm.OpcodeEnd, wasm.OpcodeI32Const, 13, wasm.OpcodeI32Add, wasm.OpcodeReturn, 1853 wasm.OpcodeEnd, wasm.OpcodeI32Const, 14, wasm.OpcodeI32Add, wasm.OpcodeReturn, 1854 wasm.OpcodeEnd, wasm.OpcodeI32Const, 15, wasm.OpcodeI32Add, wasm.OpcodeReturn, 1855 wasm.OpcodeEnd, wasm.OpcodeI32Const, 16, wasm.OpcodeI32Add, wasm.OpcodeReturn, 1856 wasm.OpcodeUnreachable, 1857 wasm.OpcodeEnd, 1858 }}, 1859 }, 1860 }, 1861 } 1862 1863 IfThenEndNestingUnreachableIfThenElseEnd = TestCase{ 1864 // This has been detected by fuzzing. This should belong to internal/integration_test/fuzzcases eventually, 1865 // but for now, wazevo should have its own cases under engine/wazevo. 1866 Name: "if_then_end_nesting_unreachable_if_then_else_end", 1867 // (module 1868 // (type (;0;) (func (param f64 f64 f64))) 1869 // (func (;0;) (type 0) (param f64 f64 f64) 1870 // block (result i64) ;; label = @1 1871 // memory.size 1872 // if ;; label = @2 1873 // memory.size 1874 // br 0 (;@2;) 1875 // if ;; label = @3 1876 // else 1877 // end 1878 // drop 1879 // end 1880 // i64.const 0 1881 // end 1882 // drop 1883 // ) 1884 // (memory (;0;) 4554) 1885 //) 1886 Module: &wasm.Module{ 1887 TypeSection: []wasm.FunctionType{ 1888 {Params: []wasm.ValueType{f64, f64, f64}}, 1889 {Results: []wasm.ValueType{i64}}, 1890 }, 1891 1892 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1893 MemorySection: &wasm.Memory{Min: 4554}, 1894 FunctionSection: []wasm.Index{0}, 1895 CodeSection: []wasm.Code{{Body: []byte{ 1896 wasm.OpcodeBlock, 1, // Signature v_i64, 1897 wasm.OpcodeMemorySize, 0, 1898 wasm.OpcodeIf, blockSignature_vv, 1899 wasm.OpcodeMemorySize, 0, 1900 wasm.OpcodeBr, 0x0, // label=0 1901 wasm.OpcodeIf, blockSignature_vv, 1902 wasm.OpcodeElse, 1903 wasm.OpcodeEnd, 1904 wasm.OpcodeDrop, 1905 wasm.OpcodeEnd, 1906 wasm.OpcodeI64Const, 0, 1907 wasm.OpcodeEnd, 1908 wasm.OpcodeDrop, 1909 wasm.OpcodeEnd, 1910 }}}, 1911 }, 1912 } 1913 1914 VecBitSelect = TestCase{ 1915 Name: "vector_bit_select", 1916 Module: &wasm.Module{ 1917 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{v128, v128, v128}, Results: []wasm.ValueType{v128, v128}}}, 1918 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1919 FunctionSection: []wasm.Index{0}, 1920 CodeSection: []wasm.Code{{Body: []byte{ 1921 // In arm64, the "C" of BSL instruction is overwritten by the result, 1922 // so this case can be used to ensure that it is still alive if 'c' is used somewhere else, 1923 // which in this case is as a return value. 1924 wasm.OpcodeLocalGet, 0, 1925 wasm.OpcodeLocalGet, 1, 1926 wasm.OpcodeLocalGet, 2, 1927 wasm.OpcodeVecPrefix, wasm.OpcodeVecV128Bitselect, 1928 wasm.OpcodeLocalGet, 2, // Returns the 'c' as-is. 1929 wasm.OpcodeEnd, 1930 }}}, 1931 }, 1932 } 1933 1934 VecShuffle = TestCase{ 1935 Name: "shuffle", 1936 Module: VecShuffleWithLane(0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31), 1937 } 1938 1939 MemoryWait32 = TestCase{ 1940 Name: "memory_wait32", 1941 Module: &wasm.Module{ 1942 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{i32, i32, i64}, Results: []wasm.ValueType{i32}}}, 1943 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1944 MemorySection: &wasm.Memory{Min: 1, Max: 1, IsMaxEncoded: true, IsShared: true}, 1945 FunctionSection: []wasm.Index{0}, 1946 CodeSection: []wasm.Code{{Body: []byte{ 1947 wasm.OpcodeLocalGet, 0, 1948 wasm.OpcodeLocalGet, 1, 1949 wasm.OpcodeLocalGet, 2, 1950 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicMemoryWait32, 0x1, 8, 1951 wasm.OpcodeEnd, 1952 }}}, 1953 }, 1954 } 1955 1956 MemoryWait64 = TestCase{ 1957 Name: "memory_wait64", 1958 Module: &wasm.Module{ 1959 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{i32, i64, i64}, Results: []wasm.ValueType{i32}}}, 1960 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1961 MemorySection: &wasm.Memory{Min: 1, Max: 1, IsMaxEncoded: true, IsShared: true}, 1962 FunctionSection: []wasm.Index{0}, 1963 CodeSection: []wasm.Code{{Body: []byte{ 1964 wasm.OpcodeLocalGet, 0, 1965 wasm.OpcodeLocalGet, 1, 1966 wasm.OpcodeLocalGet, 2, 1967 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicMemoryWait64, 0x2, 8, 1968 wasm.OpcodeEnd, 1969 }}}, 1970 }, 1971 } 1972 1973 MemoryNotify = TestCase{ 1974 Name: "memory_notify", 1975 Module: &wasm.Module{ 1976 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{i32, i32}, Results: []wasm.ValueType{i32}}}, 1977 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1978 MemorySection: &wasm.Memory{Min: 1, Max: 1, IsMaxEncoded: true, IsShared: true}, 1979 FunctionSection: []wasm.Index{0}, 1980 CodeSection: []wasm.Code{{Body: []byte{ 1981 wasm.OpcodeLocalGet, 0, 1982 wasm.OpcodeLocalGet, 1, 1983 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicMemoryNotify, 0x1, 8, 1984 wasm.OpcodeEnd, 1985 }}}, 1986 }, 1987 } 1988 1989 AtomicRmwAdd = TestCase{ 1990 Name: "atomic_rmw_add", 1991 Module: &wasm.Module{ 1992 TypeSection: []wasm.FunctionType{{ 1993 Params: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 1994 Results: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 1995 }}, 1996 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 1997 MemorySection: &wasm.Memory{Min: 1, Max: 1, IsMaxEncoded: true, IsShared: true}, 1998 FunctionSection: []wasm.Index{0}, 1999 CodeSection: []wasm.Code{{Body: []byte{ 2000 wasm.OpcodeI32Const, 0, 2001 wasm.OpcodeLocalGet, 0, 2002 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw8AddU, 0x0, 0, 2003 wasm.OpcodeI32Const, 8, 2004 wasm.OpcodeLocalGet, 1, 2005 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw16AddU, 0x1, 0, 2006 wasm.OpcodeI32Const, 16, 2007 wasm.OpcodeLocalGet, 2, 2008 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32RmwAdd, 0x2, 0, 2009 wasm.OpcodeI32Const, 24, 2010 wasm.OpcodeLocalGet, 3, 2011 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw8AddU, 0x0, 0, 2012 wasm.OpcodeI32Const, 32, 2013 wasm.OpcodeLocalGet, 4, 2014 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw16AddU, 0x1, 0, 2015 wasm.OpcodeI32Const, 40, 2016 wasm.OpcodeLocalGet, 5, 2017 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw32AddU, 0x2, 0, 2018 wasm.OpcodeI32Const, 48, 2019 wasm.OpcodeLocalGet, 6, 2020 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64RmwAdd, 0x3, 0, 2021 wasm.OpcodeEnd, 2022 }}}, 2023 }, 2024 } 2025 2026 AtomicRmwSub = TestCase{ 2027 Name: "atomic_rmw_sub", 2028 Module: &wasm.Module{ 2029 TypeSection: []wasm.FunctionType{{ 2030 Params: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2031 Results: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2032 }}, 2033 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 2034 MemorySection: &wasm.Memory{Min: 1, Max: 1, IsMaxEncoded: true, IsShared: true}, 2035 FunctionSection: []wasm.Index{0}, 2036 CodeSection: []wasm.Code{{Body: []byte{ 2037 wasm.OpcodeI32Const, 0, 2038 wasm.OpcodeLocalGet, 0, 2039 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw8SubU, 0x0, 0, 2040 wasm.OpcodeI32Const, 8, 2041 wasm.OpcodeLocalGet, 1, 2042 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw16SubU, 0x1, 0, 2043 wasm.OpcodeI32Const, 16, 2044 wasm.OpcodeLocalGet, 2, 2045 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32RmwSub, 0x2, 0, 2046 wasm.OpcodeI32Const, 24, 2047 wasm.OpcodeLocalGet, 3, 2048 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw8SubU, 0x0, 0, 2049 wasm.OpcodeI32Const, 32, 2050 wasm.OpcodeLocalGet, 4, 2051 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw16SubU, 0x1, 0, 2052 wasm.OpcodeI32Const, 40, 2053 wasm.OpcodeLocalGet, 5, 2054 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw32SubU, 0x2, 0, 2055 wasm.OpcodeI32Const, 48, 2056 wasm.OpcodeLocalGet, 6, 2057 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64RmwSub, 0x3, 0, 2058 wasm.OpcodeEnd, 2059 }}}, 2060 }, 2061 } 2062 2063 AtomicRmwAnd = TestCase{ 2064 Name: "atomic_rmw_and", 2065 Module: &wasm.Module{ 2066 TypeSection: []wasm.FunctionType{{ 2067 Params: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2068 Results: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2069 }}, 2070 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 2071 MemorySection: &wasm.Memory{Min: 1, Max: 1, IsMaxEncoded: true, IsShared: true}, 2072 FunctionSection: []wasm.Index{0}, 2073 CodeSection: []wasm.Code{{Body: []byte{ 2074 wasm.OpcodeI32Const, 0, 2075 wasm.OpcodeLocalGet, 0, 2076 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw8AndU, 0x0, 0, 2077 wasm.OpcodeI32Const, 0, 2078 wasm.OpcodeLocalGet, 1, 2079 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw16AndU, 0x1, 8, 2080 wasm.OpcodeI32Const, 0, 2081 wasm.OpcodeLocalGet, 2, 2082 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32RmwAnd, 0x2, 16, 2083 wasm.OpcodeI32Const, 0, 2084 wasm.OpcodeLocalGet, 3, 2085 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw8AndU, 0x0, 24, 2086 wasm.OpcodeI32Const, 0, 2087 wasm.OpcodeLocalGet, 4, 2088 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw16AndU, 0x1, 32, 2089 wasm.OpcodeI32Const, 0, 2090 wasm.OpcodeLocalGet, 5, 2091 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw32AndU, 0x2, 40, 2092 wasm.OpcodeI32Const, 0, 2093 wasm.OpcodeLocalGet, 6, 2094 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64RmwAnd, 0x3, 48, 2095 wasm.OpcodeEnd, 2096 }}}, 2097 }, 2098 } 2099 2100 AtomicRmwOr = TestCase{ 2101 Name: "atomic_rmw_or", 2102 Module: &wasm.Module{ 2103 TypeSection: []wasm.FunctionType{{ 2104 Params: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2105 Results: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2106 }}, 2107 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 2108 MemorySection: &wasm.Memory{Min: 1, Max: 1, IsMaxEncoded: true, IsShared: true}, 2109 FunctionSection: []wasm.Index{0}, 2110 CodeSection: []wasm.Code{{Body: []byte{ 2111 wasm.OpcodeI32Const, 0, 2112 wasm.OpcodeLocalGet, 0, 2113 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw8OrU, 0x0, 0, 2114 wasm.OpcodeI32Const, 0, 2115 wasm.OpcodeLocalGet, 1, 2116 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw16OrU, 0x1, 8, 2117 wasm.OpcodeI32Const, 0, 2118 wasm.OpcodeLocalGet, 2, 2119 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32RmwOr, 0x2, 16, 2120 wasm.OpcodeI32Const, 0, 2121 wasm.OpcodeLocalGet, 3, 2122 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw8OrU, 0x0, 24, 2123 wasm.OpcodeI32Const, 0, 2124 wasm.OpcodeLocalGet, 4, 2125 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw16OrU, 0x1, 32, 2126 wasm.OpcodeI32Const, 0, 2127 wasm.OpcodeLocalGet, 5, 2128 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw32OrU, 0x2, 40, 2129 wasm.OpcodeI32Const, 0, 2130 wasm.OpcodeLocalGet, 6, 2131 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64RmwOr, 0x3, 48, 2132 wasm.OpcodeEnd, 2133 }}}, 2134 }, 2135 } 2136 2137 AtomicRmwXor = TestCase{ 2138 Name: "atomic_rmw_xor", 2139 Module: &wasm.Module{ 2140 TypeSection: []wasm.FunctionType{{ 2141 Params: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2142 Results: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2143 }}, 2144 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 2145 MemorySection: &wasm.Memory{Min: 1, Max: 1, IsMaxEncoded: true, IsShared: true}, 2146 FunctionSection: []wasm.Index{0}, 2147 CodeSection: []wasm.Code{{Body: []byte{ 2148 wasm.OpcodeI32Const, 0, 2149 wasm.OpcodeLocalGet, 0, 2150 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw8XorU, 0x0, 0, 2151 wasm.OpcodeI32Const, 0, 2152 wasm.OpcodeLocalGet, 1, 2153 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw16XorU, 0x1, 8, 2154 wasm.OpcodeI32Const, 0, 2155 wasm.OpcodeLocalGet, 2, 2156 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32RmwXor, 0x2, 16, 2157 wasm.OpcodeI32Const, 0, 2158 wasm.OpcodeLocalGet, 3, 2159 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw8XorU, 0x0, 24, 2160 wasm.OpcodeI32Const, 0, 2161 wasm.OpcodeLocalGet, 4, 2162 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw16XorU, 0x1, 32, 2163 wasm.OpcodeI32Const, 0, 2164 wasm.OpcodeLocalGet, 5, 2165 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw32XorU, 0x2, 40, 2166 wasm.OpcodeI32Const, 0, 2167 wasm.OpcodeLocalGet, 6, 2168 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64RmwXor, 0x3, 48, 2169 wasm.OpcodeEnd, 2170 }}}, 2171 }, 2172 } 2173 2174 AtomicRmwXchg = TestCase{ 2175 Name: "atomic_rmw_xchg", 2176 Module: &wasm.Module{ 2177 TypeSection: []wasm.FunctionType{{ 2178 Params: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2179 Results: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2180 }}, 2181 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 2182 MemorySection: &wasm.Memory{Min: 1, Max: 1, IsMaxEncoded: true, IsShared: true}, 2183 FunctionSection: []wasm.Index{0}, 2184 CodeSection: []wasm.Code{{Body: []byte{ 2185 wasm.OpcodeI32Const, 0, 2186 wasm.OpcodeLocalGet, 0, 2187 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw8XchgU, 0x0, 0, 2188 wasm.OpcodeI32Const, 0, 2189 wasm.OpcodeLocalGet, 1, 2190 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw16XchgU, 0x1, 8, 2191 wasm.OpcodeI32Const, 0, 2192 wasm.OpcodeLocalGet, 2, 2193 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32RmwXchg, 0x2, 16, 2194 wasm.OpcodeI32Const, 0, 2195 wasm.OpcodeLocalGet, 3, 2196 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw8XchgU, 0x0, 24, 2197 wasm.OpcodeI32Const, 0, 2198 wasm.OpcodeLocalGet, 4, 2199 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw16XchgU, 0x1, 32, 2200 wasm.OpcodeI32Const, 0, 2201 wasm.OpcodeLocalGet, 5, 2202 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw32XchgU, 0x2, 40, 2203 wasm.OpcodeI32Const, 0, 2204 wasm.OpcodeLocalGet, 6, 2205 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64RmwXchg, 0x3, 48, 2206 wasm.OpcodeEnd, 2207 }}}, 2208 }, 2209 } 2210 2211 AtomicStoreLoad = TestCase{ 2212 Name: "atomic_store_load", 2213 Module: &wasm.Module{ 2214 TypeSection: []wasm.FunctionType{{ 2215 Params: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2216 Results: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2217 }}, 2218 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 2219 MemorySection: &wasm.Memory{Min: 1, Max: 1, IsMaxEncoded: true, IsShared: true}, 2220 FunctionSection: []wasm.Index{0}, 2221 CodeSection: []wasm.Code{{Body: []byte{ 2222 wasm.OpcodeI32Const, 0, 2223 wasm.OpcodeLocalGet, 0, 2224 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Store8, 0x0, 0, 2225 wasm.OpcodeI32Const, 0, 2226 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Load8U, 0x0, 0, 2227 wasm.OpcodeI32Const, 0, 2228 wasm.OpcodeLocalGet, 1, 2229 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Store16, 0x1, 8, 2230 wasm.OpcodeI32Const, 0, 2231 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Load16U, 0x1, 8, 2232 wasm.OpcodeI32Const, 0, 2233 wasm.OpcodeLocalGet, 2, 2234 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Store, 0x2, 16, 2235 wasm.OpcodeI32Const, 0, 2236 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Load, 0x2, 16, 2237 wasm.OpcodeI32Const, 0, 2238 wasm.OpcodeLocalGet, 3, 2239 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Store8, 0x0, 24, 2240 wasm.OpcodeI32Const, 0, 2241 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Load8U, 0x0, 24, 2242 wasm.OpcodeI32Const, 0, 2243 wasm.OpcodeLocalGet, 4, 2244 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Store16, 0x1, 32, 2245 wasm.OpcodeI32Const, 0, 2246 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Load16U, 0x1, 32, 2247 wasm.OpcodeI32Const, 0, 2248 wasm.OpcodeLocalGet, 5, 2249 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Store32, 0x2, 40, 2250 wasm.OpcodeI32Const, 0, 2251 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Load32U, 0x2, 40, 2252 wasm.OpcodeI32Const, 0, 2253 wasm.OpcodeLocalGet, 6, 2254 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Store, 0x3, 48, 2255 wasm.OpcodeI32Const, 0, 2256 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Load, 0x3, 48, 2257 wasm.OpcodeEnd, 2258 }}}, 2259 }, 2260 } 2261 2262 AtomicCas = TestCase{ 2263 Name: "atomic_cas", 2264 Module: &wasm.Module{ 2265 TypeSection: []wasm.FunctionType{{ 2266 Params: []wasm.ValueType{i32, i32, i32, i32, i32, i32, i64, i64, i64, i64, i64, i64, i64, i64}, 2267 Results: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2268 }}, 2269 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 2270 MemorySection: &wasm.Memory{Min: 1, Max: 1, IsMaxEncoded: true, IsShared: true}, 2271 FunctionSection: []wasm.Index{0}, 2272 CodeSection: []wasm.Code{{Body: []byte{ 2273 wasm.OpcodeI32Const, 0, 2274 wasm.OpcodeLocalGet, 0, 2275 wasm.OpcodeLocalGet, 1, 2276 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw8CmpxchgU, 0x0, 0, 2277 wasm.OpcodeI32Const, 0, 2278 wasm.OpcodeLocalGet, 2, 2279 wasm.OpcodeLocalGet, 3, 2280 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw16CmpxchgU, 0x1, 8, 2281 wasm.OpcodeI32Const, 0, 2282 wasm.OpcodeLocalGet, 4, 2283 wasm.OpcodeLocalGet, 5, 2284 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32RmwCmpxchg, 0x2, 16, 2285 wasm.OpcodeI32Const, 0, 2286 wasm.OpcodeLocalGet, 6, 2287 wasm.OpcodeLocalGet, 7, 2288 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw8CmpxchgU, 0x0, 24, 2289 wasm.OpcodeI32Const, 0, 2290 wasm.OpcodeLocalGet, 8, 2291 wasm.OpcodeLocalGet, 9, 2292 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw16CmpxchgU, 0x1, 32, 2293 wasm.OpcodeI32Const, 0, 2294 wasm.OpcodeLocalGet, 10, 2295 wasm.OpcodeLocalGet, 11, 2296 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw32CmpxchgU, 0x2, 40, 2297 wasm.OpcodeI32Const, 0, 2298 wasm.OpcodeLocalGet, 12, 2299 wasm.OpcodeLocalGet, 13, 2300 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64RmwCmpxchg, 0x3, 48, 2301 wasm.OpcodeEnd, 2302 }}}, 2303 }, 2304 } 2305 2306 AtomicCasConst0 = TestCase{ 2307 Name: "atomic_cas_const0", 2308 Module: &wasm.Module{ 2309 TypeSection: []wasm.FunctionType{{ 2310 Params: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2311 Results: []wasm.ValueType{i32, i32, i32, i64, i64, i64, i64}, 2312 }}, 2313 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 2314 MemorySection: &wasm.Memory{Min: 1, Max: 1, IsMaxEncoded: true, IsShared: true}, 2315 FunctionSection: []wasm.Index{0}, 2316 CodeSection: []wasm.Code{{Body: []byte{ 2317 wasm.OpcodeI32Const, 0, 2318 wasm.OpcodeI32Const, 0, 2319 wasm.OpcodeLocalGet, 0, 2320 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw8CmpxchgU, 0x0, 0, 2321 wasm.OpcodeI32Const, 8, 2322 wasm.OpcodeI32Const, 0, 2323 wasm.OpcodeLocalGet, 1, 2324 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32Rmw16CmpxchgU, 0x1, 0, 2325 wasm.OpcodeI32Const, 16, 2326 wasm.OpcodeI32Const, 0, 2327 wasm.OpcodeLocalGet, 2, 2328 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI32RmwCmpxchg, 0x2, 0, 2329 wasm.OpcodeI32Const, 24, 2330 wasm.OpcodeI64Const, 0, 2331 wasm.OpcodeLocalGet, 3, 2332 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw8CmpxchgU, 0x0, 0, 2333 wasm.OpcodeI32Const, 32, 2334 wasm.OpcodeI64Const, 0, 2335 wasm.OpcodeLocalGet, 4, 2336 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw16CmpxchgU, 0x1, 0, 2337 wasm.OpcodeI32Const, 40, 2338 wasm.OpcodeI64Const, 0, 2339 wasm.OpcodeLocalGet, 5, 2340 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64Rmw32CmpxchgU, 0x2, 0, 2341 wasm.OpcodeI32Const, 48, 2342 wasm.OpcodeI64Const, 0, 2343 wasm.OpcodeLocalGet, 6, 2344 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicI64RmwCmpxchg, 0x3, 0, 2345 wasm.OpcodeEnd, 2346 }}}, 2347 }, 2348 } 2349 2350 AtomicFence = TestCase{ 2351 Name: "atomic_fence", 2352 Module: &wasm.Module{ 2353 TypeSection: []wasm.FunctionType{{ 2354 Params: []wasm.ValueType{}, 2355 Results: []wasm.ValueType{}, 2356 }}, 2357 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 2358 MemorySection: &wasm.Memory{Min: 1, Max: 1, IsMaxEncoded: true, IsShared: true}, 2359 FunctionSection: []wasm.Index{0}, 2360 CodeSection: []wasm.Code{{Body: []byte{ 2361 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicFence, 0, 2362 wasm.OpcodeEnd, 2363 }}}, 2364 }, 2365 } 2366 2367 AtomicFenceNoMemory = TestCase{ 2368 Name: "atomic_fence", 2369 Module: &wasm.Module{ 2370 TypeSection: []wasm.FunctionType{{ 2371 Params: []wasm.ValueType{}, 2372 Results: []wasm.ValueType{}, 2373 }}, 2374 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 2375 FunctionSection: []wasm.Index{0}, 2376 CodeSection: []wasm.Code{{Body: []byte{ 2377 wasm.OpcodeAtomicPrefix, wasm.OpcodeAtomicFence, 0, 2378 wasm.OpcodeEnd, 2379 }}}, 2380 }, 2381 } 2382 2383 IcmpAndZero = TestCase{ 2384 Name: "icmp_and_zero", 2385 Module: &wasm.Module{ 2386 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{i32, i32}, Results: []wasm.ValueType{i32}}}, 2387 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 2388 FunctionSection: []wasm.Index{0}, 2389 CodeSection: []wasm.Code{{Body: []byte{ 2390 wasm.OpcodeLocalGet, 0, 2391 wasm.OpcodeLocalGet, 1, 2392 wasm.OpcodeI32And, 2393 wasm.OpcodeI32Eqz, 2394 wasm.OpcodeIf, blockSignature_vv, 2395 wasm.OpcodeI32Const, 1, 2396 wasm.OpcodeReturn, 2397 wasm.OpcodeElse, 2398 wasm.OpcodeI32Const, 0, 2399 wasm.OpcodeReturn, 2400 wasm.OpcodeEnd, 2401 wasm.OpcodeUnreachable, 2402 wasm.OpcodeEnd, 2403 }}}, 2404 }, 2405 } 2406 ) 2407 2408 // VecShuffleWithLane returns a VecShuffle test with a custom 16-bytes immediate (lane indexes). 2409 func VecShuffleWithLane(lane ...byte) *wasm.Module { 2410 return &wasm.Module{ 2411 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{v128, v128}, Results: []wasm.ValueType{v128}}}, 2412 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 2413 FunctionSection: []wasm.Index{0}, 2414 CodeSection: []wasm.Code{{ 2415 Body: append(append([]byte{ 2416 wasm.OpcodeLocalGet, 0, 2417 wasm.OpcodeLocalGet, 1, 2418 wasm.OpcodeVecPrefix, wasm.OpcodeVecV128i8x16Shuffle, 2419 }, lane...), 2420 wasm.OpcodeEnd), 2421 }}, 2422 } 2423 } 2424 2425 type TestCase struct { 2426 Name string 2427 Imported, Module *wasm.Module 2428 } 2429 2430 func SingleFunctionModule(typ wasm.FunctionType, body []byte, localTypes []wasm.ValueType) *wasm.Module { 2431 return &wasm.Module{ 2432 TypeSection: []wasm.FunctionType{typ}, 2433 FunctionSection: []wasm.Index{0}, 2434 CodeSection: []wasm.Code{{ 2435 LocalTypes: localTypes, 2436 Body: body, 2437 }}, 2438 ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}}, 2439 } 2440 } 2441 2442 var ( 2443 vv = wasm.FunctionType{} 2444 v_i32 = wasm.FunctionType{Results: []wasm.ValueType{i32}} 2445 v_i32i32 = wasm.FunctionType{Results: []wasm.ValueType{i32, i32}} 2446 i32_v = wasm.FunctionType{Params: []wasm.ValueType{i32}} 2447 i32_i32 = wasm.FunctionType{Params: []wasm.ValueType{i32}, Results: []wasm.ValueType{i32}} 2448 i32i32_i32 = wasm.FunctionType{Params: []wasm.ValueType{i32, i32}, Results: []wasm.ValueType{i32}} 2449 i32i32_i32i32 = wasm.FunctionType{Params: []wasm.ValueType{i32, i32}, Results: []wasm.ValueType{i32, i32}} 2450 i32i32i64i64f32f32f64f64_i32i64 = wasm.FunctionType{Params: []wasm.ValueType{i32, i32, i64, i64, f32, f32, f64, f64}, Results: []wasm.ValueType{i32, i64, f32, f64}} 2451 i32_i32i32 = wasm.FunctionType{Params: []wasm.ValueType{i32}, Results: []wasm.ValueType{i32, i32}} 2452 i32f32f64_v = wasm.FunctionType{Params: []wasm.ValueType{i32, f32, f64}, Results: nil} 2453 i64f32f64_i64f32f64 = wasm.FunctionType{Params: []wasm.ValueType{i64, f32, f64}, Results: []wasm.ValueType{i64, f32, f64}} 2454 ) 2455 2456 const ( 2457 i32 = wasm.ValueTypeI32 2458 i64 = wasm.ValueTypeI64 2459 f32 = wasm.ValueTypeF32 2460 f64 = wasm.ValueTypeF64 2461 v128 = wasm.ValueTypeV128 2462 2463 blockSignature_vv = 0x40 // 0x40 is the v_v signature in 33-bit signed. See wasm.DecodeBlockType. 2464 ) 2465 2466 func maskedBuf(size int) []byte { 2467 ret := make([]byte, size) 2468 for i := range ret { 2469 ret[i] = byte(i) 2470 } 2471 return ret 2472 } 2473 2474 func constExprI32(i int32) wasm.ConstantExpression { 2475 return wasm.ConstantExpression{ 2476 Opcode: wasm.OpcodeI32Const, 2477 Data: leb128.EncodeInt32(i), 2478 } 2479 } 2480 2481 func constExprI64(i int64) wasm.ConstantExpression { 2482 return wasm.ConstantExpression{ 2483 Opcode: wasm.OpcodeI64Const, 2484 Data: leb128.EncodeInt64(i), 2485 } 2486 } 2487 2488 func constExprF32(i float32) wasm.ConstantExpression { 2489 b := math.Float32bits(i) 2490 return wasm.ConstantExpression{ 2491 Opcode: wasm.OpcodeF32Const, 2492 Data: []byte{byte(b), byte(b >> 8), byte(b >> 16), byte(b >> 24)}, 2493 } 2494 } 2495 2496 func constExprF64(i float64) wasm.ConstantExpression { 2497 b := math.Float64bits(i) 2498 return wasm.ConstantExpression{ 2499 Opcode: wasm.OpcodeF64Const, 2500 Data: []byte{ 2501 byte(b), byte(b >> 8), byte(b >> 16), byte(b >> 24), 2502 byte(b >> 32), byte(b >> 40), byte(b >> 48), byte(b >> 56), 2503 }, 2504 } 2505 } 2506 2507 func constExprV128(lo, hi uint64) wasm.ConstantExpression { 2508 return wasm.ConstantExpression{ 2509 Opcode: wasm.OpcodeVecV128Const, 2510 Data: []byte{ 2511 byte(lo), byte(lo >> 8), byte(lo >> 16), byte(lo >> 24), 2512 byte(lo >> 32), byte(lo >> 40), byte(lo >> 48), byte(lo >> 56), 2513 byte(hi), byte(hi >> 8), byte(hi >> 16), byte(hi >> 24), 2514 byte(hi >> 32), byte(hi >> 40), byte(hi >> 48), byte(hi >> 56), 2515 }, 2516 } 2517 }