(
&mut self,
resolver: &Resolver,
interpreter: &mut Interpreter,
data_store: &mut impl DataStore,
gas_status: &mut GasStatus,
)
| 729 | } |
| 730 | |
| 731 | fn execute_code_impl( |
| 732 | &mut self, |
| 733 | resolver: &Resolver, |
| 734 | interpreter: &mut Interpreter, |
| 735 | data_store: &mut impl DataStore, |
| 736 | gas_status: &mut GasStatus, |
| 737 | ) -> PartialVMResult<ExitCode> { |
| 738 | let code = self.function.code(); |
| 739 | loop { |
| 740 | for instruction in &code[self.pc as usize..] { |
| 741 | trace!( |
| 742 | &self.function, |
| 743 | &self.locals, |
| 744 | self.pc, |
| 745 | instruction, |
| 746 | resolver, |
| 747 | interpreter |
| 748 | ); |
| 749 | |
| 750 | fail_point!("move_vm::interpreter_loop", |_| { |
| 751 | Err( |
| 752 | PartialVMError::new(StatusCode::VERIFIER_INVARIANT_VIOLATION).with_message( |
| 753 | "Injected move_vm::interpreter verifier failure".to_owned(), |
| 754 | ), |
| 755 | ) |
| 756 | }); |
| 757 | |
| 758 | match instruction { |
| 759 | Bytecode::Pop => { |
| 760 | gas_status.charge_instr(Opcodes::POP)?; |
| 761 | interpreter.operand_stack.pop()?; |
| 762 | } |
| 763 | Bytecode::Ret => { |
| 764 | gas_status.charge_instr(Opcodes::RET)?; |
| 765 | return Ok(ExitCode::Return); |
| 766 | } |
| 767 | Bytecode::BrTrue(offset) => { |
| 768 | gas_status.charge_instr(Opcodes::BR_TRUE)?; |
| 769 | if interpreter.operand_stack.pop_as::<bool>()? { |
| 770 | self.pc = *offset; |
| 771 | break; |
| 772 | } |
| 773 | } |
| 774 | Bytecode::BrFalse(offset) => { |
| 775 | gas_status.charge_instr(Opcodes::BR_FALSE)?; |
| 776 | if !interpreter.operand_stack.pop_as::<bool>()? { |
| 777 | self.pc = *offset; |
| 778 | break; |
| 779 | } |
| 780 | } |
| 781 | Bytecode::Branch(offset) => { |
| 782 | gas_status.charge_instr(Opcodes::BRANCH)?; |
| 783 | self.pc = *offset; |
| 784 | break; |
| 785 | } |
| 786 | Bytecode::LdU8(int_const) => { |
| 787 | gas_status.charge_instr(Opcodes::LD_U8)?; |
| 788 | interpreter.operand_stack.push(Value::u8(*int_const))?; |
no test coverage detected