(
current_function_opt: Option<FunctionDefinitionIndex>,
code: &CodeUnit,
)
| 14 | use std::{collections::HashSet, convert::TryInto}; |
| 15 | |
| 16 | pub fn verify( |
| 17 | current_function_opt: Option<FunctionDefinitionIndex>, |
| 18 | code: &CodeUnit, |
| 19 | ) -> PartialVMResult<()> { |
| 20 | let current_function = current_function_opt.unwrap_or(FunctionDefinitionIndex(0)); |
| 21 | // check fall through |
| 22 | // Check to make sure that the bytecode vector ends with a branching instruction. |
| 23 | match code.code.last() { |
| 24 | None => return Err(PartialVMError::new(StatusCode::EMPTY_CODE_UNIT)), |
| 25 | Some(last) if !last.is_unconditional_branch() => { |
| 26 | return Err(PartialVMError::new(StatusCode::INVALID_FALL_THROUGH) |
| 27 | .at_code_offset(current_function, (code.code.len() - 1) as CodeOffset)) |
| 28 | } |
| 29 | Some(_) => (), |
| 30 | } |
| 31 | |
| 32 | // check jumps |
| 33 | let context = &ControlFlowVerifier { |
| 34 | current_function, |
| 35 | code: &code.code, |
| 36 | }; |
| 37 | let labels = instruction_labels(context); |
| 38 | check_jumps(context, labels) |
| 39 | } |
| 40 | |
| 41 | #[derive(Clone, Copy)] |
| 42 | enum Label { |
nothing calls this directly
no test coverage detected