diff --git a/Cargo.lock b/Cargo.lock index 0456cba83..f13ded0da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1409,6 +1409,7 @@ dependencies = [ "buddy_system_allocator", "cc", "cfg-if", + "flatbuffers", "glob", "hyperlight-common", "hyperlight-guest", @@ -1530,6 +1531,7 @@ name = "hyperlight_guest_capi" version = "0.9.0" dependencies = [ "cbindgen", + "flatbuffers", "hyperlight-common", "hyperlight-guest", "hyperlight-guest-bin", diff --git a/Justfile b/Justfile index f0cb57a5c..ac664c72a 100644 --- a/Justfile +++ b/Justfile @@ -372,7 +372,7 @@ build-fuzzer fuzz-target: ################### gen-all-fbs-rust-code: - for fbs in `find src -name "*.fbs"`; do flatc -r --rust-module-root-file --gen-all -o ./src/hyperlight_common/src/flatbuffers/ $fbs; done + flatc --rust --rust-module-root-file --gen-all -o ./src/hyperlight_common/src/flatbuffers/ ./src/schema/all.fbs just fmt-apply install-vcpkg: diff --git a/docs/how-to-use-flatbuffers.md b/docs/how-to-use-flatbuffers.md index dc26b58c7..c541b0406 100644 --- a/docs/how-to-use-flatbuffers.md +++ b/docs/how-to-use-flatbuffers.md @@ -1,6 +1,6 @@ # How to use FlatBuffers -> Note: the last generation of the flatbuffer code was with done with flatc version 25.2.10 (i.e., the last version as of May 1st, 2025). +> Note: the last generation of the flatbuffer code was with done with flatc version 25.9.23 (i.e., the last version as of Oct 2nd, 2025). Flatbuffers is used to serialize and deserialize some data structures. @@ -19,9 +19,3 @@ We recommend building `flatc` from source. To generate rust code, use ```console just gen-all-fbs-rust-code ``` - -### Note about generated code - -Because we invoke `flatc` multiple times when generating the Rust code, the `mod.rs` generated in `./src/hyperlight_common/src/flatbuffers` is overwritten multiple times and will likely be incorrect. Make sure to manually inspect and if necessary update this file before continuing with your changes as certain modules might be missing. After fixing `mod.rs`, you might need to re-run `just fmt`, since it might not have applied to all generated files if your `mod.rs` was invalid. - ->`flatc` does support passing multiple schema files (e.g. it is possible to pass `.\src\schema\*.fbs`), so we could regenerate all the files each time a change was made, however that generates incorrect code (see [here](https://github.com/google/flatbuffers/issues/6800) for details). diff --git a/src/hyperlight_common/src/flatbuffer_wrappers/function_types.rs b/src/hyperlight_common/src/flatbuffer_wrappers/function_types.rs index 16bd91bc0..42c7ff823 100644 --- a/src/hyperlight_common/src/flatbuffer_wrappers/function_types.rs +++ b/src/hyperlight_common/src/flatbuffer_wrappers/function_types.rs @@ -22,15 +22,166 @@ use flatbuffers::size_prefixed_root; #[cfg(feature = "tracing")] use tracing::{Span, instrument}; +use super::guest_error::GuestError; use crate::flatbuffers::hyperlight::generated::{ FunctionCallResult as FbFunctionCallResult, FunctionCallResultArgs as FbFunctionCallResultArgs, - Parameter, ParameterType as FbParameterType, ParameterValue as FbParameterValue, - ReturnType as FbReturnType, ReturnValue as FbReturnValue, hlbool, hlboolArgs, hldouble, - hldoubleArgs, hlfloat, hlfloatArgs, hlint, hlintArgs, hllong, hllongArgs, hlsizeprefixedbuffer, + FunctionCallResultType, Parameter, ParameterType as FbParameterType, + ParameterValue as FbParameterValue, ReturnType as FbReturnType, ReturnValue as FbReturnValue, + ReturnValueBox, ReturnValueBoxArgs, hlbool, hlboolArgs, hldouble, hldoubleArgs, hlfloat, + hlfloatArgs, hlint, hlintArgs, hllong, hllongArgs, hlsizeprefixedbuffer, hlsizeprefixedbufferArgs, hlstring, hlstringArgs, hluint, hluintArgs, hlulong, hlulongArgs, hlvoid, hlvoidArgs, }; +pub struct FunctionCallResult(core::result::Result); + +impl FunctionCallResult { + /// Encodes self into the given builder and returns the encoded data. + /// + /// # Notes + /// + /// The builder should not be reused after a call to encode, since this function + /// does not reset the state of the builder. If you want to reuse the builder, + /// you'll need to reset it first. + pub fn encode<'a>(&self, builder: &'a mut flatbuffers::FlatBufferBuilder) -> &'a [u8] { + match &self.0 { + Ok(rv) => { + // Encode ReturnValue as ReturnValueBox + let (value, value_type) = match rv { + ReturnValue::Int(i) => { + let off = hlint::create(builder, &hlintArgs { value: *i }); + (Some(off.as_union_value()), FbReturnValue::hlint) + } + ReturnValue::UInt(ui) => { + let off = hluint::create(builder, &hluintArgs { value: *ui }); + (Some(off.as_union_value()), FbReturnValue::hluint) + } + ReturnValue::Long(l) => { + let off = hllong::create(builder, &hllongArgs { value: *l }); + (Some(off.as_union_value()), FbReturnValue::hllong) + } + ReturnValue::ULong(ul) => { + let off = hlulong::create(builder, &hlulongArgs { value: *ul }); + (Some(off.as_union_value()), FbReturnValue::hlulong) + } + ReturnValue::Float(f) => { + let off = hlfloat::create(builder, &hlfloatArgs { value: *f }); + (Some(off.as_union_value()), FbReturnValue::hlfloat) + } + ReturnValue::Double(d) => { + let off = hldouble::create(builder, &hldoubleArgs { value: *d }); + (Some(off.as_union_value()), FbReturnValue::hldouble) + } + ReturnValue::Bool(b) => { + let off = hlbool::create(builder, &hlboolArgs { value: *b }); + (Some(off.as_union_value()), FbReturnValue::hlbool) + } + ReturnValue::String(s) => { + let val = builder.create_string(s.as_str()); + let off = hlstring::create(builder, &hlstringArgs { value: Some(val) }); + (Some(off.as_union_value()), FbReturnValue::hlstring) + } + ReturnValue::VecBytes(v) => { + let val = builder.create_vector(v); + let off = hlsizeprefixedbuffer::create( + builder, + &hlsizeprefixedbufferArgs { + value: Some(val), + size: v.len() as i32, + }, + ); + ( + Some(off.as_union_value()), + FbReturnValue::hlsizeprefixedbuffer, + ) + } + ReturnValue::Void(()) => { + let off = hlvoid::create(builder, &hlvoidArgs {}); + (Some(off.as_union_value()), FbReturnValue::hlvoid) + } + }; + let rv_box = + ReturnValueBox::create(builder, &ReturnValueBoxArgs { value, value_type }); + let fcr = FbFunctionCallResult::create( + builder, + &FbFunctionCallResultArgs { + result: Some(rv_box.as_union_value()), + result_type: FunctionCallResultType::ReturnValueBox, + }, + ); + builder.finish_size_prefixed(fcr, None); + builder.finished_data() + } + Err(ge) => { + // Encode GuestError + let code: crate::flatbuffers::hyperlight::generated::ErrorCode = ge.code.into(); + let msg = builder.create_string(&ge.message); + let guest_error = crate::flatbuffers::hyperlight::generated::GuestError::create( + builder, + &crate::flatbuffers::hyperlight::generated::GuestErrorArgs { + code, + message: Some(msg), + }, + ); + let fcr = FbFunctionCallResult::create( + builder, + &FbFunctionCallResultArgs { + result: Some(guest_error.as_union_value()), + result_type: FunctionCallResultType::GuestError, + }, + ); + builder.finish_size_prefixed(fcr, None); + builder.finished_data() + } + } + } + pub fn new(value: core::result::Result) -> Self { + FunctionCallResult(value) + } + + pub fn into_inner(self) -> core::result::Result { + self.0 + } +} + +impl TryFrom<&[u8]> for FunctionCallResult { + type Error = Error; + + fn try_from(value: &[u8]) -> Result { + let function_call_result_fb = size_prefixed_root::(value) + .map_err(|e| anyhow!("Failed to get FunctionCallResult from bytes: {:?}", e))?; + + match function_call_result_fb.result_type() { + FunctionCallResultType::ReturnValueBox => { + let boxed = function_call_result_fb + .result_as_return_value_box() + .ok_or_else(|| { + anyhow!("Failed to get ReturnValueBox from function call result") + })?; + let return_value = ReturnValue::try_from(boxed)?; + Ok(FunctionCallResult(Ok(return_value))) + } + FunctionCallResultType::GuestError => { + let guest_error_table = function_call_result_fb + .result_as_guest_error() + .ok_or_else(|| anyhow!("Failed to get GuestError from function call result"))?; + let code = guest_error_table.code(); + let message = guest_error_table + .message() + .map(|s| s.to_string()) + .unwrap_or_default(); + Ok(FunctionCallResult(Err(GuestError::new( + code.into(), + message, + )))) + } + other => { + bail!("Unexpected function call result type: {:?}", other) + } + } + } +} + /// Supported parameter types with values for function calling. #[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))] #[derive(Debug, Clone, PartialEq)] @@ -516,55 +667,55 @@ impl TryFrom for () { } } -impl TryFrom> for ReturnValue { +impl TryFrom> for ReturnValue { type Error = Error; #[cfg_attr(feature = "tracing", instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace"))] - fn try_from(function_call_result_fb: FbFunctionCallResult<'_>) -> Result { - match function_call_result_fb.return_value_type() { + fn try_from(return_value_box: ReturnValueBox<'_>) -> Result { + match return_value_box.value_type() { FbReturnValue::hlint => { - let hlint = function_call_result_fb - .return_value_as_hlint() + let hlint = return_value_box + .value_as_hlint() .ok_or_else(|| anyhow!("Failed to get hlint from return value"))?; Ok(ReturnValue::Int(hlint.value())) } FbReturnValue::hluint => { - let hluint = function_call_result_fb - .return_value_as_hluint() + let hluint = return_value_box + .value_as_hluint() .ok_or_else(|| anyhow!("Failed to get hluint from return value"))?; Ok(ReturnValue::UInt(hluint.value())) } FbReturnValue::hllong => { - let hllong = function_call_result_fb - .return_value_as_hllong() + let hllong = return_value_box + .value_as_hllong() .ok_or_else(|| anyhow!("Failed to get hllong from return value"))?; Ok(ReturnValue::Long(hllong.value())) } FbReturnValue::hlulong => { - let hlulong = function_call_result_fb - .return_value_as_hlulong() + let hlulong = return_value_box + .value_as_hlulong() .ok_or_else(|| anyhow!("Failed to get hlulong from return value"))?; Ok(ReturnValue::ULong(hlulong.value())) } FbReturnValue::hlfloat => { - let hlfloat = function_call_result_fb - .return_value_as_hlfloat() + let hlfloat = return_value_box + .value_as_hlfloat() .ok_or_else(|| anyhow!("Failed to get hlfloat from return value"))?; Ok(ReturnValue::Float(hlfloat.value())) } FbReturnValue::hldouble => { - let hldouble = function_call_result_fb - .return_value_as_hldouble() + let hldouble = return_value_box + .value_as_hldouble() .ok_or_else(|| anyhow!("Failed to get hldouble from return value"))?; Ok(ReturnValue::Double(hldouble.value())) } FbReturnValue::hlbool => { - let hlbool = function_call_result_fb - .return_value_as_hlbool() + let hlbool = return_value_box + .value_as_hlbool() .ok_or_else(|| anyhow!("Failed to get hlbool from return value"))?; Ok(ReturnValue::Bool(hlbool.value())) } FbReturnValue::hlstring => { - let hlstring = match function_call_result_fb.return_value_as_hlstring() { + let hlstring = match return_value_box.value_as_hlstring() { Some(hlstring) => hlstring.value().map(|v| v.to_string()), None => None, }; @@ -572,13 +723,12 @@ impl TryFrom> for ReturnValue { } FbReturnValue::hlvoid => Ok(ReturnValue::Void(())), FbReturnValue::hlsizeprefixedbuffer => { - let hlvecbytes = - match function_call_result_fb.return_value_as_hlsizeprefixedbuffer() { - Some(hlvecbytes) => hlvecbytes - .value() - .map(|val| val.iter().collect::>()), - None => None, - }; + let hlvecbytes = match return_value_box.value_as_hlsizeprefixedbuffer() { + Some(hlvecbytes) => hlvecbytes + .value() + .map(|val| val.iter().collect::>()), + None => None, + }; Ok(ReturnValue::VecBytes(hlvecbytes.unwrap_or(Vec::new()))) } other => { @@ -588,123 +738,169 @@ impl TryFrom> for ReturnValue { } } -impl TryFrom<&[u8]> for ReturnValue { - type Error = Error; - #[cfg_attr(feature = "tracing", instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace"))] - fn try_from(value: &[u8]) -> Result { - let function_call_result_fb = size_prefixed_root::(value) - .map_err(|e| anyhow!("Failed to get ReturnValue from bytes: {:?}", e))?; - function_call_result_fb.try_into() - } -} - impl TryFrom<&ReturnValue> for Vec { type Error = Error; #[cfg_attr(feature = "tracing", instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace"))] fn try_from(value: &ReturnValue) -> Result> { let mut builder = flatbuffers::FlatBufferBuilder::new(); - let result = match value { + let result_bytes = match value { ReturnValue::Int(i) => { - let hlint = hlint::create(&mut builder, &hlintArgs { value: *i }); - let function_call_result = FbFunctionCallResult::create( + let hlint_off = hlint::create(&mut builder, &hlintArgs { value: *i }); + let rv_box = ReturnValueBox::create( + &mut builder, + &ReturnValueBoxArgs { + value: Some(hlint_off.as_union_value()), + value_type: FbReturnValue::hlint, + }, + ); + let fcr = FbFunctionCallResult::create( &mut builder, &FbFunctionCallResultArgs { - return_value: Some(hlint.as_union_value()), - return_value_type: FbReturnValue::hlint, + result: Some(rv_box.as_union_value()), + result_type: FunctionCallResultType::ReturnValueBox, }, ); - builder.finish_size_prefixed(function_call_result, None); + builder.finish_size_prefixed(fcr, None); builder.finished_data().to_vec() } ReturnValue::UInt(ui) => { - let hluint = hluint::create(&mut builder, &hluintArgs { value: *ui }); - let function_call_result = FbFunctionCallResult::create( + let off = hluint::create(&mut builder, &hluintArgs { value: *ui }); + let rv_box = ReturnValueBox::create( + &mut builder, + &ReturnValueBoxArgs { + value: Some(off.as_union_value()), + value_type: FbReturnValue::hluint, + }, + ); + let fcr = FbFunctionCallResult::create( &mut builder, &FbFunctionCallResultArgs { - return_value: Some(hluint.as_union_value()), - return_value_type: FbReturnValue::hluint, + result: Some(rv_box.as_union_value()), + result_type: FunctionCallResultType::ReturnValueBox, }, ); - builder.finish_size_prefixed(function_call_result, None); + builder.finish_size_prefixed(fcr, None); builder.finished_data().to_vec() } ReturnValue::Long(l) => { - let hllong = hllong::create(&mut builder, &hllongArgs { value: *l }); - let function_call_result = FbFunctionCallResult::create( + let off = hllong::create(&mut builder, &hllongArgs { value: *l }); + let rv_box = ReturnValueBox::create( + &mut builder, + &ReturnValueBoxArgs { + value: Some(off.as_union_value()), + value_type: FbReturnValue::hllong, + }, + ); + let fcr = FbFunctionCallResult::create( &mut builder, &FbFunctionCallResultArgs { - return_value: Some(hllong.as_union_value()), - return_value_type: FbReturnValue::hllong, + result: Some(rv_box.as_union_value()), + result_type: FunctionCallResultType::ReturnValueBox, }, ); - builder.finish_size_prefixed(function_call_result, None); + builder.finish_size_prefixed(fcr, None); builder.finished_data().to_vec() } ReturnValue::ULong(ul) => { - let hlulong = hlulong::create(&mut builder, &hlulongArgs { value: *ul }); - let function_call_result = FbFunctionCallResult::create( + let off = hlulong::create(&mut builder, &hlulongArgs { value: *ul }); + let rv_box = ReturnValueBox::create( + &mut builder, + &ReturnValueBoxArgs { + value: Some(off.as_union_value()), + value_type: FbReturnValue::hlulong, + }, + ); + let fcr = FbFunctionCallResult::create( &mut builder, &FbFunctionCallResultArgs { - return_value: Some(hlulong.as_union_value()), - return_value_type: FbReturnValue::hlulong, + result: Some(rv_box.as_union_value()), + result_type: FunctionCallResultType::ReturnValueBox, }, ); - builder.finish_size_prefixed(function_call_result, None); + builder.finish_size_prefixed(fcr, None); builder.finished_data().to_vec() } ReturnValue::Float(f) => { - let hlfloat = hlfloat::create(&mut builder, &hlfloatArgs { value: *f }); - let function_call_result = FbFunctionCallResult::create( + let off = hlfloat::create(&mut builder, &hlfloatArgs { value: *f }); + let rv_box = ReturnValueBox::create( + &mut builder, + &ReturnValueBoxArgs { + value: Some(off.as_union_value()), + value_type: FbReturnValue::hlfloat, + }, + ); + let fcr = FbFunctionCallResult::create( &mut builder, &FbFunctionCallResultArgs { - return_value: Some(hlfloat.as_union_value()), - return_value_type: FbReturnValue::hlfloat, + result: Some(rv_box.as_union_value()), + result_type: FunctionCallResultType::ReturnValueBox, }, ); - builder.finish_size_prefixed(function_call_result, None); + builder.finish_size_prefixed(fcr, None); builder.finished_data().to_vec() } ReturnValue::Double(d) => { - let hldouble = hldouble::create(&mut builder, &hldoubleArgs { value: *d }); - let function_call_result = FbFunctionCallResult::create( + let off = hldouble::create(&mut builder, &hldoubleArgs { value: *d }); + let rv_box = ReturnValueBox::create( + &mut builder, + &ReturnValueBoxArgs { + value: Some(off.as_union_value()), + value_type: FbReturnValue::hldouble, + }, + ); + let fcr = FbFunctionCallResult::create( &mut builder, &FbFunctionCallResultArgs { - return_value: Some(hldouble.as_union_value()), - return_value_type: FbReturnValue::hldouble, + result: Some(rv_box.as_union_value()), + result_type: FunctionCallResultType::ReturnValueBox, }, ); - builder.finish_size_prefixed(function_call_result, None); + builder.finish_size_prefixed(fcr, None); builder.finished_data().to_vec() } ReturnValue::Bool(b) => { - let hlbool = hlbool::create(&mut builder, &hlboolArgs { value: *b }); - let function_call_result = FbFunctionCallResult::create( + let off = hlbool::create(&mut builder, &hlboolArgs { value: *b }); + let rv_box = ReturnValueBox::create( + &mut builder, + &ReturnValueBoxArgs { + value: Some(off.as_union_value()), + value_type: FbReturnValue::hlbool, + }, + ); + let fcr = FbFunctionCallResult::create( &mut builder, &FbFunctionCallResultArgs { - return_value: Some(hlbool.as_union_value()), - return_value_type: FbReturnValue::hlbool, + result: Some(rv_box.as_union_value()), + result_type: FunctionCallResultType::ReturnValueBox, }, ); - builder.finish_size_prefixed(function_call_result, None); + builder.finish_size_prefixed(fcr, None); builder.finished_data().to_vec() } ReturnValue::String(s) => { - let hlstring = { + let off = { let val = builder.create_string(s.as_str()); hlstring::create(&mut builder, &hlstringArgs { value: Some(val) }) }; - let function_call_result = FbFunctionCallResult::create( + let rv_box = ReturnValueBox::create( + &mut builder, + &ReturnValueBoxArgs { + value: Some(off.as_union_value()), + value_type: FbReturnValue::hlstring, + }, + ); + let fcr = FbFunctionCallResult::create( &mut builder, &FbFunctionCallResultArgs { - return_value: Some(hlstring.as_union_value()), - return_value_type: FbReturnValue::hlstring, + result: Some(rv_box.as_union_value()), + result_type: FunctionCallResultType::ReturnValueBox, }, ); - builder.finish_size_prefixed(function_call_result, None); + builder.finish_size_prefixed(fcr, None); builder.finished_data().to_vec() } ReturnValue::VecBytes(v) => { - let hlvecbytes = { + let off = { let val = builder.create_vector(v.as_slice()); hlsizeprefixedbuffer::create( &mut builder, @@ -714,30 +910,77 @@ impl TryFrom<&ReturnValue> for Vec { }, ) }; - let function_call_result = FbFunctionCallResult::create( + let rv_box = ReturnValueBox::create( + &mut builder, + &ReturnValueBoxArgs { + value: Some(off.as_union_value()), + value_type: FbReturnValue::hlsizeprefixedbuffer, + }, + ); + let fcr = FbFunctionCallResult::create( &mut builder, &FbFunctionCallResultArgs { - return_value: Some(hlvecbytes.as_union_value()), - return_value_type: FbReturnValue::hlsizeprefixedbuffer, + result: Some(rv_box.as_union_value()), + result_type: FunctionCallResultType::ReturnValueBox, }, ); - builder.finish_size_prefixed(function_call_result, None); + builder.finish_size_prefixed(fcr, None); builder.finished_data().to_vec() } ReturnValue::Void(()) => { - let hlvoid = hlvoid::create(&mut builder, &hlvoidArgs {}); - let function_call_result = FbFunctionCallResult::create( + let off = hlvoid::create(&mut builder, &hlvoidArgs {}); + let rv_box = ReturnValueBox::create( + &mut builder, + &ReturnValueBoxArgs { + value: Some(off.as_union_value()), + value_type: FbReturnValue::hlvoid, + }, + ); + let fcr = FbFunctionCallResult::create( &mut builder, &FbFunctionCallResultArgs { - return_value: Some(hlvoid.as_union_value()), - return_value_type: FbReturnValue::hlvoid, + result: Some(rv_box.as_union_value()), + result_type: FunctionCallResultType::ReturnValueBox, }, ); - builder.finish_size_prefixed(function_call_result, None); + builder.finish_size_prefixed(fcr, None); builder.finished_data().to_vec() } }; - Ok(result) + Ok(result_bytes) + } +} + +#[cfg(test)] +mod tests { + use flatbuffers::FlatBufferBuilder; + + use super::super::guest_error::ErrorCode; + use super::*; + + #[test] + fn encode_success_result() { + let mut builder = FlatBufferBuilder::new(); + let test_data = FunctionCallResult::new(Ok(ReturnValue::Int(42))).encode(&mut builder); + + let function_call_result = FunctionCallResult::try_from(test_data).unwrap(); + let result = function_call_result.into_inner().unwrap(); + assert_eq!(result, ReturnValue::Int(42)); + } + + #[test] + fn encode_error_result() { + let mut builder = FlatBufferBuilder::new(); + let test_error = GuestError::new( + ErrorCode::GuestFunctionNotFound, + "Function not found".to_string(), + ); + let test_data = FunctionCallResult::new(Err(test_error.clone())).encode(&mut builder); + + let function_call_result = FunctionCallResult::try_from(test_data).unwrap(); + let error = function_call_result.into_inner().unwrap_err(); + assert_eq!(error.code, test_error.code); + assert_eq!(error.message, test_error.message); } } diff --git a/src/hyperlight_common/src/flatbuffer_wrappers/guest_error.rs b/src/hyperlight_common/src/flatbuffer_wrappers/guest_error.rs index 289ae48b4..b3d1f457e 100644 --- a/src/hyperlight_common/src/flatbuffer_wrappers/guest_error.rs +++ b/src/hyperlight_common/src/flatbuffer_wrappers/guest_error.rs @@ -17,16 +17,11 @@ limitations under the License. extern crate flatbuffers; use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use anyhow::{Error, Result}; -use flatbuffers::size_prefixed_root; #[cfg(feature = "tracing")] use tracing::{Span, instrument}; -use crate::flatbuffers::hyperlight::generated::{ - ErrorCode as FbErrorCode, GuestError as FbGuestError, GuestErrorArgs, -}; +use crate::flatbuffers::hyperlight::generated::ErrorCode as FbErrorCode; #[derive(Debug, Clone, Copy, Eq, PartialEq)] #[repr(C)] @@ -48,6 +43,7 @@ pub enum ErrorCode { GuestFunctionParameterTypeMismatch = 14, GuestError = 15, ArrayLengthParamIsMissing = 16, + HostFunctionError = 17, } impl From for FbErrorCode { @@ -73,6 +69,7 @@ impl From for FbErrorCode { } ErrorCode::GuestError => Self::GuestError, ErrorCode::ArrayLengthParamIsMissing => Self::ArrayLengthParamIsMissing, + ErrorCode::HostFunctionError => Self::HostError, } } } @@ -99,6 +96,7 @@ impl From for ErrorCode { } FbErrorCode::GuestError => Self::GuestError, FbErrorCode::ArrayLengthParamIsMissing => Self::ArrayLengthParamIsMissing, + FbErrorCode::HostError => Self::HostFunctionError, _ => Self::UnknownError, } } @@ -123,6 +121,7 @@ impl From for ErrorCode { 14 => Self::GuestFunctionParameterTypeMismatch, 15 => Self::GuestError, 16 => Self::ArrayLengthParamIsMissing, + 17 => Self::HostFunctionError, _ => Self::UnknownError, } } @@ -147,6 +146,7 @@ impl From for u64 { ErrorCode::GuestFunctionParameterTypeMismatch => 14, ErrorCode::GuestError => 15, ErrorCode::ArrayLengthParamIsMissing => 16, + ErrorCode::HostFunctionError => 17, } } } @@ -174,6 +174,7 @@ impl From for String { } ErrorCode::GuestError => "GuestError".to_string(), ErrorCode::ArrayLengthParamIsMissing => "ArrayLengthParamIsMissing".to_string(), + ErrorCode::HostFunctionError => "HostFunctionError".to_string(), } } } @@ -194,44 +195,6 @@ impl GuestError { } } -impl TryFrom<&[u8]> for GuestError { - type Error = Error; - fn try_from(value: &[u8]) -> Result { - let guest_error_fb = size_prefixed_root::(value) - .map_err(|e| anyhow::anyhow!("Error while reading GuestError: {:?}", e))?; - let code = guest_error_fb.code(); - let message = match guest_error_fb.message() { - Some(message) => message.to_string(), - None => String::new(), - }; - Ok(Self { - code: code.into(), - message, - }) - } -} - -impl TryFrom<&GuestError> for Vec { - type Error = Error; - #[cfg_attr(feature = "tracing", instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace"))] - fn try_from(value: &GuestError) -> Result> { - let mut builder = flatbuffers::FlatBufferBuilder::new(); - let message = builder.create_string(&value.message); - - let guest_error_fb = FbGuestError::create( - &mut builder, - &GuestErrorArgs { - code: value.code.into(), - message: Some(message), - }, - ); - builder.finish_size_prefixed(guest_error_fb, None); - let res = builder.finished_data().to_vec(); - - Ok(res) - } -} - impl Default for GuestError { #[cfg_attr(feature = "tracing", instrument(parent = Span::current(), level= "Trace"))] fn default() -> Self { diff --git a/src/hyperlight_common/src/flatbuffer_wrappers/util.rs b/src/hyperlight_common/src/flatbuffer_wrappers/util.rs index 96ab16f1e..f1ce3de02 100644 --- a/src/hyperlight_common/src/flatbuffer_wrappers/util.rs +++ b/src/hyperlight_common/src/flatbuffer_wrappers/util.rs @@ -21,7 +21,8 @@ use flatbuffers::FlatBufferBuilder; use crate::flatbuffer_wrappers::function_types::ParameterValue; use crate::flatbuffers::hyperlight::generated::{ FunctionCallResult as FbFunctionCallResult, FunctionCallResultArgs as FbFunctionCallResultArgs, - ReturnValue as FbReturnValue, hlbool as Fbhlbool, hlboolArgs as FbhlboolArgs, + FunctionCallResultType as FbFunctionCallResultType, ReturnValue as FbReturnValue, + ReturnValueBox, ReturnValueBoxArgs, hlbool as Fbhlbool, hlboolArgs as FbhlboolArgs, hldouble as Fbhldouble, hldoubleArgs as FbhldoubleArgs, hlfloat as Fbhlfloat, hlfloatArgs as FbhlfloatArgs, hlint as Fbhlint, hlintArgs as FbhlintArgs, hllong as Fbhllong, hllongArgs as FbhllongArgs, hlsizeprefixedbuffer as Fbhlsizeprefixedbuffer, @@ -34,8 +35,8 @@ use crate::flatbuffers::hyperlight::generated::{ /// Flatbuffer-encodes the given value pub fn get_flatbuffer_result(val: T) -> Vec { let mut builder = FlatBufferBuilder::new(); - let res = &T::serialize(&val, &mut builder); - let result_offset = FbFunctionCallResult::create(&mut builder, res); + let res = T::serialize(&val, &mut builder); + let result_offset = FbFunctionCallResult::create(&mut builder, &res); builder.finish_size_prefixed(result_offset, None); @@ -50,9 +51,17 @@ pub trait FlatbufferSerializable { impl FlatbufferSerializable for () { fn serialize(&self, builder: &mut FlatBufferBuilder) -> FbFunctionCallResultArgs { + let void_off = Fbhlvoid::create(builder, &FbhlvoidArgs {}); + let rv_box = ReturnValueBox::create( + builder, + &ReturnValueBoxArgs { + value_type: FbReturnValue::hlvoid, + value: Some(void_off.as_union_value()), + }, + ); FbFunctionCallResultArgs { - return_value: Some(Fbhlvoid::create(builder, &FbhlvoidArgs {}).as_union_value()), - return_value_type: FbReturnValue::hlvoid, + result_type: FbFunctionCallResultType::ReturnValueBox, + result: Some(rv_box.as_union_value()), } } } @@ -60,113 +69,165 @@ impl FlatbufferSerializable for () { impl FlatbufferSerializable for &str { fn serialize(&self, builder: &mut FlatBufferBuilder) -> FbFunctionCallResultArgs { let string_offset = builder.create_string(self); + let str_off = Fbhlstring::create( + builder, + &FbhlstringArgs { + value: Some(string_offset), + }, + ); + let rv_box = ReturnValueBox::create( + builder, + &ReturnValueBoxArgs { + value_type: FbReturnValue::hlstring, + value: Some(str_off.as_union_value()), + }, + ); FbFunctionCallResultArgs { - return_value: Some( - Fbhlstring::create( - builder, - &FbhlstringArgs { - value: Some(string_offset), - }, - ) - .as_union_value(), - ), - return_value_type: FbReturnValue::hlstring, + result_type: FbFunctionCallResultType::ReturnValueBox, + result: Some(rv_box.as_union_value()), } } } impl FlatbufferSerializable for &[u8] { fn serialize(&self, builder: &mut FlatBufferBuilder) -> FbFunctionCallResultArgs { - let vec_offset = builder.create_vector(self); + let vec_off = builder.create_vector(self); + let buf_off = Fbhlsizeprefixedbuffer::create( + builder, + &FbhlsizeprefixedbufferArgs { + size: self.len() as i32, + value: Some(vec_off), + }, + ); + let rv_box = ReturnValueBox::create( + builder, + &ReturnValueBoxArgs { + value_type: FbReturnValue::hlsizeprefixedbuffer, + value: Some(buf_off.as_union_value()), + }, + ); FbFunctionCallResultArgs { - return_value: Some( - Fbhlsizeprefixedbuffer::create( - builder, - &FbhlsizeprefixedbufferArgs { - size: self.len() as i32, - value: Some(vec_offset), - }, - ) - .as_union_value(), - ), - return_value_type: FbReturnValue::hlsizeprefixedbuffer, + result_type: FbFunctionCallResultType::ReturnValueBox, + result: Some(rv_box.as_union_value()), } } } impl FlatbufferSerializable for f32 { fn serialize(&self, builder: &mut FlatBufferBuilder) -> FbFunctionCallResultArgs { + let off = Fbhlfloat::create(builder, &FbhlfloatArgs { value: *self }); + let rv_box = ReturnValueBox::create( + builder, + &ReturnValueBoxArgs { + value_type: FbReturnValue::hlfloat, + value: Some(off.as_union_value()), + }, + ); FbFunctionCallResultArgs { - return_value: Some( - Fbhlfloat::create(builder, &FbhlfloatArgs { value: *self }).as_union_value(), - ), - return_value_type: FbReturnValue::hlfloat, + result_type: FbFunctionCallResultType::ReturnValueBox, + result: Some(rv_box.as_union_value()), } } } impl FlatbufferSerializable for f64 { fn serialize(&self, builder: &mut FlatBufferBuilder) -> FbFunctionCallResultArgs { + let off = Fbhldouble::create(builder, &FbhldoubleArgs { value: *self }); + let rv_box = ReturnValueBox::create( + builder, + &ReturnValueBoxArgs { + value_type: FbReturnValue::hldouble, + value: Some(off.as_union_value()), + }, + ); FbFunctionCallResultArgs { - return_value: Some( - Fbhldouble::create(builder, &FbhldoubleArgs { value: *self }).as_union_value(), - ), - return_value_type: FbReturnValue::hldouble, + result_type: FbFunctionCallResultType::ReturnValueBox, + result: Some(rv_box.as_union_value()), } } } impl FlatbufferSerializable for i32 { fn serialize(&self, builder: &mut FlatBufferBuilder) -> FbFunctionCallResultArgs { + let off = Fbhlint::create(builder, &FbhlintArgs { value: *self }); + let rv_box = ReturnValueBox::create( + builder, + &ReturnValueBoxArgs { + value_type: FbReturnValue::hlint, + value: Some(off.as_union_value()), + }, + ); FbFunctionCallResultArgs { - return_value: Some( - Fbhlint::create(builder, &FbhlintArgs { value: *self }).as_union_value(), - ), - return_value_type: FbReturnValue::hlint, + result_type: FbFunctionCallResultType::ReturnValueBox, + result: Some(rv_box.as_union_value()), } } } impl FlatbufferSerializable for i64 { fn serialize(&self, builder: &mut FlatBufferBuilder) -> FbFunctionCallResultArgs { + let off = Fbhllong::create(builder, &FbhllongArgs { value: *self }); + let rv_box = ReturnValueBox::create( + builder, + &ReturnValueBoxArgs { + value_type: FbReturnValue::hllong, + value: Some(off.as_union_value()), + }, + ); FbFunctionCallResultArgs { - return_value: Some( - Fbhllong::create(builder, &FbhllongArgs { value: *self }).as_union_value(), - ), - return_value_type: FbReturnValue::hllong, + result_type: FbFunctionCallResultType::ReturnValueBox, + result: Some(rv_box.as_union_value()), } } } impl FlatbufferSerializable for u32 { fn serialize(&self, builder: &mut FlatBufferBuilder) -> FbFunctionCallResultArgs { + let off = Fbhluint::create(builder, &FbhluintArgs { value: *self }); + let rv_box = ReturnValueBox::create( + builder, + &ReturnValueBoxArgs { + value_type: FbReturnValue::hluint, + value: Some(off.as_union_value()), + }, + ); FbFunctionCallResultArgs { - return_value: Some( - Fbhluint::create(builder, &FbhluintArgs { value: *self }).as_union_value(), - ), - return_value_type: FbReturnValue::hluint, + result_type: FbFunctionCallResultType::ReturnValueBox, + result: Some(rv_box.as_union_value()), } } } impl FlatbufferSerializable for u64 { fn serialize(&self, builder: &mut FlatBufferBuilder) -> FbFunctionCallResultArgs { + let off = Fbhlulong::create(builder, &FbhlulongArgs { value: *self }); + let rv_box = ReturnValueBox::create( + builder, + &ReturnValueBoxArgs { + value_type: FbReturnValue::hlulong, + value: Some(off.as_union_value()), + }, + ); FbFunctionCallResultArgs { - return_value: Some( - Fbhlulong::create(builder, &FbhlulongArgs { value: *self }).as_union_value(), - ), - return_value_type: FbReturnValue::hlulong, + result_type: FbFunctionCallResultType::ReturnValueBox, + result: Some(rv_box.as_union_value()), } } } impl FlatbufferSerializable for bool { fn serialize(&self, builder: &mut FlatBufferBuilder) -> FbFunctionCallResultArgs { + let off = Fbhlbool::create(builder, &FbhlboolArgs { value: *self }); + let rv_box = ReturnValueBox::create( + builder, + &ReturnValueBoxArgs { + value_type: FbReturnValue::hlbool, + value: Some(off.as_union_value()), + }, + ); FbFunctionCallResultArgs { - return_value: Some( - Fbhlbool::create(builder, &FbhlboolArgs { value: *self }).as_union_value(), - ), - return_value_type: FbReturnValue::hlbool, + result_type: FbFunctionCallResultType::ReturnValueBox, + result: Some(rv_box.as_union_value()), } } } diff --git a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/error_code_generated.rs b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/error_code_generated.rs index 6b03bb0cb..b299358e3 100644 --- a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/error_code_generated.rs +++ b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/error_code_generated.rs @@ -19,13 +19,13 @@ pub const ENUM_MIN_ERROR_CODE: u64 = 0; since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021." )] -pub const ENUM_MAX_ERROR_CODE: u64 = 16; +pub const ENUM_MAX_ERROR_CODE: u64 = 17; #[deprecated( since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021." )] #[allow(non_camel_case_types)] -pub const ENUM_VALUES_ERROR_CODE: [ErrorCode; 16] = [ +pub const ENUM_VALUES_ERROR_CODE: [ErrorCode; 17] = [ ErrorCode::NoError, ErrorCode::UnsupportedParameterType, ErrorCode::GuestFunctionNameNotProvided, @@ -42,6 +42,7 @@ pub const ENUM_VALUES_ERROR_CODE: [ErrorCode; 16] = [ ErrorCode::GuestFunctionParameterTypeMismatch, ErrorCode::GuestError, ErrorCode::ArrayLengthParamIsMissing, + ErrorCode::HostError, ]; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] @@ -65,9 +66,10 @@ impl ErrorCode { pub const GuestFunctionParameterTypeMismatch: Self = Self(14); pub const GuestError: Self = Self(15); pub const ArrayLengthParamIsMissing: Self = Self(16); + pub const HostError: Self = Self(17); pub const ENUM_MIN: u64 = 0; - pub const ENUM_MAX: u64 = 16; + pub const ENUM_MAX: u64 = 17; pub const ENUM_VALUES: &'static [Self] = &[ Self::NoError, Self::UnsupportedParameterType, @@ -85,6 +87,7 @@ impl ErrorCode { Self::GuestFunctionParameterTypeMismatch, Self::GuestError, Self::ArrayLengthParamIsMissing, + Self::HostError, ]; /// Returns the variant's name or "" if unknown. pub fn variant_name(self) -> Option<&'static str> { @@ -107,6 +110,7 @@ impl ErrorCode { Self::GuestFunctionParameterTypeMismatch => Some("GuestFunctionParameterTypeMismatch"), Self::GuestError => Some("GuestError"), Self::ArrayLengthParamIsMissing => Some("ArrayLengthParamIsMissing"), + Self::HostError => Some("HostError"), _ => None, } } diff --git a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/function_call_generated.rs b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/function_call_generated.rs index 786d6de98..7ea5b4d63 100644 --- a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/function_call_generated.rs +++ b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/function_call_generated.rs @@ -237,80 +237,3 @@ impl core::fmt::Debug for FunctionCall<'_> { ds.finish() } } -#[inline] -/// Verifies that a buffer of bytes contains a `FunctionCall` -/// and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_function_call_unchecked`. -pub fn root_as_function_call(buf: &[u8]) -> Result { - flatbuffers::root::(buf) -} -#[inline] -/// Verifies that a buffer of bytes contains a size prefixed -/// `FunctionCall` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `size_prefixed_root_as_function_call_unchecked`. -pub fn size_prefixed_root_as_function_call( - buf: &[u8], -) -> Result { - flatbuffers::size_prefixed_root::(buf) -} -#[inline] -/// Verifies, with the given options, that a buffer of bytes -/// contains a `FunctionCall` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_function_call_unchecked`. -pub fn root_as_function_call_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::root_with_opts::>(opts, buf) -} -#[inline] -/// Verifies, with the given verifier options, that a buffer of -/// bytes contains a size prefixed `FunctionCall` and returns -/// it. Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_function_call_unchecked`. -pub fn size_prefixed_root_as_function_call_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::size_prefixed_root_with_opts::>(opts, buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a FunctionCall and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid `FunctionCall`. -pub unsafe fn root_as_function_call_unchecked(buf: &[u8]) -> FunctionCall { - unsafe { flatbuffers::root_unchecked::(buf) } -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a size prefixed FunctionCall and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid size prefixed `FunctionCall`. -pub unsafe fn size_prefixed_root_as_function_call_unchecked(buf: &[u8]) -> FunctionCall { - unsafe { flatbuffers::size_prefixed_root_unchecked::(buf) } -} -#[inline] -pub fn finish_function_call_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish(root, None); -} - -#[inline] -pub fn finish_size_prefixed_function_call_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish_size_prefixed(root, None); -} diff --git a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/function_call_result_generated.rs b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/function_call_result_generated.rs index 9e7cddd15..7f26e9c00 100644 --- a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/function_call_result_generated.rs +++ b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/function_call_result_generated.rs @@ -28,8 +28,8 @@ impl<'a> flatbuffers::Follow<'a> for FunctionCallResult<'a> { } impl<'a> FunctionCallResult<'a> { - pub const VT_RETURN_VALUE_TYPE: flatbuffers::VOffsetT = 4; - pub const VT_RETURN_VALUE: flatbuffers::VOffsetT = 6; + pub const VT_RESULT_TYPE: flatbuffers::VOffsetT = 4; + pub const VT_RESULT: flatbuffers::VOffsetT = 6; #[inline] pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { @@ -41,36 +41,36 @@ impl<'a> FunctionCallResult<'a> { args: &'args FunctionCallResultArgs, ) -> flatbuffers::WIPOffset> { let mut builder = FunctionCallResultBuilder::new(_fbb); - if let Some(x) = args.return_value { - builder.add_return_value(x); + if let Some(x) = args.result { + builder.add_result(x); } - builder.add_return_value_type(args.return_value_type); + builder.add_result_type(args.result_type); builder.finish() } #[inline] - pub fn return_value_type(&self) -> ReturnValue { + pub fn result_type(&self) -> FunctionCallResultType { // Safety: // Created from valid Table for this object // which contains a valid value in this slot unsafe { self._tab - .get::( - FunctionCallResult::VT_RETURN_VALUE_TYPE, - Some(ReturnValue::NONE), + .get::( + FunctionCallResult::VT_RESULT_TYPE, + Some(FunctionCallResultType::NONE), ) .unwrap() } } #[inline] - pub fn return_value(&self) -> flatbuffers::Table<'a> { + pub fn result(&self) -> flatbuffers::Table<'a> { // Safety: // Created from valid Table for this object // which contains a valid value in this slot unsafe { self._tab .get::>>( - FunctionCallResult::VT_RETURN_VALUE, + FunctionCallResult::VT_RESULT, None, ) .unwrap() @@ -78,13 +78,13 @@ impl<'a> FunctionCallResult<'a> { } #[inline] #[allow(non_snake_case)] - pub fn return_value_as_hlint(&self) -> Option> { - if self.return_value_type() == ReturnValue::hlint { - let u = self.return_value(); + pub fn result_as_return_value_box(&self) -> Option> { + if self.result_type() == FunctionCallResultType::ReturnValueBox { + let u = self.result(); // Safety: // Created from a valid Table for this object // Which contains a valid union in this slot - Some(unsafe { hlint::init_from_table(u) }) + Some(unsafe { ReturnValueBox::init_from_table(u) }) } else { None } @@ -92,125 +92,13 @@ impl<'a> FunctionCallResult<'a> { #[inline] #[allow(non_snake_case)] - pub fn return_value_as_hluint(&self) -> Option> { - if self.return_value_type() == ReturnValue::hluint { - let u = self.return_value(); + pub fn result_as_guest_error(&self) -> Option> { + if self.result_type() == FunctionCallResultType::GuestError { + let u = self.result(); // Safety: // Created from a valid Table for this object // Which contains a valid union in this slot - Some(unsafe { hluint::init_from_table(u) }) - } else { - None - } - } - - #[inline] - #[allow(non_snake_case)] - pub fn return_value_as_hllong(&self) -> Option> { - if self.return_value_type() == ReturnValue::hllong { - let u = self.return_value(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { hllong::init_from_table(u) }) - } else { - None - } - } - - #[inline] - #[allow(non_snake_case)] - pub fn return_value_as_hlulong(&self) -> Option> { - if self.return_value_type() == ReturnValue::hlulong { - let u = self.return_value(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { hlulong::init_from_table(u) }) - } else { - None - } - } - - #[inline] - #[allow(non_snake_case)] - pub fn return_value_as_hlfloat(&self) -> Option> { - if self.return_value_type() == ReturnValue::hlfloat { - let u = self.return_value(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { hlfloat::init_from_table(u) }) - } else { - None - } - } - - #[inline] - #[allow(non_snake_case)] - pub fn return_value_as_hldouble(&self) -> Option> { - if self.return_value_type() == ReturnValue::hldouble { - let u = self.return_value(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { hldouble::init_from_table(u) }) - } else { - None - } - } - - #[inline] - #[allow(non_snake_case)] - pub fn return_value_as_hlstring(&self) -> Option> { - if self.return_value_type() == ReturnValue::hlstring { - let u = self.return_value(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { hlstring::init_from_table(u) }) - } else { - None - } - } - - #[inline] - #[allow(non_snake_case)] - pub fn return_value_as_hlbool(&self) -> Option> { - if self.return_value_type() == ReturnValue::hlbool { - let u = self.return_value(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { hlbool::init_from_table(u) }) - } else { - None - } - } - - #[inline] - #[allow(non_snake_case)] - pub fn return_value_as_hlvoid(&self) -> Option> { - if self.return_value_type() == ReturnValue::hlvoid { - let u = self.return_value(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { hlvoid::init_from_table(u) }) - } else { - None - } - } - - #[inline] - #[allow(non_snake_case)] - pub fn return_value_as_hlsizeprefixedbuffer(&self) -> Option> { - if self.return_value_type() == ReturnValue::hlsizeprefixedbuffer { - let u = self.return_value(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { hlsizeprefixedbuffer::init_from_table(u) }) + Some(unsafe { GuestError::init_from_table(u) }) } else { None } @@ -225,61 +113,21 @@ impl flatbuffers::Verifiable for FunctionCallResult<'_> { ) -> Result<(), flatbuffers::InvalidFlatbuffer> { use self::flatbuffers::Verifiable; v.visit_table(pos)? - .visit_union::( - "return_value_type", - Self::VT_RETURN_VALUE_TYPE, - "return_value", - Self::VT_RETURN_VALUE, + .visit_union::( + "result_type", + Self::VT_RESULT_TYPE, + "result", + Self::VT_RESULT, true, |key, v, pos| match key { - ReturnValue::hlint => v - .verify_union_variant::>( - "ReturnValue::hlint", - pos, - ), - ReturnValue::hluint => v - .verify_union_variant::>( - "ReturnValue::hluint", - pos, - ), - ReturnValue::hllong => v - .verify_union_variant::>( - "ReturnValue::hllong", - pos, - ), - ReturnValue::hlulong => v - .verify_union_variant::>( - "ReturnValue::hlulong", - pos, - ), - ReturnValue::hlfloat => v - .verify_union_variant::>( - "ReturnValue::hlfloat", + FunctionCallResultType::ReturnValueBox => v + .verify_union_variant::>( + "FunctionCallResultType::ReturnValueBox", pos, ), - ReturnValue::hldouble => v - .verify_union_variant::>( - "ReturnValue::hldouble", - pos, - ), - ReturnValue::hlstring => v - .verify_union_variant::>( - "ReturnValue::hlstring", - pos, - ), - ReturnValue::hlbool => v - .verify_union_variant::>( - "ReturnValue::hlbool", - pos, - ), - ReturnValue::hlvoid => v - .verify_union_variant::>( - "ReturnValue::hlvoid", - pos, - ), - ReturnValue::hlsizeprefixedbuffer => v - .verify_union_variant::>( - "ReturnValue::hlsizeprefixedbuffer", + FunctionCallResultType::GuestError => v + .verify_union_variant::>( + "FunctionCallResultType::GuestError", pos, ), _ => Ok(()), @@ -290,15 +138,15 @@ impl flatbuffers::Verifiable for FunctionCallResult<'_> { } } pub struct FunctionCallResultArgs { - pub return_value_type: ReturnValue, - pub return_value: Option>, + pub result_type: FunctionCallResultType, + pub result: Option>, } impl<'a> Default for FunctionCallResultArgs { #[inline] fn default() -> Self { FunctionCallResultArgs { - return_value_type: ReturnValue::NONE, - return_value: None, // required field + result_type: FunctionCallResultType::NONE, + result: None, // required field } } } @@ -309,22 +157,17 @@ pub struct FunctionCallResultBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> } impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FunctionCallResultBuilder<'a, 'b, A> { #[inline] - pub fn add_return_value_type(&mut self, return_value_type: ReturnValue) { - self.fbb_.push_slot::( - FunctionCallResult::VT_RETURN_VALUE_TYPE, - return_value_type, - ReturnValue::NONE, + pub fn add_result_type(&mut self, result_type: FunctionCallResultType) { + self.fbb_.push_slot::( + FunctionCallResult::VT_RESULT_TYPE, + result_type, + FunctionCallResultType::NONE, ); } #[inline] - pub fn add_return_value( - &mut self, - return_value: flatbuffers::WIPOffset, - ) { - self.fbb_.push_slot_always::>( - FunctionCallResult::VT_RETURN_VALUE, - return_value, - ); + pub fn add_result(&mut self, result: flatbuffers::WIPOffset) { + self.fbb_ + .push_slot_always::>(FunctionCallResult::VT_RESULT, result); } #[inline] pub fn new( @@ -340,7 +183,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FunctionCallResultBuilder<'a, ' pub fn finish(self) -> flatbuffers::WIPOffset> { let o = self.fbb_.end_table(self.start_); self.fbb_ - .required(o, FunctionCallResult::VT_RETURN_VALUE, "return_value"); + .required(o, FunctionCallResult::VT_RESULT, "result"); flatbuffers::WIPOffset::new(o.value()) } } @@ -348,194 +191,33 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FunctionCallResultBuilder<'a, ' impl core::fmt::Debug for FunctionCallResult<'_> { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let mut ds = f.debug_struct("FunctionCallResult"); - ds.field("return_value_type", &self.return_value_type()); - match self.return_value_type() { - ReturnValue::hlint => { - if let Some(x) = self.return_value_as_hlint() { - ds.field("return_value", &x) + ds.field("result_type", &self.result_type()); + match self.result_type() { + FunctionCallResultType::ReturnValueBox => { + if let Some(x) = self.result_as_return_value_box() { + ds.field("result", &x) } else { ds.field( - "return_value", + "result", &"InvalidFlatbuffer: Union discriminant does not match value.", ) } } - ReturnValue::hluint => { - if let Some(x) = self.return_value_as_hluint() { - ds.field("return_value", &x) + FunctionCallResultType::GuestError => { + if let Some(x) = self.result_as_guest_error() { + ds.field("result", &x) } else { ds.field( - "return_value", - &"InvalidFlatbuffer: Union discriminant does not match value.", - ) - } - } - ReturnValue::hllong => { - if let Some(x) = self.return_value_as_hllong() { - ds.field("return_value", &x) - } else { - ds.field( - "return_value", - &"InvalidFlatbuffer: Union discriminant does not match value.", - ) - } - } - ReturnValue::hlulong => { - if let Some(x) = self.return_value_as_hlulong() { - ds.field("return_value", &x) - } else { - ds.field( - "return_value", - &"InvalidFlatbuffer: Union discriminant does not match value.", - ) - } - } - ReturnValue::hlfloat => { - if let Some(x) = self.return_value_as_hlfloat() { - ds.field("return_value", &x) - } else { - ds.field( - "return_value", - &"InvalidFlatbuffer: Union discriminant does not match value.", - ) - } - } - ReturnValue::hldouble => { - if let Some(x) = self.return_value_as_hldouble() { - ds.field("return_value", &x) - } else { - ds.field( - "return_value", - &"InvalidFlatbuffer: Union discriminant does not match value.", - ) - } - } - ReturnValue::hlstring => { - if let Some(x) = self.return_value_as_hlstring() { - ds.field("return_value", &x) - } else { - ds.field( - "return_value", - &"InvalidFlatbuffer: Union discriminant does not match value.", - ) - } - } - ReturnValue::hlbool => { - if let Some(x) = self.return_value_as_hlbool() { - ds.field("return_value", &x) - } else { - ds.field( - "return_value", - &"InvalidFlatbuffer: Union discriminant does not match value.", - ) - } - } - ReturnValue::hlvoid => { - if let Some(x) = self.return_value_as_hlvoid() { - ds.field("return_value", &x) - } else { - ds.field( - "return_value", - &"InvalidFlatbuffer: Union discriminant does not match value.", - ) - } - } - ReturnValue::hlsizeprefixedbuffer => { - if let Some(x) = self.return_value_as_hlsizeprefixedbuffer() { - ds.field("return_value", &x) - } else { - ds.field( - "return_value", + "result", &"InvalidFlatbuffer: Union discriminant does not match value.", ) } } _ => { let x: Option<()> = None; - ds.field("return_value", &x) + ds.field("result", &x) } }; ds.finish() } } -#[inline] -/// Verifies that a buffer of bytes contains a `FunctionCallResult` -/// and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_function_call_result_unchecked`. -pub fn root_as_function_call_result( - buf: &[u8], -) -> Result { - flatbuffers::root::(buf) -} -#[inline] -/// Verifies that a buffer of bytes contains a size prefixed -/// `FunctionCallResult` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `size_prefixed_root_as_function_call_result_unchecked`. -pub fn size_prefixed_root_as_function_call_result( - buf: &[u8], -) -> Result { - flatbuffers::size_prefixed_root::(buf) -} -#[inline] -/// Verifies, with the given options, that a buffer of bytes -/// contains a `FunctionCallResult` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_function_call_result_unchecked`. -pub fn root_as_function_call_result_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::root_with_opts::>(opts, buf) -} -#[inline] -/// Verifies, with the given verifier options, that a buffer of -/// bytes contains a size prefixed `FunctionCallResult` and returns -/// it. Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_function_call_result_unchecked`. -pub fn size_prefixed_root_as_function_call_result_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::size_prefixed_root_with_opts::>(opts, buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a FunctionCallResult and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid `FunctionCallResult`. -pub unsafe fn root_as_function_call_result_unchecked(buf: &[u8]) -> FunctionCallResult { - unsafe { flatbuffers::root_unchecked::(buf) } -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a size prefixed FunctionCallResult and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid size prefixed `FunctionCallResult`. -pub unsafe fn size_prefixed_root_as_function_call_result_unchecked( - buf: &[u8], -) -> FunctionCallResult { - unsafe { flatbuffers::size_prefixed_root_unchecked::(buf) } -} -#[inline] -pub fn finish_function_call_result_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish(root, None); -} - -#[inline] -pub fn finish_size_prefixed_function_call_result_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish_size_prefixed(root, None); -} diff --git a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/function_call_result_type_generated.rs b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/function_call_result_type_generated.rs new file mode 100644 index 000000000..0c54dfed4 --- /dev/null +++ b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/function_call_result_type_generated.rs @@ -0,0 +1,110 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::cmp::Ordering; +use core::mem; + +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +#[deprecated( + since = "2.0.0", + note = "Use associated constants instead. This will no longer be generated in 2021." +)] +pub const ENUM_MIN_FUNCTION_CALL_RESULT_TYPE: u8 = 0; +#[deprecated( + since = "2.0.0", + note = "Use associated constants instead. This will no longer be generated in 2021." +)] +pub const ENUM_MAX_FUNCTION_CALL_RESULT_TYPE: u8 = 2; +#[deprecated( + since = "2.0.0", + note = "Use associated constants instead. This will no longer be generated in 2021." +)] +#[allow(non_camel_case_types)] +pub const ENUM_VALUES_FUNCTION_CALL_RESULT_TYPE: [FunctionCallResultType; 3] = [ + FunctionCallResultType::NONE, + FunctionCallResultType::ReturnValueBox, + FunctionCallResultType::GuestError, +]; + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +#[repr(transparent)] +pub struct FunctionCallResultType(pub u8); +#[allow(non_upper_case_globals)] +impl FunctionCallResultType { + pub const NONE: Self = Self(0); + pub const ReturnValueBox: Self = Self(1); + pub const GuestError: Self = Self(2); + + pub const ENUM_MIN: u8 = 0; + pub const ENUM_MAX: u8 = 2; + pub const ENUM_VALUES: &'static [Self] = &[Self::NONE, Self::ReturnValueBox, Self::GuestError]; + /// Returns the variant's name or "" if unknown. + pub fn variant_name(self) -> Option<&'static str> { + match self { + Self::NONE => Some("NONE"), + Self::ReturnValueBox => Some("ReturnValueBox"), + Self::GuestError => Some("GuestError"), + _ => None, + } + } +} +impl core::fmt::Debug for FunctionCallResultType { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + if let Some(name) = self.variant_name() { + f.write_str(name) + } else { + f.write_fmt(format_args!("", self.0)) + } + } +} +impl<'a> flatbuffers::Follow<'a> for FunctionCallResultType { + type Inner = Self; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = unsafe { flatbuffers::read_scalar_at::(buf, loc) }; + Self(b) + } +} + +impl flatbuffers::Push for FunctionCallResultType { + type Output = FunctionCallResultType; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + unsafe { + flatbuffers::emplace_scalar::(dst, self.0); + } + } +} + +impl flatbuffers::EndianScalar for FunctionCallResultType { + type Scalar = u8; + #[inline] + fn to_little_endian(self) -> u8 { + self.0.to_le() + } + #[inline] + #[allow(clippy::wrong_self_convention)] + fn from_little_endian(v: u8) -> Self { + let b = u8::from_le(v); + Self(b) + } +} + +impl<'a> flatbuffers::Verifiable for FunctionCallResultType { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, + pos: usize, + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + u8::run_verifier(v, pos) + } +} + +impl flatbuffers::SimpleToVerifyInSlice for FunctionCallResultType {} +pub struct FunctionCallResultTypeUnionTableOffset {} diff --git a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/guest_error_generated.rs b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/guest_error_generated.rs index 24b76ea47..21ef559b6 100644 --- a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/guest_error_generated.rs +++ b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/guest_error_generated.rs @@ -139,80 +139,3 @@ impl core::fmt::Debug for GuestError<'_> { ds.finish() } } -#[inline] -/// Verifies that a buffer of bytes contains a `GuestError` -/// and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_guest_error_unchecked`. -pub fn root_as_guest_error(buf: &[u8]) -> Result { - flatbuffers::root::(buf) -} -#[inline] -/// Verifies that a buffer of bytes contains a size prefixed -/// `GuestError` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `size_prefixed_root_as_guest_error_unchecked`. -pub fn size_prefixed_root_as_guest_error( - buf: &[u8], -) -> Result { - flatbuffers::size_prefixed_root::(buf) -} -#[inline] -/// Verifies, with the given options, that a buffer of bytes -/// contains a `GuestError` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_guest_error_unchecked`. -pub fn root_as_guest_error_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::root_with_opts::>(opts, buf) -} -#[inline] -/// Verifies, with the given verifier options, that a buffer of -/// bytes contains a size prefixed `GuestError` and returns -/// it. Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_guest_error_unchecked`. -pub fn size_prefixed_root_as_guest_error_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::size_prefixed_root_with_opts::>(opts, buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a GuestError and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid `GuestError`. -pub unsafe fn root_as_guest_error_unchecked(buf: &[u8]) -> GuestError { - unsafe { flatbuffers::root_unchecked::(buf) } -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a size prefixed GuestError and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid size prefixed `GuestError`. -pub unsafe fn size_prefixed_root_as_guest_error_unchecked(buf: &[u8]) -> GuestError { - unsafe { flatbuffers::size_prefixed_root_unchecked::(buf) } -} -#[inline] -pub fn finish_guest_error_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish(root, None); -} - -#[inline] -pub fn finish_size_prefixed_guest_error_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish_size_prefixed(root, None); -} diff --git a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/guest_log_data_generated.rs b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/guest_log_data_generated.rs index d57f8ed7e..d3de70427 100644 --- a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/guest_log_data_generated.rs +++ b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/guest_log_data_generated.rs @@ -235,80 +235,3 @@ impl core::fmt::Debug for GuestLogData<'_> { ds.finish() } } -#[inline] -/// Verifies that a buffer of bytes contains a `GuestLogData` -/// and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_guest_log_data_unchecked`. -pub fn root_as_guest_log_data(buf: &[u8]) -> Result { - flatbuffers::root::(buf) -} -#[inline] -/// Verifies that a buffer of bytes contains a size prefixed -/// `GuestLogData` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `size_prefixed_root_as_guest_log_data_unchecked`. -pub fn size_prefixed_root_as_guest_log_data( - buf: &[u8], -) -> Result { - flatbuffers::size_prefixed_root::(buf) -} -#[inline] -/// Verifies, with the given options, that a buffer of bytes -/// contains a `GuestLogData` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_guest_log_data_unchecked`. -pub fn root_as_guest_log_data_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::root_with_opts::>(opts, buf) -} -#[inline] -/// Verifies, with the given verifier options, that a buffer of -/// bytes contains a size prefixed `GuestLogData` and returns -/// it. Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_guest_log_data_unchecked`. -pub fn size_prefixed_root_as_guest_log_data_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::size_prefixed_root_with_opts::>(opts, buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a GuestLogData and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid `GuestLogData`. -pub unsafe fn root_as_guest_log_data_unchecked(buf: &[u8]) -> GuestLogData { - unsafe { flatbuffers::root_unchecked::(buf) } -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a size prefixed GuestLogData and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid size prefixed `GuestLogData`. -pub unsafe fn size_prefixed_root_as_guest_log_data_unchecked(buf: &[u8]) -> GuestLogData { - unsafe { flatbuffers::size_prefixed_root_unchecked::(buf) } -} -#[inline] -pub fn finish_guest_log_data_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish(root, None); -} - -#[inline] -pub fn finish_size_prefixed_guest_log_data_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish_size_prefixed(root, None); -} diff --git a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_definition_generated.rs b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_definition_generated.rs index 010d111bf..8ffb6f35e 100644 --- a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_definition_generated.rs +++ b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_definition_generated.rs @@ -202,88 +202,3 @@ impl core::fmt::Debug for HostFunctionDefinition<'_> { ds.finish() } } -#[inline] -/// Verifies that a buffer of bytes contains a `HostFunctionDefinition` -/// and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_host_function_definition_unchecked`. -pub fn root_as_host_function_definition( - buf: &[u8], -) -> Result { - flatbuffers::root::(buf) -} -#[inline] -/// Verifies that a buffer of bytes contains a size prefixed -/// `HostFunctionDefinition` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `size_prefixed_root_as_host_function_definition_unchecked`. -pub fn size_prefixed_root_as_host_function_definition( - buf: &[u8], -) -> Result { - flatbuffers::size_prefixed_root::(buf) -} -#[inline] -/// Verifies, with the given options, that a buffer of bytes -/// contains a `HostFunctionDefinition` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_host_function_definition_unchecked`. -pub fn root_as_host_function_definition_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::root_with_opts::>(opts, buf) -} -#[inline] -/// Verifies, with the given verifier options, that a buffer of -/// bytes contains a size prefixed `HostFunctionDefinition` and returns -/// it. Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_host_function_definition_unchecked`. -pub fn size_prefixed_root_as_host_function_definition_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::size_prefixed_root_with_opts::>(opts, buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a HostFunctionDefinition and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid `HostFunctionDefinition`. -pub unsafe fn root_as_host_function_definition_unchecked(buf: &[u8]) -> HostFunctionDefinition { - unsafe { flatbuffers::root_unchecked::(buf) } -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a size prefixed HostFunctionDefinition and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid size prefixed `HostFunctionDefinition`. -pub unsafe fn size_prefixed_root_as_host_function_definition_unchecked( - buf: &[u8], -) -> HostFunctionDefinition { - unsafe { flatbuffers::size_prefixed_root_unchecked::(buf) } -} -#[inline] -pub fn finish_host_function_definition_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish(root, None); -} - -#[inline] -pub fn finish_size_prefixed_host_function_definition_buffer< - 'a, - 'b, - A: flatbuffers::Allocator + 'a, ->( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish_size_prefixed(root, None); -} diff --git a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_details_generated.rs b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_details_generated.rs index a502dd491..54cf45c73 100644 --- a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_details_generated.rs +++ b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_details_generated.rs @@ -132,84 +132,3 @@ impl core::fmt::Debug for HostFunctionDetails<'_> { ds.finish() } } -#[inline] -/// Verifies that a buffer of bytes contains a `HostFunctionDetails` -/// and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_host_function_details_unchecked`. -pub fn root_as_host_function_details( - buf: &[u8], -) -> Result { - flatbuffers::root::(buf) -} -#[inline] -/// Verifies that a buffer of bytes contains a size prefixed -/// `HostFunctionDetails` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `size_prefixed_root_as_host_function_details_unchecked`. -pub fn size_prefixed_root_as_host_function_details( - buf: &[u8], -) -> Result { - flatbuffers::size_prefixed_root::(buf) -} -#[inline] -/// Verifies, with the given options, that a buffer of bytes -/// contains a `HostFunctionDetails` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_host_function_details_unchecked`. -pub fn root_as_host_function_details_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::root_with_opts::>(opts, buf) -} -#[inline] -/// Verifies, with the given verifier options, that a buffer of -/// bytes contains a size prefixed `HostFunctionDetails` and returns -/// it. Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_host_function_details_unchecked`. -pub fn size_prefixed_root_as_host_function_details_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::size_prefixed_root_with_opts::>(opts, buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a HostFunctionDetails and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid `HostFunctionDetails`. -pub unsafe fn root_as_host_function_details_unchecked(buf: &[u8]) -> HostFunctionDetails { - unsafe { flatbuffers::root_unchecked::(buf) } -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a size prefixed HostFunctionDetails and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid size prefixed `HostFunctionDetails`. -pub unsafe fn size_prefixed_root_as_host_function_details_unchecked( - buf: &[u8], -) -> HostFunctionDetails { - unsafe { flatbuffers::size_prefixed_root_unchecked::(buf) } -} -#[inline] -pub fn finish_host_function_details_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish(root, None); -} - -#[inline] -pub fn finish_size_prefixed_host_function_details_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish_size_prefixed(root, None); -} diff --git a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/return_value_box_generated.rs b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/return_value_box_generated.rs new file mode 100644 index 000000000..cecd8b6c1 --- /dev/null +++ b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/return_value_box_generated.rs @@ -0,0 +1,451 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::cmp::Ordering; +use core::mem; + +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +pub enum ReturnValueBoxOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct ReturnValueBox<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for ReturnValueBox<'a> { + type Inner = ReturnValueBox<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { + _tab: unsafe { flatbuffers::Table::new(buf, loc) }, + } + } +} + +impl<'a> ReturnValueBox<'a> { + pub const VT_VALUE_TYPE: flatbuffers::VOffsetT = 4; + pub const VT_VALUE: flatbuffers::VOffsetT = 6; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + ReturnValueBox { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args ReturnValueBoxArgs, + ) -> flatbuffers::WIPOffset> { + let mut builder = ReturnValueBoxBuilder::new(_fbb); + if let Some(x) = args.value { + builder.add_value(x); + } + builder.add_value_type(args.value_type); + builder.finish() + } + + #[inline] + pub fn value_type(&self) -> ReturnValue { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::(ReturnValueBox::VT_VALUE_TYPE, Some(ReturnValue::NONE)) + .unwrap() + } + } + #[inline] + pub fn value(&self) -> flatbuffers::Table<'a> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>>( + ReturnValueBox::VT_VALUE, + None, + ) + .unwrap() + } + } + #[inline] + #[allow(non_snake_case)] + pub fn value_as_hlint(&self) -> Option> { + if self.value_type() == ReturnValue::hlint { + let u = self.value(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { hlint::init_from_table(u) }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn value_as_hluint(&self) -> Option> { + if self.value_type() == ReturnValue::hluint { + let u = self.value(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { hluint::init_from_table(u) }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn value_as_hllong(&self) -> Option> { + if self.value_type() == ReturnValue::hllong { + let u = self.value(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { hllong::init_from_table(u) }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn value_as_hlulong(&self) -> Option> { + if self.value_type() == ReturnValue::hlulong { + let u = self.value(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { hlulong::init_from_table(u) }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn value_as_hlfloat(&self) -> Option> { + if self.value_type() == ReturnValue::hlfloat { + let u = self.value(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { hlfloat::init_from_table(u) }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn value_as_hldouble(&self) -> Option> { + if self.value_type() == ReturnValue::hldouble { + let u = self.value(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { hldouble::init_from_table(u) }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn value_as_hlstring(&self) -> Option> { + if self.value_type() == ReturnValue::hlstring { + let u = self.value(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { hlstring::init_from_table(u) }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn value_as_hlbool(&self) -> Option> { + if self.value_type() == ReturnValue::hlbool { + let u = self.value(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { hlbool::init_from_table(u) }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn value_as_hlvoid(&self) -> Option> { + if self.value_type() == ReturnValue::hlvoid { + let u = self.value(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { hlvoid::init_from_table(u) }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn value_as_hlsizeprefixedbuffer(&self) -> Option> { + if self.value_type() == ReturnValue::hlsizeprefixedbuffer { + let u = self.value(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { hlsizeprefixedbuffer::init_from_table(u) }) + } else { + None + } + } +} + +impl flatbuffers::Verifiable for ReturnValueBox<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, + pos: usize, + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_union::( + "value_type", + Self::VT_VALUE_TYPE, + "value", + Self::VT_VALUE, + true, + |key, v, pos| match key { + ReturnValue::hlint => v + .verify_union_variant::>( + "ReturnValue::hlint", + pos, + ), + ReturnValue::hluint => v + .verify_union_variant::>( + "ReturnValue::hluint", + pos, + ), + ReturnValue::hllong => v + .verify_union_variant::>( + "ReturnValue::hllong", + pos, + ), + ReturnValue::hlulong => v + .verify_union_variant::>( + "ReturnValue::hlulong", + pos, + ), + ReturnValue::hlfloat => v + .verify_union_variant::>( + "ReturnValue::hlfloat", + pos, + ), + ReturnValue::hldouble => v + .verify_union_variant::>( + "ReturnValue::hldouble", + pos, + ), + ReturnValue::hlstring => v + .verify_union_variant::>( + "ReturnValue::hlstring", + pos, + ), + ReturnValue::hlbool => v + .verify_union_variant::>( + "ReturnValue::hlbool", + pos, + ), + ReturnValue::hlvoid => v + .verify_union_variant::>( + "ReturnValue::hlvoid", + pos, + ), + ReturnValue::hlsizeprefixedbuffer => v + .verify_union_variant::>( + "ReturnValue::hlsizeprefixedbuffer", + pos, + ), + _ => Ok(()), + }, + )? + .finish(); + Ok(()) + } +} +pub struct ReturnValueBoxArgs { + pub value_type: ReturnValue, + pub value: Option>, +} +impl<'a> Default for ReturnValueBoxArgs { + #[inline] + fn default() -> Self { + ReturnValueBoxArgs { + value_type: ReturnValue::NONE, + value: None, // required field + } + } +} + +pub struct ReturnValueBoxBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ReturnValueBoxBuilder<'a, 'b, A> { + #[inline] + pub fn add_value_type(&mut self, value_type: ReturnValue) { + self.fbb_.push_slot::( + ReturnValueBox::VT_VALUE_TYPE, + value_type, + ReturnValue::NONE, + ); + } + #[inline] + pub fn add_value(&mut self, value: flatbuffers::WIPOffset) { + self.fbb_ + .push_slot_always::>(ReturnValueBox::VT_VALUE, value); + } + #[inline] + pub fn new( + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> ReturnValueBoxBuilder<'a, 'b, A> { + let start = _fbb.start_table(); + ReturnValueBoxBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_.required(o, ReturnValueBox::VT_VALUE, "value"); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for ReturnValueBox<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("ReturnValueBox"); + ds.field("value_type", &self.value_type()); + match self.value_type() { + ReturnValue::hlint => { + if let Some(x) = self.value_as_hlint() { + ds.field("value", &x) + } else { + ds.field( + "value", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ReturnValue::hluint => { + if let Some(x) = self.value_as_hluint() { + ds.field("value", &x) + } else { + ds.field( + "value", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ReturnValue::hllong => { + if let Some(x) = self.value_as_hllong() { + ds.field("value", &x) + } else { + ds.field( + "value", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ReturnValue::hlulong => { + if let Some(x) = self.value_as_hlulong() { + ds.field("value", &x) + } else { + ds.field( + "value", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ReturnValue::hlfloat => { + if let Some(x) = self.value_as_hlfloat() { + ds.field("value", &x) + } else { + ds.field( + "value", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ReturnValue::hldouble => { + if let Some(x) = self.value_as_hldouble() { + ds.field("value", &x) + } else { + ds.field( + "value", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ReturnValue::hlstring => { + if let Some(x) = self.value_as_hlstring() { + ds.field("value", &x) + } else { + ds.field( + "value", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ReturnValue::hlbool => { + if let Some(x) = self.value_as_hlbool() { + ds.field("value", &x) + } else { + ds.field( + "value", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ReturnValue::hlvoid => { + if let Some(x) = self.value_as_hlvoid() { + ds.field("value", &x) + } else { + ds.field( + "value", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ReturnValue::hlsizeprefixedbuffer => { + if let Some(x) = self.value_as_hlsizeprefixedbuffer() { + ds.field("value", &x) + } else { + ds.field( + "value", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + _ => { + let x: Option<()> = None; + ds.field("value", &x) + } + }; + ds.finish() + } +} diff --git a/src/hyperlight_common/src/flatbuffers/mod.rs b/src/hyperlight_common/src/flatbuffers/mod.rs index d0a859cd8..bf8582877 100644 --- a/src/hyperlight_common/src/flatbuffers/mod.rs +++ b/src/hyperlight_common/src/flatbuffers/mod.rs @@ -2,7 +2,6 @@ // @generated pub mod hyperlight { use super::*; - #[allow(mismatched_lifetime_syntaxes)] pub mod generated { use super::*; mod parameter_value_generated; @@ -13,6 +12,14 @@ pub mod hyperlight { pub use self::return_type_generated::*; mod return_value_generated; pub use self::return_value_generated::*; + mod error_code_generated; + pub use self::error_code_generated::*; + mod function_call_result_type_generated; + pub use self::function_call_result_type_generated::*; + mod function_call_type_generated; + pub use self::function_call_type_generated::*; + mod log_level_generated; + pub use self::log_level_generated::*; mod hlint_generated; pub use self::hlint_generated::*; mod hluint_generated; @@ -31,29 +38,25 @@ pub mod hyperlight { pub use self::hlbool_generated::*; mod hlvecbytes_generated; pub use self::hlvecbytes_generated::*; + mod hlsizeprefixedbuffer_generated; + pub use self::hlsizeprefixedbuffer_generated::*; mod hlvoid_generated; pub use self::hlvoid_generated::*; + mod guest_error_generated; + pub use self::guest_error_generated::*; + mod return_value_box_generated; + pub use self::return_value_box_generated::*; mod function_call_result_generated; pub use self::function_call_result_generated::*; mod parameter_generated; pub use self::parameter_generated::*; mod function_call_generated; pub use self::function_call_generated::*; - mod function_call_type_generated; - pub use self::function_call_type_generated::*; - mod error_code_generated; - pub use self::error_code_generated::*; - mod guest_error_generated; - pub use self::guest_error_generated::*; + mod guest_log_data_generated; + pub use self::guest_log_data_generated::*; mod host_function_definition_generated; pub use self::host_function_definition_generated::*; mod host_function_details_generated; pub use self::host_function_details_generated::*; - mod hlsizeprefixedbuffer_generated; - pub use self::hlsizeprefixedbuffer_generated::*; - mod log_level_generated; - pub use self::log_level_generated::*; - mod guest_log_data_generated; - pub use self::guest_log_data_generated::*; - } -} + } // generated +} // hyperlight diff --git a/src/hyperlight_guest/src/guest_handle/host_comm.rs b/src/hyperlight_guest/src/guest_handle/host_comm.rs index 17b5300e5..5802d08f7 100644 --- a/src/hyperlight_guest/src/guest_handle/host_comm.rs +++ b/src/hyperlight_guest/src/guest_handle/host_comm.rs @@ -22,9 +22,9 @@ use core::slice::from_raw_parts; use flatbuffers::FlatBufferBuilder; use hyperlight_common::flatbuffer_wrappers::function_call::{FunctionCall, FunctionCallType}; use hyperlight_common::flatbuffer_wrappers::function_types::{ - ParameterValue, ReturnType, ReturnValue, + FunctionCallResult, ParameterValue, ReturnType, ReturnValue, }; -use hyperlight_common::flatbuffer_wrappers::guest_error::{ErrorCode, GuestError}; +use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode; use hyperlight_common::flatbuffer_wrappers::guest_log_data::GuestLogData; use hyperlight_common::flatbuffer_wrappers::guest_log_level::LogLevel; use hyperlight_common::flatbuffer_wrappers::host_function_details::HostFunctionDetails; @@ -68,18 +68,24 @@ impl GuestHandle { /// internally to get the return value. #[hyperlight_guest_tracing::trace_function] pub fn get_host_return_value>(&self) -> Result { - let return_value = self - .try_pop_shared_input_data_into::() - .expect("Unable to deserialize a return value from host"); - T::try_from(return_value).map_err(|_| { - HyperlightGuestError::new( - ErrorCode::GuestError, - format!( - "Host return value was not a {} as expected", - core::any::type_name::() - ), - ) - }) + let inner = self + .try_pop_shared_input_data_into::() + .expect("Unable to deserialize a return value from host") + .into_inner(); + + match inner { + Ok(ret) => T::try_from(ret).map_err(|_| { + let expected = core::any::type_name::(); + HyperlightGuestError::new( + ErrorCode::UnsupportedParameterType, + format!("Host return value could not be converted to expected {expected}",), + ) + }), + Err(e) => Err(HyperlightGuestError { + kind: e.code, + message: e.message, + }), + } } /// Call a host function without reading its return value from shared mem. @@ -148,22 +154,6 @@ impl GuestHandle { .expect("Failed to convert buffer to HostFunctionDetails") } - /// Write an error to the shared output data buffer. - #[hyperlight_guest_tracing::trace_function] - pub fn write_error(&self, error_code: ErrorCode, message: Option<&str>) { - let guest_error: GuestError = GuestError::new( - error_code, - message.map_or("".to_string(), |m| m.to_string()), - ); - let guest_error_buffer: Vec = (&guest_error) - .try_into() - .expect("Invalid guest_error_buffer, could not be converted to a Vec"); - - if let Err(e) = self.push_shared_output_data(&guest_error_buffer) { - panic!("Unable to push guest error to shared output data: {:#?}", e); - } - } - /// Log a message with the specified log level, source, caller, source file, and line number. #[hyperlight_guest_tracing::trace_function] pub fn log_message( diff --git a/src/hyperlight_guest_bin/Cargo.toml b/src/hyperlight_guest_bin/Cargo.toml index c21d00c91..31dfe4030 100644 --- a/src/hyperlight_guest_bin/Cargo.toml +++ b/src/hyperlight_guest_bin/Cargo.toml @@ -27,6 +27,8 @@ hyperlight-guest-tracing = { workspace = true, default-features = false } buddy_system_allocator = "0.11.0" log = { version = "0.4", default-features = false } spin = "0.10.0" +flatbuffers = { version = "25.2.10", default-features = false } + [lints] workspace = true diff --git a/src/hyperlight_guest_bin/src/guest_err.rs b/src/hyperlight_guest_bin/src/guest_err.rs deleted file mode 100644 index 0b384a391..000000000 --- a/src/hyperlight_guest_bin/src/guest_err.rs +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 2025 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -use core::ffi::{CStr, c_char}; - -use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode; -use hyperlight_guest::exit::halt; - -use crate::GUEST_HANDLE; - -/// Exposes a C API to allow the guest to set an error -/// -/// # Safety -/// TODO -/// cbindgen:ignore -#[unsafe(no_mangle)] -#[allow(non_camel_case_types)] -pub unsafe extern "C" fn setError(code: u64, message: *const c_char) { - let handle = unsafe { GUEST_HANDLE }; - - let error_code = ErrorCode::from(code); - match message.is_null() { - true => handle.write_error(error_code, None), - false => { - let message = unsafe { CStr::from_ptr(message).to_str().ok() } - .expect("Invalid error message, could not be converted to a string"); - handle.write_error(error_code, Some(message)); - } - } - - halt(); -} diff --git a/src/hyperlight_guest_bin/src/guest_function/call.rs b/src/hyperlight_guest_bin/src/guest_function/call.rs index 7eabdeb29..7bc3ca087 100644 --- a/src/hyperlight_guest_bin/src/guest_function/call.rs +++ b/src/hyperlight_guest_bin/src/guest_function/call.rs @@ -17,9 +17,10 @@ limitations under the License. use alloc::format; use alloc::vec::Vec; +use flatbuffers::FlatBufferBuilder; use hyperlight_common::flatbuffer_wrappers::function_call::{FunctionCall, FunctionCallType}; -use hyperlight_common::flatbuffer_wrappers::function_types::ParameterType; -use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode; +use hyperlight_common::flatbuffer_wrappers::function_types::{FunctionCallResult, ParameterType}; +use hyperlight_common::flatbuffer_wrappers::guest_error::{ErrorCode, GuestError}; use hyperlight_guest::error::{HyperlightGuestError, Result}; use hyperlight_guest::exit::halt; @@ -81,10 +82,12 @@ pub(crate) fn call_guest_function(function_call: FunctionCall) -> Result // This function is marked as no_mangle/inline to prevent the compiler from inlining it , if its inlined the epilogue will not be called // and we will leak memory as the epilogue will not be called as halt() is not going to return. +// +// This function may panic, as we have no other ways of dealing with errors at this level #[unsafe(no_mangle)] #[inline(never)] #[hyperlight_guest_tracing::trace_function] -fn internal_dispatch_function() -> Result<()> { +fn internal_dispatch_function() { let handle = unsafe { GUEST_HANDLE }; #[cfg(debug_assertions)] @@ -94,11 +97,24 @@ fn internal_dispatch_function() -> Result<()> { .try_pop_shared_input_data_into::() .expect("Function call deserialization failed"); - let result_vec = call_guest_function(function_call).inspect_err(|e| { - handle.write_error(e.kind, Some(e.message.as_str())); - })?; + let res = call_guest_function(function_call); - handle.push_shared_output_data(&result_vec) + match res { + Ok(bytes) => { + handle + .push_shared_output_data(bytes.as_slice()) + .expect("Failed to serialize function call result"); + } + Err(err) => { + let guest_error = Err(GuestError::new(err.kind, err.message)); + let fcr = FunctionCallResult::new(guest_error); + let mut builder = FlatBufferBuilder::new(); + let data = fcr.encode(&mut builder); + handle + .push_shared_output_data(data) + .expect("Failed to serialize function call result"); + } + } } // This is implemented as a separate function to make sure that epilogue in the internal_dispatch_function is called before the halt() @@ -117,6 +133,6 @@ pub(crate) extern "C" fn dispatch_function() { // part of the big identity-mapped region at the base of the // guest. crate::paging::flush_tlb(); - let _ = internal_dispatch_function(); + internal_dispatch_function(); halt(); } diff --git a/src/hyperlight_guest_bin/src/lib.rs b/src/hyperlight_guest_bin/src/lib.rs index 8686aab5e..1c6089a0e 100644 --- a/src/hyperlight_guest_bin/src/lib.rs +++ b/src/hyperlight_guest_bin/src/lib.rs @@ -45,7 +45,6 @@ pub mod exceptions { pub(super) mod idtr; mod interrupt_entry; } -pub mod guest_err; pub mod guest_function { pub(super) mod call; pub mod definition; @@ -121,7 +120,7 @@ pub(crate) static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::empty(); pub(crate) static HEAP_ALLOCATOR: ProfiledLockedHeap<32> = ProfiledLockedHeap(LockedHeap::<32>::empty()); -pub(crate) static mut GUEST_HANDLE: GuestHandle = GuestHandle::new(); +pub static mut GUEST_HANDLE: GuestHandle = GuestHandle::new(); pub(crate) static mut REGISTERED_GUEST_FUNCTIONS: GuestFunctionRegister = GuestFunctionRegister::new(); diff --git a/src/hyperlight_guest_capi/Cargo.toml b/src/hyperlight_guest_capi/Cargo.toml index 66bc454ab..1a9c277c2 100644 --- a/src/hyperlight_guest_capi/Cargo.toml +++ b/src/hyperlight_guest_capi/Cargo.toml @@ -15,6 +15,8 @@ workspace = true hyperlight-guest = { workspace = true, default-features = false } hyperlight-guest-bin = { workspace = true, default-features = true } hyperlight-common = { workspace = true, default-features = false } + +flatbuffers = { version = "25.2.10", default-features = false } log = { version = "0.4", default-features = false } [build-dependencies] diff --git a/src/hyperlight_guest_capi/src/error.rs b/src/hyperlight_guest_capi/src/error.rs index a6be2bf59..03217600e 100644 --- a/src/hyperlight_guest_capi/src/error.rs +++ b/src/hyperlight_guest_capi/src/error.rs @@ -14,15 +14,32 @@ See the License for the specific language governing permissions and limitations under the License. */ -use core::ffi::c_char; +use core::ffi::{CStr, c_char}; -use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode; -use hyperlight_guest_bin::guest_err::setError; +use flatbuffers::FlatBufferBuilder; +use hyperlight_common::flatbuffer_wrappers::function_types::FunctionCallResult; +use hyperlight_common::flatbuffer_wrappers::guest_error::{ErrorCode, GuestError}; +use hyperlight_guest_bin::GUEST_HANDLE; + +use crate::alloc::borrow::ToOwned; #[unsafe(no_mangle)] pub extern "C" fn hl_set_error(err: ErrorCode, message: *const c_char) { + let cstr = unsafe { CStr::from_ptr(message) }; + let guest_error = Err(GuestError::new( + err.into(), + cstr.to_str() + .expect("Failed to convert CStr to &str") + .to_owned(), + )); + let fcr = FunctionCallResult::new(guest_error); + let mut builder = FlatBufferBuilder::new(); + let data = fcr.encode(&mut builder); unsafe { - setError(err.into(), message); + #[allow(static_mut_refs)] // we are single threaded + GUEST_HANDLE + .push_shared_output_data(data) + .expect("Failed to set error") } } diff --git a/src/hyperlight_host/src/func/guest_err.rs b/src/hyperlight_host/src/func/guest_err.rs deleted file mode 100644 index 27db6d231..000000000 --- a/src/hyperlight_host/src/func/guest_err.rs +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2025 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode; - -use crate::error::HyperlightError::{GuestError, StackOverflow}; -use crate::mem::mgr::SandboxMemoryManager; -use crate::mem::shared_mem::HostSharedMemory; -use crate::metrics::{METRIC_GUEST_ERROR, METRIC_GUEST_ERROR_LABEL_CODE}; -use crate::{Result, log_then_return}; - -/// Check for a guest error and return an `Err` if one was found, -/// and `Ok` if one was not found. -pub(crate) fn check_for_guest_error( - mgr: &mut SandboxMemoryManager, -) -> Result<()> { - let guest_err = mgr.get_guest_error().ok(); - let Some(guest_err) = guest_err else { - return Ok(()); - }; - - metrics::counter!( - METRIC_GUEST_ERROR, - METRIC_GUEST_ERROR_LABEL_CODE => (guest_err.code as u64).to_string() - ) - .increment(1); - - match guest_err.code { - ErrorCode::NoError => Ok(()), - ErrorCode::StackOverflow => { - log_then_return!(StackOverflow()); - } - _ => { - log_then_return!(GuestError(guest_err.code, guest_err.message.clone())); - } - } -} diff --git a/src/hyperlight_host/src/func/mod.rs b/src/hyperlight_host/src/func/mod.rs index 57b69dbc4..4290d503d 100644 --- a/src/hyperlight_host/src/func/mod.rs +++ b/src/hyperlight_host/src/func/mod.rs @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -/// Functionality to check for errors after a guest call -pub(crate) mod guest_err; /// Definitions and functionality to enable guest-to-host function calling, /// also called "host functions" /// diff --git a/src/hyperlight_host/src/mem/mgr.rs b/src/hyperlight_host/src/mem/mgr.rs index 7d9d0d288..0a5e0916e 100644 --- a/src/hyperlight_host/src/mem/mgr.rs +++ b/src/hyperlight_host/src/mem/mgr.rs @@ -16,11 +16,11 @@ limitations under the License. use std::cmp::Ordering; +use flatbuffers::FlatBufferBuilder; use hyperlight_common::flatbuffer_wrappers::function_call::{ FunctionCall, validate_guest_function_call_buffer, }; -use hyperlight_common::flatbuffer_wrappers::function_types::ReturnValue; -use hyperlight_common::flatbuffer_wrappers::guest_error::GuestError; +use hyperlight_common::flatbuffer_wrappers::function_types::FunctionCallResult; use hyperlight_common::flatbuffer_wrappers::guest_log_data::GuestLogData; use hyperlight_common::flatbuffer_wrappers::host_function_details::HostFunctionDetails; use tracing::{Span, instrument}; @@ -501,18 +501,19 @@ impl SandboxMemoryManager { ) } - /// Writes a function call result to memory + /// Writes a host function call result to memory #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] - pub(crate) fn write_response_from_host_method_call(&mut self, res: &ReturnValue) -> Result<()> { - let function_call_ret_val_buffer = Vec::::try_from(res).map_err(|_| { - new_error!( - "write_response_from_host_method_call: failed to convert ReturnValue to Vec" - ) - })?; + pub(crate) fn write_response_from_host_function_call( + &mut self, + res: &FunctionCallResult, + ) -> Result<()> { + let mut builder = FlatBufferBuilder::new(); + let data = res.encode(&mut builder); + self.shared_mem.push_buffer( self.layout.input_data_buffer_offset, self.layout.sandbox_memory_config.get_input_data_size(), - function_call_ret_val_buffer.as_slice(), + data, ) } @@ -533,10 +534,11 @@ impl SandboxMemoryManager { ) } - /// Reads a function call result from memory + /// Reads a function call result from memory. + /// A function call result can be either an error or a successful return value. #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] - pub(crate) fn get_guest_function_call_result(&mut self) -> Result { - self.shared_mem.try_pop_buffer_into::( + pub(crate) fn get_guest_function_call_result(&mut self) -> Result { + self.shared_mem.try_pop_buffer_into::( self.layout.output_data_buffer_offset, self.layout.sandbox_memory_config.get_output_data_size(), ) @@ -551,14 +553,6 @@ impl SandboxMemoryManager { ) } - /// Get the guest error data - pub(crate) fn get_guest_error(&mut self) -> Result { - self.shared_mem.try_pop_buffer_into::( - self.layout.output_data_buffer_offset, - self.layout.sandbox_memory_config.get_output_data_size(), - ) - } - pub(crate) fn clear_io_buffers(&mut self) { // Clear the output data buffer loop { diff --git a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs index b80a7c960..817c48251 100644 --- a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs +++ b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs @@ -28,14 +28,14 @@ use hyperlight_common::flatbuffer_wrappers::function_call::{FunctionCall, Functi use hyperlight_common::flatbuffer_wrappers::function_types::{ ParameterValue, ReturnType, ReturnValue, }; +use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode; use hyperlight_common::flatbuffer_wrappers::util::estimate_flatbuffer_capacity; use tracing::{Span, instrument}; use super::Callable; use super::host_funcs::FunctionRegistry; use super::snapshot::Snapshot; -use crate::HyperlightError::SnapshotSandboxMismatch; -use crate::func::guest_err::check_for_guest_error; +use crate::HyperlightError::{self, SnapshotSandboxMismatch}; use crate::func::{ParameterTuple, SupportedReturnType}; use crate::hypervisor::{Hypervisor, InterruptHandle}; #[cfg(unix)] @@ -44,7 +44,9 @@ use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags}; use crate::mem::mgr::SandboxMemoryManager; use crate::mem::ptr::RawPtr; use crate::mem::shared_mem::HostSharedMemory; -use crate::metrics::maybe_time_and_emit_guest_call; +use crate::metrics::{ + METRIC_GUEST_ERROR, METRIC_GUEST_ERROR_LABEL_CODE, maybe_time_and_emit_guest_call, +}; use crate::{Result, log_then_return}; /// Global counter for assigning unique IDs to sandboxes @@ -410,9 +412,24 @@ impl MultiUseSandbox { )?; self.mem_mgr.check_stack_guard()?; - check_for_guest_error(&mut self.mem_mgr)?; - self.mem_mgr.get_guest_function_call_result() + let guest_result = self.mem_mgr.get_guest_function_call_result()?.into_inner(); + + match guest_result { + Ok(val) => Ok(val), + Err(guest_error) => { + metrics::counter!( + METRIC_GUEST_ERROR, + METRIC_GUEST_ERROR_LABEL_CODE => (guest_error.code as u64).to_string() + ) + .increment(1); + + Err(match guest_error.code { + ErrorCode::StackOverflow => HyperlightError::StackOverflow(), + _ => HyperlightError::GuestError(guest_error.code, guest_error.message), + }) + } + } })(); // In the happy path we do not need to clear io-buffers from the host because: @@ -493,6 +510,43 @@ mod tests { use crate::sandbox::SandboxConfiguration; use crate::{GuestBinary, HyperlightError, MultiUseSandbox, Result, UninitializedSandbox}; + /// Make sure input/output buffers are properly reset after guest call (with host call) + #[test] + fn host_func_error() { + let path = simple_guest_as_string().unwrap(); + let mut sandbox = UninitializedSandbox::new(GuestBinary::FilePath(path), None).unwrap(); + sandbox + .register("HostError", || -> Result<()> { + Err(HyperlightError::Error("hi".to_string())) + }) + .unwrap(); + let mut sandbox = sandbox.evolve().unwrap(); + + // will exhaust io if leaky + for _ in 0..1000 { + let result = sandbox + .call::( + "CallGivenParamlessHostFuncThatReturnsI64", + "HostError".to_string(), + ) + .unwrap_err(); + + assert!( + matches!(result, HyperlightError::GuestError(code, msg) if code == ErrorCode::HostFunctionError && msg == "hi"), + ); + } + } + + #[test] + fn call_host_func_expect_error() { + let path = simple_guest_as_string().unwrap(); + let sandbox = UninitializedSandbox::new(GuestBinary::FilePath(path), None).unwrap(); + let mut sandbox = sandbox.evolve().unwrap(); + sandbox + .call::<()>("CallHostExpectError", "SomeUnknownHostFunc".to_string()) + .unwrap(); + } + /// Make sure input/output buffers are properly reset after guest call (with host call) #[test] fn io_buffer_reset() { @@ -606,6 +660,9 @@ mod tests { #[ignore] #[cfg(target_os = "linux")] fn test_violate_seccomp_filters() -> Result<()> { + #[cfg(feature = "seccomp")] + use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode; + fn make_get_pid_syscall() -> Result { let pid = unsafe { libc::syscall(libc::SYS_getpid) }; Ok(pid as u64) @@ -629,7 +686,9 @@ mod tests { match res { Ok(_) => panic!("Expected to fail due to seccomp violation"), Err(e) => match e { - HyperlightError::DisallowedSyscall => {} + HyperlightError::GuestError(t, msg) + if t == ErrorCode::HostFunctionError + && msg.contains("Seccomp filter trapped on disallowed syscall") => {} _ => panic!("Expected DisallowedSyscall error: {}", e), }, } diff --git a/src/hyperlight_host/src/sandbox/outb.rs b/src/hyperlight_host/src/sandbox/outb.rs index 8f9c1166f..6e59c5367 100644 --- a/src/hyperlight_host/src/sandbox/outb.rs +++ b/src/hyperlight_host/src/sandbox/outb.rs @@ -22,8 +22,8 @@ use std::sync::{Arc, Mutex}; use fallible_iterator::FallibleIterator; #[cfg(feature = "unwind_guest")] use framehop::Unwinder; -use hyperlight_common::flatbuffer_wrappers::function_types::ParameterValue; -use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode; +use hyperlight_common::flatbuffer_wrappers::function_types::{FunctionCallResult, ParameterValue}; +use hyperlight_common::flatbuffer_wrappers::guest_error::{ErrorCode, GuestError}; use hyperlight_common::flatbuffer_wrappers::guest_log_data::GuestLogData; use hyperlight_common::outb::{Exception, OutBAction}; #[cfg(feature = "trace_guest")] @@ -283,8 +283,12 @@ pub(crate) fn handle_outb( let res = host_funcs .try_lock() .map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))? - .call_host_function(&name, args)?; - mem_mgr.write_response_from_host_method_call(&res)?; // push input buffers + .call_host_function(&name, args) + .map_err(|e| GuestError::new(ErrorCode::HostFunctionError, e.to_string())); + + let func_result = FunctionCallResult::new(res); + + mem_mgr.write_response_from_host_function_call(&func_result)?; Ok(()) } diff --git a/src/hyperlight_host/tests/sandbox_host_tests.rs b/src/hyperlight_host/tests/sandbox_host_tests.rs index 5255cd811..cfcc0e6c6 100644 --- a/src/hyperlight_host/tests/sandbox_host_tests.rs +++ b/src/hyperlight_host/tests/sandbox_host_tests.rs @@ -351,10 +351,17 @@ fn host_function_error() -> Result<()> { // call guest function that calls host function let mut init_sandbox: MultiUseSandbox = sandbox.evolve()?; let msg = "Hello world"; - let res = init_sandbox - .call::("GuestMethod1", msg.to_string()) - .unwrap_err(); - assert!(matches!(res, HyperlightError::Error(msg) if msg == "Host function error!")); + + for _ in 0..1000 { + let res = init_sandbox + .call::("GuestMethod1", msg.to_string()) + .unwrap_err(); + assert!( + matches!(&res, HyperlightError::GuestError(_, msg) if msg == "Host function error!") // rust guest + || matches!(&res, HyperlightError::GuestAborted(_, msg) if msg.contains("Host function error!")) // c guest + || matches!(&res, HyperlightError::StackOverflow()) // c guest. TODO fix this. C guest leaks when host func returns error guest panics. + ); + } } Ok(()) } diff --git a/src/schema/all.fbs b/src/schema/all.fbs new file mode 100644 index 000000000..9e70a50b8 --- /dev/null +++ b/src/schema/all.fbs @@ -0,0 +1,7 @@ +include "function_types.fbs"; +include "function_call_result.fbs"; +include "function_call.fbs"; +include "guest_error.fbs"; +include "guest_log_data.fbs"; +include "host_function_definition.fbs"; +include "host_function_details.fbs"; \ No newline at end of file diff --git a/src/schema/function_call_result.fbs b/src/schema/function_call_result.fbs index 28a5b6fe3..53ea52b25 100644 --- a/src/schema/function_call_result.fbs +++ b/src/schema/function_call_result.fbs @@ -1,9 +1,21 @@ include "function_types.fbs"; +include "guest_error.fbs"; namespace Hyperlight.Generated; +// Wrapper so ReturnValue (a union) can be a single union variant +table ReturnValueBox { + value: ReturnValue (required); +} + +// Result-like union +union FunctionCallResultType { + ReturnValueBox, + GuestError +} + table FunctionCallResult { - return_value:ReturnValue(required); + result: FunctionCallResultType (required); } root_type FunctionCallResult; \ No newline at end of file diff --git a/src/schema/guest_error.fbs b/src/schema/guest_error.fbs index fca2cc0b0..14dfa85e4 100644 --- a/src/schema/guest_error.fbs +++ b/src/schema/guest_error.fbs @@ -16,7 +16,8 @@ enum ErrorCode: ulong { MallocFailed = 13, // this error is set when malloc returns 0 bytes. GuestFunctionParameterTypeMismatch = 14, // The function call parameter type was not the expected type. GuestError = 15, // An error occurred in the guest Guest implementation should use this along with a message when calling setError. - ArrayLengthParamIsMissing = 16 // Expected a int parameter to follow a byte array + ArrayLengthParamIsMissing = 16, // Expected a int parameter to follow a byte array + HostError = 17 // Guest called Host Function, which errored. } table GuestError { diff --git a/src/tests/rust_guests/dummyguest/Cargo.lock b/src/tests/rust_guests/dummyguest/Cargo.lock index fa3de189b..173932b4b 100644 --- a/src/tests/rust_guests/dummyguest/Cargo.lock +++ b/src/tests/rust_guests/dummyguest/Cargo.lock @@ -96,6 +96,7 @@ dependencies = [ "buddy_system_allocator", "cc", "cfg-if", + "flatbuffers", "glob", "hyperlight-common", "hyperlight-guest", diff --git a/src/tests/rust_guests/simpleguest/Cargo.lock b/src/tests/rust_guests/simpleguest/Cargo.lock index b9380c8e0..573560b83 100644 --- a/src/tests/rust_guests/simpleguest/Cargo.lock +++ b/src/tests/rust_guests/simpleguest/Cargo.lock @@ -88,6 +88,7 @@ dependencies = [ "buddy_system_allocator", "cc", "cfg-if", + "flatbuffers", "glob", "hyperlight-common", "hyperlight-guest", diff --git a/src/tests/rust_guests/simpleguest/src/main.rs b/src/tests/rust_guests/simpleguest/src/main.rs index 681165a60..bdf8d5f62 100644 --- a/src/tests/rust_guests/simpleguest/src/main.rs +++ b/src/tests/rust_guests/simpleguest/src/main.rs @@ -939,9 +939,45 @@ fn exec_mapped_buffer(function_call: &FunctionCall) -> Result> { } } +fn call_host_expect_error(function_call: &FunctionCall) -> Result> { + if let ParameterValue::String(hostfuncname) = + function_call.parameters.clone().unwrap()[0].clone() + { + let res = call_host_function::(&hostfuncname, None, ReturnType::Int); + + match res { + Ok(_) => Err(HyperlightGuestError::new( + ErrorCode::GuestError, + "Expected host function to fail, but it succeeded".to_string(), + )), + Err(e) => { + assert_eq!(e.kind, ErrorCode::HostFunctionError); + assert_eq!( + e.message, + format!("HostFunction {} was not found", hostfuncname) + ); + Ok(get_flatbuffer_result(())) + } + } + } else { + Err(HyperlightGuestError::new( + ErrorCode::GuestFunctionParameterTypeMismatch, + "Invalid parameters passed to call_host_expect_error".to_string(), + )) + } +} + #[no_mangle] #[hyperlight_guest_tracing::trace_function] pub extern "C" fn hyperlight_main() { + let expect_error_def = GuestFunctionDefinition::new( + "CallHostExpectError".to_string(), + Vec::from(&[ParameterType::String]), + ReturnType::Void, + call_host_expect_error as usize, + ); + register_function(expect_error_def); + let twenty_four_k_in_def = GuestFunctionDefinition::new( "24K_in_8K_out".to_string(), Vec::from(&[ParameterType::VecBytes]), diff --git a/src/tests/rust_guests/witguest/Cargo.lock b/src/tests/rust_guests/witguest/Cargo.lock index 6a33cb503..7265deae2 100644 --- a/src/tests/rust_guests/witguest/Cargo.lock +++ b/src/tests/rust_guests/witguest/Cargo.lock @@ -231,6 +231,7 @@ dependencies = [ "buddy_system_allocator", "cc", "cfg-if", + "flatbuffers", "glob", "hyperlight-common", "hyperlight-guest",