Skip to main content

hyperlight_guest_bin/guest_function/
register.rs

1/*
2Copyright 2025  The Hyperlight Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17use alloc::collections::BTreeMap;
18use alloc::string::String;
19
20use hyperlight_common::func::{ParameterTuple, SupportedReturnType};
21
22use super::definition::{GuestFunc, GuestFunctionDefinition};
23use crate::REGISTERED_GUEST_FUNCTIONS;
24use crate::guest_function::definition::AsGuestFunctionDefinition;
25
26/// Represents the functions that the guest exposes to the host.
27#[derive(Debug, Clone)]
28pub struct GuestFunctionRegister<F: Copy> {
29    /// Currently registered guest functions
30    guest_functions: BTreeMap<String, GuestFunctionDefinition<F>>,
31}
32
33impl<F: Copy> Default for GuestFunctionRegister<F> {
34    fn default() -> Self {
35        Self {
36            guest_functions: BTreeMap::new(),
37        }
38    }
39}
40
41impl<F: Copy> GuestFunctionRegister<F> {
42    /// Create a new `GuestFunctionRegister`.
43    pub const fn new() -> Self {
44        Self {
45            guest_functions: BTreeMap::new(),
46        }
47    }
48
49    /// Register a new `GuestFunctionDefinition` into self.
50    /// If a function with the same name already exists, it will be replaced.
51    /// None is returned if the function name was not previously registered,
52    /// otherwise the previous `GuestFunctionDefinition` is returned.
53    pub fn register(
54        &mut self,
55        guest_function: GuestFunctionDefinition<F>,
56    ) -> Option<GuestFunctionDefinition<F>> {
57        self.guest_functions
58            .insert(guest_function.function_name.clone(), guest_function)
59    }
60
61    /// Gets a `GuestFunctionDefinition` by its `name` field.
62    pub fn get(&self, function_name: &str) -> Option<&GuestFunctionDefinition<F>> {
63        self.guest_functions.get(function_name)
64    }
65}
66
67impl GuestFunctionRegister<GuestFunc> {
68    pub fn register_fn<Output, Args>(
69        &mut self,
70        name: impl Into<String>,
71        f: impl AsGuestFunctionDefinition<Output, Args>,
72    ) where
73        Args: ParameterTuple,
74        Output: SupportedReturnType,
75    {
76        let gfd = f.as_guest_function_definition(name);
77        self.register(gfd);
78    }
79}
80
81pub fn register_function(function_definition: GuestFunctionDefinition<GuestFunc>) {
82    unsafe {
83        // This is currently safe, because we are single threaded, but we
84        // should find a better way to do this, see issue #808
85        #[allow(static_mut_refs)]
86        let gfd = &mut REGISTERED_GUEST_FUNCTIONS;
87        gfd.register(function_definition);
88    }
89}
90
91pub fn register_fn<Output, Args>(
92    name: impl Into<String>,
93    f: impl AsGuestFunctionDefinition<Output, Args>,
94) where
95    Args: ParameterTuple,
96    Output: SupportedReturnType,
97{
98    unsafe {
99        // This is currently safe, because we are single threaded, but we
100        // should find a better way to do this, see issue #808
101        #[allow(static_mut_refs)]
102        let gfd = &mut REGISTERED_GUEST_FUNCTIONS;
103        gfd.register_fn(name, f);
104    }
105}