sui_adapter_latest/
error.rsuse move_binary_format::{
errors::{Location, VMError},
file_format::FunctionDefinitionIndex,
};
use move_core_types::{
language_storage::ModuleId,
vm_status::{StatusCode, StatusType},
};
use sui_types::error::ExecutionError;
use sui_types::execution_status::{ExecutionFailureStatus, MoveLocation, MoveLocationOpt};
pub(crate) fn convert_vm_error_impl(
error: VMError,
abort_module_id_relocation_fn: &impl Fn(&ModuleId) -> ModuleId,
function_name_resolution_fn: &impl Fn(&ModuleId, FunctionDefinitionIndex) -> Option<String>,
) -> ExecutionError {
let kind = match (error.major_status(), error.sub_status(), error.location()) {
(StatusCode::EXECUTED, _, _) => {
debug_assert!(false, "VmError shouldn't ever report successful execution");
ExecutionFailureStatus::VMInvariantViolation
}
(StatusCode::ABORTED, None, _) => {
debug_assert!(false, "No abort code");
ExecutionFailureStatus::VMInvariantViolation
}
(StatusCode::ABORTED, Some(code), Location::Module(id)) => {
let abort_location_id = abort_module_id_relocation_fn(id);
let offset = error.offsets().first().copied().map(|(f, i)| (f.0, i));
debug_assert!(offset.is_some(), "Move should set the location on aborts");
let (function, instruction) = offset.unwrap_or((0, 0));
let function_name = function_name_resolution_fn(id, FunctionDefinitionIndex(function));
ExecutionFailureStatus::MoveAbort(
MoveLocation {
module: abort_location_id,
function,
instruction,
function_name,
},
code,
)
}
(StatusCode::OUT_OF_GAS, _, _) => ExecutionFailureStatus::InsufficientGas,
(_, _, location) => match error.major_status().status_type() {
StatusType::Execution => {
debug_assert!(error.major_status() != StatusCode::ABORTED);
let location = match location {
Location::Module(id) => {
let offset = error.offsets().first().copied().map(|(f, i)| (f.0, i));
debug_assert!(
offset.is_some(),
"Move should set the location on all execution errors. Error {error}"
);
let (function, instruction) = offset.unwrap_or((0, 0));
let function_name =
function_name_resolution_fn(id, FunctionDefinitionIndex(function));
Some(MoveLocation {
module: id.clone(),
function,
instruction,
function_name,
})
}
_ => None,
};
ExecutionFailureStatus::MovePrimitiveRuntimeError(MoveLocationOpt(location))
}
StatusType::Validation
| StatusType::Verification
| StatusType::Deserialization
| StatusType::Unknown => ExecutionFailureStatus::VMVerificationOrDeserializationError,
StatusType::InvariantViolation => ExecutionFailureStatus::VMInvariantViolation,
},
};
ExecutionError::new_with_source(kind, error)
}