Skip to content

Commit 3af19d5

Browse files
committed
move function type traits to hyperlight_common
Signed-off-by: Jorge Prendes <jorge.prendes@gmail.com>
1 parent 36d3767 commit 3af19d5

File tree

12 files changed

+234
-92
lines changed

12 files changed

+234
-92
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/hyperlight_common/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,16 @@ log = "0.4.27"
2121
tracing = { version = "0.1.41", optional = true }
2222
arbitrary = {version = "1.4.2", optional = true, features = ["derive"]}
2323
spin = "0.10.0"
24+
thiserror = { version = "2.0.16", default-features = false }
2425

2526
[features]
2627
default = ["tracing"]
28+
tracing = ["dep:tracing"]
2729
fuzzing = ["dep:arbitrary"]
2830
trace_guest = []
2931
unwind_guest = []
3032
mem_profile = []
31-
std = []
33+
std = ["thiserror/std", "log/std", "tracing/std"]
3234

3335
[dev-dependencies]
3436
hyperlight-testing = { workspace = true }
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
Copyright 2025 The Hyperlight Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
use alloc::string::String;
18+
19+
use thiserror::Error;
20+
21+
use crate::func::{ParameterValue, ReturnValue};
22+
23+
/// The error type for Hyperlight operations
24+
#[derive(Error, Debug)]
25+
pub enum Error {
26+
/// Failed to get value from parameter value
27+
#[error("Failed To Convert Parameter Value {0:?} to {1:?}")]
28+
ParameterValueConversionFailure(ParameterValue, &'static str),
29+
30+
/// Failed to get value from return value
31+
#[error("Failed To Convert Return Value {0:?} to {1:?}")]
32+
ReturnValueConversionFailure(ReturnValue, &'static str),
33+
34+
/// A function was called with an incorrect number of arguments
35+
#[error("The number of arguments to the function is wrong: got {0:?} expected {1:?}")]
36+
UnexpectedNoOfArguments(usize, usize),
37+
38+
/// The parameter value type is unexpected
39+
#[error("The parameter value type is unexpected got {0:?} expected {1:?}")]
40+
UnexpectedParameterValueType(ParameterValue, String),
41+
42+
/// The return value type is unexpected
43+
#[error("The return value type is unexpected got {0:?} expected {1:?}")]
44+
UnexpectedReturnValueType(ReturnValue, String),
45+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
Copyright 2025 The Hyperlight Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
use super::utils::for_each_tuple;
18+
use super::{Error, ParameterTuple, ResultType, SupportedReturnType};
19+
20+
pub trait Function<Output: SupportedReturnType, Args: ParameterTuple, E: From<Error>> {
21+
fn call(&self, args: Args) -> Result<Output, E>;
22+
}
23+
24+
macro_rules! impl_function {
25+
([$N:expr] ($($p:ident: $P:ident),*)) => {
26+
impl<F, R, E, $($P),*> Function<R::ReturnType, ($($P,)*), E> for F
27+
where
28+
F: Fn($($P),*) -> R,
29+
($($P,)*): ParameterTuple,
30+
R: ResultType<E>,
31+
E: From<Error>,
32+
{
33+
fn call(&self, ($($p,)*): ($($P,)*)) -> Result<R::ReturnType, E> {
34+
(self)($($p),*).into_result()
35+
}
36+
}
37+
};
38+
}
39+
40+
for_each_tuple!(impl_function);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
Copyright 2025 The Hyperlight Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
/// Error types related to function support
18+
pub(crate) mod error;
19+
/// Definitions and functionality to enable guest-to-host function calling,
20+
/// also called "host functions"
21+
///
22+
/// This module includes functionality to do the following
23+
///
24+
/// - Define several prototypes for what a host function must look like,
25+
/// including the number of arguments (arity) they can have, supported argument
26+
/// types, and supported return types
27+
/// - Registering host functions to be callable by the guest
28+
/// - Dynamically dispatching a call from the guest to the appropriate
29+
/// host function
30+
pub(crate) mod functions;
31+
/// Definitions and functionality for supported parameter types
32+
pub(crate) mod param_type;
33+
/// Definitions and functionality for supported return types
34+
pub(crate) mod ret_type;
35+
36+
pub use error::Error;
37+
/// Re-export for `HostFunction` trait
38+
pub use functions::Function;
39+
pub use param_type::{ParameterTuple, SupportedParameterType};
40+
pub use ret_type::{ResultType, SupportedReturnType};
41+
42+
/// Re-export for `ParameterValue` enum
43+
pub use crate::flatbuffer_wrappers::function_types::ParameterValue;
44+
/// Re-export for `ReturnType` enum
45+
pub use crate::flatbuffer_wrappers::function_types::ReturnType;
46+
/// Re-export for `ReturnType` enum
47+
pub use crate::flatbuffer_wrappers::function_types::ReturnValue;
48+
49+
mod utils;

src/hyperlight_host/src/func/param_type.rs renamed to src/hyperlight_common/src/func/param_type.rs

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
use hyperlight_common::flatbuffer_wrappers::function_types::{ParameterType, ParameterValue};
18-
use tracing::{Span, instrument};
17+
use alloc::string::String;
18+
use alloc::vec;
19+
use alloc::vec::Vec;
1920

21+
use super::error::Error;
2022
use super::utils::for_each_tuple;
21-
use crate::HyperlightError::{ParameterValueConversionFailure, UnexpectedNoOfArguments};
22-
use crate::{Result, log_then_return};
23+
use crate::flatbuffer_wrappers::function_types::{ParameterType, ParameterValue};
2324

2425
/// This is a marker trait that is used to indicate that a type is a
2526
/// valid Hyperlight parameter type.
@@ -34,7 +35,7 @@ pub trait SupportedParameterType: Sized + Clone + Send + Sync + 'static {
3435
/// `SupportedParameterType`
3536
fn into_value(self) -> ParameterValue;
3637
/// Get the actual inner value of this `SupportedParameterType`
37-
fn from_value(value: ParameterValue) -> Result<Self>;
38+
fn from_value(value: ParameterValue) -> Result<Self, Error>;
3839
}
3940

4041
// We can then implement these traits for each type that Hyperlight supports as a parameter or return type
@@ -57,21 +58,17 @@ macro_rules! impl_supported_param_type {
5758
impl SupportedParameterType for $type {
5859
const TYPE: ParameterType = ParameterType::$enum;
5960

60-
#[instrument(skip_all, parent = Span::current(), level= "Trace")]
6161
fn into_value(self) -> ParameterValue {
6262
ParameterValue::$enum(self)
6363
}
6464

65-
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
66-
fn from_value(value: ParameterValue) -> Result<Self> {
65+
fn from_value(value: ParameterValue) -> Result<Self, Error> {
6766
match value {
6867
ParameterValue::$enum(i) => Ok(i),
69-
other => {
70-
log_then_return!(ParameterValueConversionFailure(
71-
other.clone(),
72-
stringify!($type)
73-
));
74-
}
68+
other => Err(Error::ParameterValueConversionFailure(
69+
other.clone(),
70+
stringify!($type),
71+
)),
7572
}
7673
}
7774
}
@@ -93,26 +90,22 @@ pub trait ParameterTuple: Sized + Clone + Send + Sync + 'static {
9390
fn into_value(self) -> Vec<ParameterValue>;
9491

9592
/// Get the actual inner value of this `SupportedParameterType`
96-
fn from_value(value: Vec<ParameterValue>) -> Result<Self>;
93+
fn from_value(value: Vec<ParameterValue>) -> Result<Self, Error>;
9794
}
9895

9996
impl<T: SupportedParameterType> ParameterTuple for T {
10097
const SIZE: usize = 1;
10198

10299
const TYPE: &[ParameterType] = &[T::TYPE];
103100

104-
#[instrument(skip_all, parent = Span::current(), level= "Trace")]
105101
fn into_value(self) -> Vec<ParameterValue> {
106102
vec![self.into_value()]
107103
}
108104

109-
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
110-
fn from_value(value: Vec<ParameterValue>) -> Result<Self> {
105+
fn from_value(value: Vec<ParameterValue>) -> Result<Self, Error> {
111106
match <[ParameterValue; 1]>::try_from(value) {
112107
Ok([val]) => Ok(T::from_value(val)?),
113-
Err(value) => {
114-
log_then_return!(UnexpectedNoOfArguments(value.len(), 1));
115-
}
108+
Err(value) => Err(Error::UnexpectedNoOfArguments(value.len(), 1)),
116109
}
117110
}
118111
}
@@ -126,17 +119,15 @@ macro_rules! impl_param_tuple {
126119
$($param::TYPE),*
127120
];
128121

129-
#[instrument(skip_all, parent = Span::current(), level= "Trace")]
130122
fn into_value(self) -> Vec<ParameterValue> {
131123
let ($($name,)*) = self;
132124
vec![$($name.into_value()),*]
133125
}
134126

135-
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
136-
fn from_value(value: Vec<ParameterValue>) -> Result<Self> {
127+
fn from_value(value: Vec<ParameterValue>) -> Result<Self, Error> {
137128
match <[ParameterValue; $N]>::try_from(value) {
138129
Ok([$($name,)*]) => Ok(($($param::from_value($name)?,)*)),
139-
Err(value) => { log_then_return!(UnexpectedNoOfArguments(value.len(), $N)); }
130+
Err(value) => Err(Error::UnexpectedNoOfArguments(value.len(), $N))
140131
}
141132
}
142133
}

src/hyperlight_host/src/func/ret_type.rs renamed to src/hyperlight_common/src/func/ret_type.rs

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
use hyperlight_common::flatbuffer_wrappers::function_types::{ReturnType, ReturnValue};
18-
use tracing::{Span, instrument};
17+
use alloc::string::String;
18+
use alloc::vec::Vec;
1919

20-
use crate::HyperlightError::ReturnValueConversionFailure;
21-
use crate::{Result, log_then_return};
20+
use super::error::Error;
21+
use crate::flatbuffer_wrappers::function_types::{ReturnType, ReturnValue};
2222

2323
/// This is a marker trait that is used to indicate that a type is a valid Hyperlight return type.
2424
pub trait SupportedReturnType: Sized + Clone + Send + Sync + 'static {
@@ -29,16 +29,7 @@ pub trait SupportedReturnType: Sized + Clone + Send + Sync + 'static {
2929
fn into_value(self) -> ReturnValue;
3030

3131
/// Gets the inner value of the supported return type
32-
fn from_value(value: ReturnValue) -> Result<Self>;
33-
}
34-
35-
/// A trait to handle either a [`SupportedReturnType`] or a [`Result<impl SupportedReturnType>`]
36-
pub trait ResultType {
37-
/// The return type of the supported return value
38-
type ReturnType: SupportedReturnType;
39-
40-
/// Convert the return type into a `Result<impl SupportedReturnType>`
41-
fn into_result(self) -> Result<Self::ReturnType>;
32+
fn from_value(value: ReturnValue) -> Result<Self, Error>;
4233
}
4334

4435
macro_rules! for_each_return_type {
@@ -61,43 +52,46 @@ macro_rules! impl_supported_return_type {
6152
impl SupportedReturnType for $type {
6253
const TYPE: ReturnType = ReturnType::$enum;
6354

64-
#[instrument(skip_all, parent = Span::current(), level= "Trace")]
6555
fn into_value(self) -> ReturnValue {
6656
ReturnValue::$enum(self)
6757
}
6858

69-
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
70-
fn from_value(value: ReturnValue) -> Result<Self> {
59+
fn from_value(value: ReturnValue) -> Result<Self, Error> {
7160
match value {
7261
ReturnValue::$enum(i) => Ok(i),
73-
other => {
74-
log_then_return!(ReturnValueConversionFailure(
75-
other.clone(),
76-
stringify!($type)
77-
));
78-
}
62+
other => Err(Error::ReturnValueConversionFailure(
63+
other.clone(),
64+
stringify!($type),
65+
)),
7966
}
8067
}
8168
}
69+
};
70+
}
71+
72+
/// A trait to handle either a [`SupportedReturnType`] or a [`Result<impl SupportedReturnType>`]
73+
pub trait ResultType<E> {
74+
/// The return type of the supported return value
75+
type ReturnType: SupportedReturnType;
8276

83-
impl ResultType for $type {
84-
type ReturnType = $type;
77+
/// Convert the return type into a `Result<impl SupportedReturnType>`
78+
fn into_result(self) -> Result<Self::ReturnType, E>;
79+
}
8580

86-
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
87-
fn into_result(self) -> Result<Self::ReturnType> {
88-
Ok(self)
89-
}
90-
}
81+
impl<T: SupportedReturnType, E> ResultType<E> for T {
82+
type ReturnType = T;
9183

92-
impl ResultType for Result<$type> {
93-
type ReturnType = $type;
84+
fn into_result(self) -> Result<Self::ReturnType, E> {
85+
Ok(self)
86+
}
87+
}
9488

95-
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
96-
fn into_result(self) -> Result<Self::ReturnType> {
97-
self
98-
}
99-
}
100-
};
89+
impl<T: SupportedReturnType, E> ResultType<E> for Result<T, E> {
90+
type ReturnType = T;
91+
92+
fn into_result(self) -> Result<Self::ReturnType, E> {
93+
self
94+
}
10195
}
10296

10397
for_each_return_type!(impl_supported_return_type);

src/hyperlight_host/src/func/utils.rs renamed to src/hyperlight_common/src/func/utils.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ limitations under the License.
3131
///
3232
/// for_each_tuple!(my_macro);
3333
/// ```
34+
#[doc(hidden)]
35+
#[macro_export]
3436
macro_rules! for_each_tuple {
3537
(@
3638
$macro:ident

src/hyperlight_common/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,6 @@ pub mod outb;
4242

4343
/// cbindgen:ignore
4444
pub mod resource;
45+
46+
/// cbindgen:ignore
47+
pub mod func;

0 commit comments

Comments
 (0)