| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_WASM_OPCODES_H_ | 5 #ifndef V8_WASM_OPCODES_H_ |
| 6 #define V8_WASM_OPCODES_H_ | 6 #define V8_WASM_OPCODES_H_ |
| 7 | 7 |
| 8 #include "src/globals.h" | 8 #include "src/globals.h" |
| 9 #include "src/machine-type.h" | 9 #include "src/machine-type.h" |
| 10 #include "src/runtime/runtime.h" | 10 #include "src/runtime/runtime.h" |
| 11 #include "src/signature.h" | 11 #include "src/signature.h" |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 namespace wasm { | 15 namespace wasm { |
| 16 | 16 |
| 17 // Binary encoding of local types. | 17 // Binary encoding of local types. |
| 18 enum LocalTypeCode { | 18 enum ValueTypeCode { |
| 19 kLocalVoid = 0x40, | 19 kLocalVoid = 0x40, |
| 20 kLocalI32 = 0x7f, | 20 kLocalI32 = 0x7f, |
| 21 kLocalI64 = 0x7e, | 21 kLocalI64 = 0x7e, |
| 22 kLocalF32 = 0x7d, | 22 kLocalF32 = 0x7d, |
| 23 kLocalF64 = 0x7c, | 23 kLocalF64 = 0x7c, |
| 24 kLocalS128 = 0x7b | 24 kLocalS128 = 0x7b |
| 25 }; | 25 }; |
| 26 | 26 |
| 27 // Type code for multi-value block types. | 27 // Type code for multi-value block types. |
| 28 static const uint8_t kMultivalBlock = 0x41; | 28 static const uint8_t kMultivalBlock = 0x41; |
| 29 | 29 |
| 30 // We reuse the internal machine type to represent WebAssembly types. | 30 // We reuse the internal machine type to represent WebAssembly types. |
| 31 // A typedef improves readability without adding a whole new type system. | 31 // A typedef improves readability without adding a whole new type system. |
| 32 typedef MachineRepresentation LocalType; | 32 typedef MachineRepresentation ValueType; |
| 33 const LocalType kAstStmt = MachineRepresentation::kNone; | 33 const ValueType kWasmStmt = MachineRepresentation::kNone; |
| 34 const LocalType kAstI32 = MachineRepresentation::kWord32; | 34 const ValueType kWasmI32 = MachineRepresentation::kWord32; |
| 35 const LocalType kAstI64 = MachineRepresentation::kWord64; | 35 const ValueType kWasmI64 = MachineRepresentation::kWord64; |
| 36 const LocalType kAstF32 = MachineRepresentation::kFloat32; | 36 const ValueType kWasmF32 = MachineRepresentation::kFloat32; |
| 37 const LocalType kAstF64 = MachineRepresentation::kFloat64; | 37 const ValueType kWasmF64 = MachineRepresentation::kFloat64; |
| 38 const LocalType kAstS128 = MachineRepresentation::kSimd128; | 38 const ValueType kWasmS128 = MachineRepresentation::kSimd128; |
| 39 // We use kTagged here because kNone is already used by kAstStmt. | 39 // We use kTagged here because kNone is already used by kWasmStmt. |
| 40 const LocalType kAstEnd = MachineRepresentation::kTagged; | 40 const ValueType kWasmEnd = MachineRepresentation::kTagged; |
| 41 | 41 |
| 42 typedef Signature<LocalType> FunctionSig; | 42 typedef Signature<ValueType> FunctionSig; |
| 43 std::ostream& operator<<(std::ostream& os, const FunctionSig& function); | 43 std::ostream& operator<<(std::ostream& os, const FunctionSig& function); |
| 44 | 44 |
| 45 typedef Vector<const char> WasmName; | 45 typedef Vector<const char> WasmName; |
| 46 | 46 |
| 47 typedef int WasmCodePosition; | 47 typedef int WasmCodePosition; |
| 48 const WasmCodePosition kNoCodePosition = -1; | 48 const WasmCodePosition kNoCodePosition = -1; |
| 49 | 49 |
| 50 // Control expressions and blocks. | 50 // Control expressions and blocks. |
| 51 #define FOREACH_CONTROL_OPCODE(V) \ | 51 #define FOREACH_CONTROL_OPCODE(V) \ |
| 52 V(Unreachable, 0x00, _) \ | 52 V(Unreachable, 0x00, _) \ |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 FOREACH_SIMPLE_OPCODE(V) \ | 445 FOREACH_SIMPLE_OPCODE(V) \ |
| 446 FOREACH_STORE_MEM_OPCODE(V) \ | 446 FOREACH_STORE_MEM_OPCODE(V) \ |
| 447 FOREACH_LOAD_MEM_OPCODE(V) \ | 447 FOREACH_LOAD_MEM_OPCODE(V) \ |
| 448 FOREACH_MISC_MEM_OPCODE(V) \ | 448 FOREACH_MISC_MEM_OPCODE(V) \ |
| 449 FOREACH_ASMJS_COMPAT_OPCODE(V) \ | 449 FOREACH_ASMJS_COMPAT_OPCODE(V) \ |
| 450 FOREACH_SIMD_0_OPERAND_OPCODE(V) \ | 450 FOREACH_SIMD_0_OPERAND_OPCODE(V) \ |
| 451 FOREACH_SIMD_1_OPERAND_OPCODE(V) \ | 451 FOREACH_SIMD_1_OPERAND_OPCODE(V) \ |
| 452 FOREACH_ATOMIC_OPCODE(V) | 452 FOREACH_ATOMIC_OPCODE(V) |
| 453 | 453 |
| 454 // All signatures. | 454 // All signatures. |
| 455 #define FOREACH_SIGNATURE(V) \ | 455 #define FOREACH_SIGNATURE(V) \ |
| 456 FOREACH_SIMD_SIGNATURE(V) \ | 456 FOREACH_SIMD_SIGNATURE(V) \ |
| 457 V(i_ii, kAstI32, kAstI32, kAstI32) \ | 457 V(i_ii, kWasmI32, kWasmI32, kWasmI32) \ |
| 458 V(i_i, kAstI32, kAstI32) \ | 458 V(i_i, kWasmI32, kWasmI32) \ |
| 459 V(i_v, kAstI32) \ | 459 V(i_v, kWasmI32) \ |
| 460 V(i_ff, kAstI32, kAstF32, kAstF32) \ | 460 V(i_ff, kWasmI32, kWasmF32, kWasmF32) \ |
| 461 V(i_f, kAstI32, kAstF32) \ | 461 V(i_f, kWasmI32, kWasmF32) \ |
| 462 V(i_dd, kAstI32, kAstF64, kAstF64) \ | 462 V(i_dd, kWasmI32, kWasmF64, kWasmF64) \ |
| 463 V(i_d, kAstI32, kAstF64) \ | 463 V(i_d, kWasmI32, kWasmF64) \ |
| 464 V(i_l, kAstI32, kAstI64) \ | 464 V(i_l, kWasmI32, kWasmI64) \ |
| 465 V(l_ll, kAstI64, kAstI64, kAstI64) \ | 465 V(l_ll, kWasmI64, kWasmI64, kWasmI64) \ |
| 466 V(i_ll, kAstI32, kAstI64, kAstI64) \ | 466 V(i_ll, kWasmI32, kWasmI64, kWasmI64) \ |
| 467 V(l_l, kAstI64, kAstI64) \ | 467 V(l_l, kWasmI64, kWasmI64) \ |
| 468 V(l_i, kAstI64, kAstI32) \ | 468 V(l_i, kWasmI64, kWasmI32) \ |
| 469 V(l_f, kAstI64, kAstF32) \ | 469 V(l_f, kWasmI64, kWasmF32) \ |
| 470 V(l_d, kAstI64, kAstF64) \ | 470 V(l_d, kWasmI64, kWasmF64) \ |
| 471 V(f_ff, kAstF32, kAstF32, kAstF32) \ | 471 V(f_ff, kWasmF32, kWasmF32, kWasmF32) \ |
| 472 V(f_f, kAstF32, kAstF32) \ | 472 V(f_f, kWasmF32, kWasmF32) \ |
| 473 V(f_d, kAstF32, kAstF64) \ | 473 V(f_d, kWasmF32, kWasmF64) \ |
| 474 V(f_i, kAstF32, kAstI32) \ | 474 V(f_i, kWasmF32, kWasmI32) \ |
| 475 V(f_l, kAstF32, kAstI64) \ | 475 V(f_l, kWasmF32, kWasmI64) \ |
| 476 V(d_dd, kAstF64, kAstF64, kAstF64) \ | 476 V(d_dd, kWasmF64, kWasmF64, kWasmF64) \ |
| 477 V(d_d, kAstF64, kAstF64) \ | 477 V(d_d, kWasmF64, kWasmF64) \ |
| 478 V(d_f, kAstF64, kAstF32) \ | 478 V(d_f, kWasmF64, kWasmF32) \ |
| 479 V(d_i, kAstF64, kAstI32) \ | 479 V(d_i, kWasmF64, kWasmI32) \ |
| 480 V(d_l, kAstF64, kAstI64) \ | 480 V(d_l, kWasmF64, kWasmI64) \ |
| 481 V(d_id, kAstF64, kAstI32, kAstF64) \ | 481 V(d_id, kWasmF64, kWasmI32, kWasmF64) \ |
| 482 V(f_if, kAstF32, kAstI32, kAstF32) \ | 482 V(f_if, kWasmF32, kWasmI32, kWasmF32) \ |
| 483 V(l_il, kAstI64, kAstI32, kAstI64) | 483 V(l_il, kWasmI64, kWasmI32, kWasmI64) |
| 484 | 484 |
| 485 #define FOREACH_SIMD_SIGNATURE(V) \ | 485 #define FOREACH_SIMD_SIGNATURE(V) \ |
| 486 V(s_s, kAstS128, kAstS128) \ | 486 V(s_s, kWasmS128, kWasmS128) \ |
| 487 V(s_f, kAstS128, kAstF32) \ | 487 V(s_f, kWasmS128, kWasmF32) \ |
| 488 V(s_ss, kAstS128, kAstS128, kAstS128) \ | 488 V(s_ss, kWasmS128, kWasmS128, kWasmS128) \ |
| 489 V(s_sss, kAstS128, kAstS128, kAstS128, kAstS128) \ | 489 V(s_sss, kWasmS128, kWasmS128, kWasmS128, kWasmS128) \ |
| 490 V(s_i, kAstS128, kAstI32) \ | 490 V(s_i, kWasmS128, kWasmI32) \ |
| 491 V(s_si, kAstS128, kAstS128, kAstI32) | 491 V(s_si, kWasmS128, kWasmS128, kWasmI32) |
| 492 | 492 |
| 493 #define FOREACH_PREFIX(V) \ | 493 #define FOREACH_PREFIX(V) \ |
| 494 V(Simd, 0xe5) \ | 494 V(Simd, 0xe5) \ |
| 495 V(Atomic, 0xe6) | 495 V(Atomic, 0xe6) |
| 496 | 496 |
| 497 enum WasmOpcode { | 497 enum WasmOpcode { |
| 498 // Declare expression opcodes. | 498 // Declare expression opcodes. |
| 499 #define DECLARE_NAMED_ENUM(name, opcode, sig) kExpr##name = opcode, | 499 #define DECLARE_NAMED_ENUM(name, opcode, sig) kExpr##name = opcode, |
| 500 FOREACH_OPCODE(DECLARE_NAMED_ENUM) | 500 FOREACH_OPCODE(DECLARE_NAMED_ENUM) |
| 501 #undef DECLARE_NAMED_ENUM | 501 #undef DECLARE_NAMED_ENUM |
| (...skipping 30 matching lines...) Expand all Loading... |
| 532 static FunctionSig* AtomicSignature(WasmOpcode opcode); | 532 static FunctionSig* AtomicSignature(WasmOpcode opcode); |
| 533 static bool IsPrefixOpcode(WasmOpcode opcode); | 533 static bool IsPrefixOpcode(WasmOpcode opcode); |
| 534 | 534 |
| 535 static int TrapReasonToMessageId(TrapReason reason); | 535 static int TrapReasonToMessageId(TrapReason reason); |
| 536 static const char* TrapReasonMessage(TrapReason reason); | 536 static const char* TrapReasonMessage(TrapReason reason); |
| 537 | 537 |
| 538 static byte MemSize(MachineType type) { | 538 static byte MemSize(MachineType type) { |
| 539 return 1 << ElementSizeLog2Of(type.representation()); | 539 return 1 << ElementSizeLog2Of(type.representation()); |
| 540 } | 540 } |
| 541 | 541 |
| 542 static byte MemSize(LocalType type) { return 1 << ElementSizeLog2Of(type); } | 542 static byte MemSize(ValueType type) { return 1 << ElementSizeLog2Of(type); } |
| 543 | 543 |
| 544 static LocalTypeCode LocalTypeCodeFor(LocalType type) { | 544 static ValueTypeCode ValueTypeCodeFor(ValueType type) { |
| 545 switch (type) { | 545 switch (type) { |
| 546 case kAstI32: | 546 case kWasmI32: |
| 547 return kLocalI32; | 547 return kLocalI32; |
| 548 case kAstI64: | 548 case kWasmI64: |
| 549 return kLocalI64; | 549 return kLocalI64; |
| 550 case kAstF32: | 550 case kWasmF32: |
| 551 return kLocalF32; | 551 return kLocalF32; |
| 552 case kAstF64: | 552 case kWasmF64: |
| 553 return kLocalF64; | 553 return kLocalF64; |
| 554 case kAstS128: | 554 case kWasmS128: |
| 555 return kLocalS128; | 555 return kLocalS128; |
| 556 case kAstStmt: | 556 case kWasmStmt: |
| 557 return kLocalVoid; | 557 return kLocalVoid; |
| 558 default: | 558 default: |
| 559 UNREACHABLE(); | 559 UNREACHABLE(); |
| 560 return kLocalVoid; | 560 return kLocalVoid; |
| 561 } | 561 } |
| 562 } | 562 } |
| 563 | 563 |
| 564 static MachineType MachineTypeFor(LocalType type) { | 564 static MachineType MachineTypeFor(ValueType type) { |
| 565 switch (type) { | 565 switch (type) { |
| 566 case kAstI32: | 566 case kWasmI32: |
| 567 return MachineType::Int32(); | 567 return MachineType::Int32(); |
| 568 case kAstI64: | 568 case kWasmI64: |
| 569 return MachineType::Int64(); | 569 return MachineType::Int64(); |
| 570 case kAstF32: | 570 case kWasmF32: |
| 571 return MachineType::Float32(); | 571 return MachineType::Float32(); |
| 572 case kAstF64: | 572 case kWasmF64: |
| 573 return MachineType::Float64(); | 573 return MachineType::Float64(); |
| 574 case kAstS128: | 574 case kWasmS128: |
| 575 return MachineType::Simd128(); | 575 return MachineType::Simd128(); |
| 576 case kAstStmt: | 576 case kWasmStmt: |
| 577 return MachineType::None(); | 577 return MachineType::None(); |
| 578 default: | 578 default: |
| 579 UNREACHABLE(); | 579 UNREACHABLE(); |
| 580 return MachineType::None(); | 580 return MachineType::None(); |
| 581 } | 581 } |
| 582 } | 582 } |
| 583 | 583 |
| 584 static LocalType LocalTypeFor(MachineType type) { | 584 static ValueType ValueTypeFor(MachineType type) { |
| 585 if (type == MachineType::Int8()) { | 585 if (type == MachineType::Int8()) { |
| 586 return kAstI32; | 586 return kWasmI32; |
| 587 } else if (type == MachineType::Uint8()) { | 587 } else if (type == MachineType::Uint8()) { |
| 588 return kAstI32; | 588 return kWasmI32; |
| 589 } else if (type == MachineType::Int16()) { | 589 } else if (type == MachineType::Int16()) { |
| 590 return kAstI32; | 590 return kWasmI32; |
| 591 } else if (type == MachineType::Uint16()) { | 591 } else if (type == MachineType::Uint16()) { |
| 592 return kAstI32; | 592 return kWasmI32; |
| 593 } else if (type == MachineType::Int32()) { | 593 } else if (type == MachineType::Int32()) { |
| 594 return kAstI32; | 594 return kWasmI32; |
| 595 } else if (type == MachineType::Uint32()) { | 595 } else if (type == MachineType::Uint32()) { |
| 596 return kAstI32; | 596 return kWasmI32; |
| 597 } else if (type == MachineType::Int64()) { | 597 } else if (type == MachineType::Int64()) { |
| 598 return kAstI64; | 598 return kWasmI64; |
| 599 } else if (type == MachineType::Uint64()) { | 599 } else if (type == MachineType::Uint64()) { |
| 600 return kAstI64; | 600 return kWasmI64; |
| 601 } else if (type == MachineType::Float32()) { | 601 } else if (type == MachineType::Float32()) { |
| 602 return kAstF32; | 602 return kWasmF32; |
| 603 } else if (type == MachineType::Float64()) { | 603 } else if (type == MachineType::Float64()) { |
| 604 return kAstF64; | 604 return kWasmF64; |
| 605 } else if (type == MachineType::Simd128()) { | 605 } else if (type == MachineType::Simd128()) { |
| 606 return kAstS128; | 606 return kWasmS128; |
| 607 } else { | 607 } else { |
| 608 UNREACHABLE(); | 608 UNREACHABLE(); |
| 609 return kAstI32; | 609 return kWasmI32; |
| 610 } | 610 } |
| 611 } | 611 } |
| 612 | 612 |
| 613 static WasmOpcode LoadStoreOpcodeOf(MachineType type, bool store) { | 613 static WasmOpcode LoadStoreOpcodeOf(MachineType type, bool store) { |
| 614 if (type == MachineType::Int8()) { | 614 if (type == MachineType::Int8()) { |
| 615 return store ? kExprI32StoreMem8 : kExprI32LoadMem8S; | 615 return store ? kExprI32StoreMem8 : kExprI32LoadMem8S; |
| 616 } else if (type == MachineType::Uint8()) { | 616 } else if (type == MachineType::Uint8()) { |
| 617 return store ? kExprI32StoreMem8 : kExprI32LoadMem8U; | 617 return store ? kExprI32StoreMem8 : kExprI32LoadMem8U; |
| 618 } else if (type == MachineType::Int16()) { | 618 } else if (type == MachineType::Int16()) { |
| 619 return store ? kExprI32StoreMem16 : kExprI32LoadMem16S; | 619 return store ? kExprI32StoreMem16 : kExprI32LoadMem16S; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 630 } else if (type == MachineType::Float32()) { | 630 } else if (type == MachineType::Float32()) { |
| 631 return store ? kExprF32StoreMem : kExprF32LoadMem; | 631 return store ? kExprF32StoreMem : kExprF32LoadMem; |
| 632 } else if (type == MachineType::Float64()) { | 632 } else if (type == MachineType::Float64()) { |
| 633 return store ? kExprF64StoreMem : kExprF64LoadMem; | 633 return store ? kExprF64StoreMem : kExprF64LoadMem; |
| 634 } else { | 634 } else { |
| 635 UNREACHABLE(); | 635 UNREACHABLE(); |
| 636 return kExprNop; | 636 return kExprNop; |
| 637 } | 637 } |
| 638 } | 638 } |
| 639 | 639 |
| 640 static char ShortNameOf(LocalType type) { | 640 static char ShortNameOf(ValueType type) { |
| 641 switch (type) { | 641 switch (type) { |
| 642 case kAstI32: | 642 case kWasmI32: |
| 643 return 'i'; | 643 return 'i'; |
| 644 case kAstI64: | 644 case kWasmI64: |
| 645 return 'l'; | 645 return 'l'; |
| 646 case kAstF32: | 646 case kWasmF32: |
| 647 return 'f'; | 647 return 'f'; |
| 648 case kAstF64: | 648 case kWasmF64: |
| 649 return 'd'; | 649 return 'd'; |
| 650 case kAstS128: | 650 case kWasmS128: |
| 651 return 's'; | 651 return 's'; |
| 652 case kAstStmt: | 652 case kWasmStmt: |
| 653 return 'v'; | 653 return 'v'; |
| 654 case kAstEnd: | 654 case kWasmEnd: |
| 655 return 'x'; | 655 return 'x'; |
| 656 default: | 656 default: |
| 657 UNREACHABLE(); | 657 UNREACHABLE(); |
| 658 return '?'; | 658 return '?'; |
| 659 } | 659 } |
| 660 } | 660 } |
| 661 | 661 |
| 662 static const char* TypeName(LocalType type) { | 662 static const char* TypeName(ValueType type) { |
| 663 switch (type) { | 663 switch (type) { |
| 664 case kAstI32: | 664 case kWasmI32: |
| 665 return "i32"; | 665 return "i32"; |
| 666 case kAstI64: | 666 case kWasmI64: |
| 667 return "i64"; | 667 return "i64"; |
| 668 case kAstF32: | 668 case kWasmF32: |
| 669 return "f32"; | 669 return "f32"; |
| 670 case kAstF64: | 670 case kWasmF64: |
| 671 return "f64"; | 671 return "f64"; |
| 672 case kAstS128: | 672 case kWasmS128: |
| 673 return "s128"; | 673 return "s128"; |
| 674 case kAstStmt: | 674 case kWasmStmt: |
| 675 return "<stmt>"; | 675 return "<stmt>"; |
| 676 case kAstEnd: | 676 case kWasmEnd: |
| 677 return "<end>"; | 677 return "<end>"; |
| 678 default: | 678 default: |
| 679 return "<unknown>"; | 679 return "<unknown>"; |
| 680 } | 680 } |
| 681 } | 681 } |
| 682 }; | 682 }; |
| 683 } // namespace wasm | 683 } // namespace wasm |
| 684 } // namespace internal | 684 } // namespace internal |
| 685 } // namespace v8 | 685 } // namespace v8 |
| 686 | 686 |
| 687 #endif // V8_WASM_OPCODES_H_ | 687 #endif // V8_WASM_OPCODES_H_ |
| OLD | NEW |