Return information about a call instruction. Any instruction that can call another function reveals its call signature here.
(
&'a self,
pool: &'a ValueListPool,
exception_tables: &ExceptionTables,
)
| 587 | /// |
| 588 | /// Any instruction that can call another function reveals its call signature here. |
| 589 | pub fn analyze_call<'a>( |
| 590 | &'a self, |
| 591 | pool: &'a ValueListPool, |
| 592 | exception_tables: &ExceptionTables, |
| 593 | ) -> CallInfo<'a> { |
| 594 | match *self { |
| 595 | Self::Call { |
| 596 | func_ref, ref args, .. |
| 597 | } => CallInfo::Direct(func_ref, args.as_slice(pool)), |
| 598 | Self::CallIndirect { |
| 599 | sig_ref, ref args, .. |
| 600 | } => CallInfo::Indirect(sig_ref, &args.as_slice(pool)[1..]), |
| 601 | Self::TryCall { |
| 602 | func_ref, |
| 603 | ref args, |
| 604 | exception, |
| 605 | .. |
| 606 | } => { |
| 607 | let exdata = &exception_tables[exception]; |
| 608 | CallInfo::DirectWithSig(func_ref, exdata.signature(), args.as_slice(pool)) |
| 609 | } |
| 610 | Self::TryCallIndirect { |
| 611 | exception, |
| 612 | ref args, |
| 613 | .. |
| 614 | } => { |
| 615 | let exdata = &exception_tables[exception]; |
| 616 | CallInfo::Indirect(exdata.signature(), &args.as_slice(pool)[1..]) |
| 617 | } |
| 618 | Self::Ternary { |
| 619 | opcode: Opcode::StackSwitch, |
| 620 | .. |
| 621 | } => { |
| 622 | // `StackSwitch` is not actually a call, but has the .call() side |
| 623 | // effect as it continues execution elsewhere. |
| 624 | CallInfo::NotACall |
| 625 | } |
| 626 | _ => { |
| 627 | debug_assert!(!self.opcode().is_call()); |
| 628 | CallInfo::NotACall |
| 629 | } |
| 630 | } |
| 631 | } |
| 632 | |
| 633 | #[inline] |
| 634 | pub(crate) fn mask_immediates(&mut self, ctrl_typevar: Type) { |
no test coverage detected