diff --git a/bindings/rust/evmc-declare/src/lib.rs b/bindings/rust/evmc-declare/src/lib.rs index 2c9398a..4821a56 100644 --- a/bindings/rust/evmc-declare/src/lib.rs +++ b/bindings/rust/evmc-declare/src/lib.rs @@ -337,40 +337,34 @@ fn build_execute_fn(names: &VMNameSet) -> proc_macro2::TokenStream { { use evmc_vm::EvmcVm; + assert!(!instance.is_null()); + // TODO: context is optional in case of the "precompiles" capability + assert!(!context.is_null()); + assert!(!msg.is_null()); + + let execution_message: ::evmc_vm::ExecutionMessage = unsafe { + msg.as_ref().expect("EVMC message is null").into() + }; + + let empty_code = [0u8;0]; + let code_ref: &[u8] = if code.is_null() { + assert_eq!(code_size, 0); + &empty_code + } else { + unsafe { + ::std::slice::from_raw_parts(code, code_size) + } + }; + + let container = unsafe { + ::evmc_vm::EvmcContainer::<#type_name_ident>::from_ffi_pointer(instance) + }; + let result = ::std::panic::catch_unwind(|| { - assert!(!instance.is_null()); - // TODO: context is optional in case of the "precompiles" capability - assert!(!context.is_null()); - assert!(!msg.is_null()); - - let execution_message: ::evmc_vm::ExecutionMessage = unsafe { - msg.as_ref().expect("EVMC message is null").into() - }; - - let empty_code = [0u8;0]; - let code_ref: &[u8] = if code.is_null() { - assert_eq!(code_size, 0); - &empty_code - } else { - unsafe { - ::std::slice::from_raw_parts(code, code_size) - } - }; - - let container = unsafe { - ::evmc_vm::EvmcContainer::<#type_name_ident>::from_ffi_pointer(instance) - }; - let mut execution_context = unsafe { ::evmc_vm::ExecutionContext::new(context.as_mut().expect("EVMC context is null")) }; - let result = container.execute(revision, code_ref, &execution_message, &mut execution_context); - - unsafe { - ::evmc_vm::EvmcContainer::into_ffi_pointer(container); - } - - result + container.execute(revision, code_ref, &execution_message, &mut execution_context) }); let result = if result.is_err() { @@ -380,6 +374,10 @@ fn build_execute_fn(names: &VMNameSet) -> proc_macro2::TokenStream { result.unwrap() }; + unsafe { + ::evmc_vm::EvmcContainer::into_ffi_pointer(container); + } + result.into() } }