|
1 | 1 | use crate::{ |
2 | | - ir::{BranchOffset, Op, Slot}, |
| 2 | + ir::{self, BranchOffset, Op, Slot}, |
3 | 3 | Error, |
4 | 4 | }; |
5 | 5 |
|
@@ -590,3 +590,125 @@ impl TryIntoCmpBranchInstr for Op { |
590 | 590 | Some(cmp_branch_instr) |
591 | 591 | } |
592 | 592 | } |
| 593 | + |
| 594 | +/// Extension trait for [`Op`] to update [`BranchOffset`] of branch operators. |
| 595 | +pub trait UpdateBranchOffset: Sized { |
| 596 | + /// Updates the [`BranchOffset`] of `self` to `new_offset`. |
| 597 | + /// |
| 598 | + /// # Panics |
| 599 | + /// |
| 600 | + /// - If `self` does not have a [`BranchOffset`] to udpate. |
| 601 | + /// - If the [`BranchOffset`] of `self` is already initialized. (Debug) |
| 602 | + fn update_branch_offset(&mut self, new_offset: BranchOffset); |
| 603 | + |
| 604 | + /// Consumes `self` and returns it back with its [`BranchOffset`] set to `new_offset`. |
| 605 | + fn with_branch_offset(self, new_offset: BranchOffset) -> Self { |
| 606 | + let mut this = self; |
| 607 | + this.update_branch_offset(new_offset); |
| 608 | + this |
| 609 | + } |
| 610 | +} |
| 611 | + |
| 612 | +impl UpdateBranchOffset for ir::BranchTableTarget { |
| 613 | + fn update_branch_offset(&mut self, new_offset: BranchOffset) { |
| 614 | + self.offset = new_offset; |
| 615 | + } |
| 616 | +} |
| 617 | + |
| 618 | +impl UpdateBranchOffset for Op { |
| 619 | + #[track_caller] |
| 620 | + fn update_branch_offset(&mut self, new_offset: BranchOffset) { |
| 621 | + match self { |
| 622 | + // unconditional |
| 623 | + | Op::Branch { offset } |
| 624 | + // i32 |
| 625 | + | Op::BranchI32Eq_Ss { offset, .. } |
| 626 | + | Op::BranchI32Eq_Si { offset, .. } |
| 627 | + | Op::BranchI32And_Ss { offset, .. } |
| 628 | + | Op::BranchI32And_Si { offset, .. } |
| 629 | + | Op::BranchI32Or_Ss { offset, .. } |
| 630 | + | Op::BranchI32Or_Si { offset, .. } |
| 631 | + | Op::BranchI32NotEq_Ss { offset, .. } |
| 632 | + | Op::BranchI32NotEq_Si { offset, .. } |
| 633 | + | Op::BranchI32NotAnd_Ss { offset, .. } |
| 634 | + | Op::BranchI32NotAnd_Si { offset, .. } |
| 635 | + | Op::BranchI32NotOr_Ss { offset, .. } |
| 636 | + | Op::BranchI32NotOr_Si { offset, .. } |
| 637 | + | Op::BranchI32Lt_Ss { offset, .. } |
| 638 | + | Op::BranchI32Lt_Si { offset, .. } |
| 639 | + | Op::BranchI32Lt_Is { offset, .. } |
| 640 | + | Op::BranchU32Lt_Ss { offset, .. } |
| 641 | + | Op::BranchU32Lt_Si { offset, .. } |
| 642 | + | Op::BranchU32Lt_Is { offset, .. } |
| 643 | + | Op::BranchI32Le_Ss { offset, .. } |
| 644 | + | Op::BranchI32Le_Si { offset, .. } |
| 645 | + | Op::BranchI32Le_Is { offset, .. } |
| 646 | + | Op::BranchU32Le_Ss { offset, .. } |
| 647 | + | Op::BranchU32Le_Si { offset, .. } |
| 648 | + | Op::BranchU32Le_Is { offset, .. } |
| 649 | + // i64 |
| 650 | + | Op::BranchI64Eq_Ss { offset, .. } |
| 651 | + | Op::BranchI64Eq_Si { offset, .. } |
| 652 | + | Op::BranchI64And_Ss { offset, .. } |
| 653 | + | Op::BranchI64And_Si { offset, .. } |
| 654 | + | Op::BranchI64Or_Ss { offset, .. } |
| 655 | + | Op::BranchI64Or_Si { offset, .. } |
| 656 | + | Op::BranchI64NotEq_Ss { offset, .. } |
| 657 | + | Op::BranchI64NotEq_Si { offset, .. } |
| 658 | + | Op::BranchI64NotAnd_Ss { offset, .. } |
| 659 | + | Op::BranchI64NotAnd_Si { offset, .. } |
| 660 | + | Op::BranchI64NotOr_Ss { offset, .. } |
| 661 | + | Op::BranchI64NotOr_Si { offset, .. } |
| 662 | + | Op::BranchI64Lt_Ss { offset, .. } |
| 663 | + | Op::BranchI64Lt_Si { offset, .. } |
| 664 | + | Op::BranchI64Lt_Is { offset, .. } |
| 665 | + | Op::BranchU64Lt_Ss { offset, .. } |
| 666 | + | Op::BranchU64Lt_Si { offset, .. } |
| 667 | + | Op::BranchU64Lt_Is { offset, .. } |
| 668 | + | Op::BranchI64Le_Ss { offset, .. } |
| 669 | + | Op::BranchI64Le_Si { offset, .. } |
| 670 | + | Op::BranchI64Le_Is { offset, .. } |
| 671 | + | Op::BranchU64Le_Ss { offset, .. } |
| 672 | + | Op::BranchU64Le_Si { offset, .. } |
| 673 | + | Op::BranchU64Le_Is { offset, .. } |
| 674 | + // f32 |
| 675 | + | Op::BranchF32Eq_Ss { offset, .. } |
| 676 | + | Op::BranchF32Eq_Si { offset, .. } |
| 677 | + | Op::BranchF32Lt_Ss { offset, .. } |
| 678 | + | Op::BranchF32Lt_Si { offset, .. } |
| 679 | + | Op::BranchF32Lt_Is { offset, .. } |
| 680 | + | Op::BranchF32Le_Ss { offset, .. } |
| 681 | + | Op::BranchF32Le_Si { offset, .. } |
| 682 | + | Op::BranchF32Le_Is { offset, .. } |
| 683 | + | Op::BranchF32NotEq_Ss { offset, .. } |
| 684 | + | Op::BranchF32NotEq_Si { offset, .. } |
| 685 | + | Op::BranchF32NotLt_Ss { offset, .. } |
| 686 | + | Op::BranchF32NotLt_Si { offset, .. } |
| 687 | + | Op::BranchF32NotLt_Is { offset, .. } |
| 688 | + | Op::BranchF32NotLe_Ss { offset, .. } |
| 689 | + | Op::BranchF32NotLe_Si { offset, .. } |
| 690 | + | Op::BranchF32NotLe_Is { offset, .. } |
| 691 | + // f64 |
| 692 | + | Op::BranchF64Eq_Ss { offset, .. } |
| 693 | + | Op::BranchF64Eq_Si { offset, .. } |
| 694 | + | Op::BranchF64Lt_Ss { offset, .. } |
| 695 | + | Op::BranchF64Lt_Si { offset, .. } |
| 696 | + | Op::BranchF64Lt_Is { offset, .. } |
| 697 | + | Op::BranchF64Le_Ss { offset, .. } |
| 698 | + | Op::BranchF64Le_Si { offset, .. } |
| 699 | + | Op::BranchF64Le_Is { offset, .. } |
| 700 | + | Op::BranchF64NotEq_Ss { offset, .. } |
| 701 | + | Op::BranchF64NotEq_Si { offset, .. } |
| 702 | + | Op::BranchF64NotLt_Ss { offset, .. } |
| 703 | + | Op::BranchF64NotLt_Si { offset, .. } |
| 704 | + | Op::BranchF64NotLt_Is { offset, .. } |
| 705 | + | Op::BranchF64NotLe_Ss { offset, .. } |
| 706 | + | Op::BranchF64NotLe_Si { offset, .. } |
| 707 | + | Op::BranchF64NotLe_Is { offset, .. } => { |
| 708 | + debug_assert!(!offset.is_init()); |
| 709 | + *offset = new_offset; |
| 710 | + } |
| 711 | + _ => panic!("expected branch `Op` but found: {:?}", self), |
| 712 | + } |
| 713 | + } |
| 714 | +} |
0 commit comments