Skip to content

Commit af74f30

Browse files
committed
Fix host call with no return type
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
1 parent e4c7006 commit af74f30

File tree

5 files changed

+45
-5
lines changed

5 files changed

+45
-5
lines changed

src/component_sample/src/bindings.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,16 @@ pub mod exports {
118118
.cast::<usize>();
119119
_rt::cabi_dealloc(l0, l1, 1);
120120
}
121+
#[doc(hidden)]
122+
#[allow(non_snake_case)]
123+
pub unsafe fn _export_do_something_cabi<T: Guest>(arg0: i32) {
124+
#[cfg(target_arch = "wasm32")] _rt::run_ctors_once();
125+
T::do_something(arg0 as u32);
126+
}
121127
pub trait Guest {
122128
fn add(left: u32, right: u32) -> u32;
123129
fn call_host(input: _rt::String) -> _rt::String;
130+
fn do_something(number: u32) -> ();
124131
}
125132
#[doc(hidden)]
126133
macro_rules! __export_component_sample_example_adder_cabi {

src/component_sample/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ impl Guest for Component {
1414

1515
fn call_host(input: String) -> String {
1616
let host_result = host_function(&format!("{} from component", &input));
17-
print(&host_result);
1817
host_result.to_string()
1918
}
19+
20+
fn do_something(number: u32) {
21+
print(&format!("{number}"));
22+
}
2023
}
2124

2225
bindings::export!(Component with_types_in bindings);

src/component_sample/wit/example.wit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ world example {
88
interface adder {
99
add: func(left: u32, right: u32) -> u32;
1010
call-host: func(input: string) -> string;
11+
do-something: func(number: u32);
1112
}
1213

1314
interface host {

src/hyperlight_wasm/examples/component_example/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ impl Default for State {
2525

2626
impl bindings::component_sample::example::Host for State {
2727
fn r#print(&mut self, message: alloc::string::String) {
28+
assert_eq!("42", message);
2829
println!("Logged from component: {message}");
2930
}
3031

@@ -66,6 +67,7 @@ fn main() {
6667
let result = instance.add(4, 3);
6768
assert_eq!(7, result);
6869
println!("Add result is {result}");
70+
instance.do_something(42);
6971

7072
let result = instance.call_host("Hello".to_string());
7173
assert_eq!("Hello from component and the host!", result);

src/hyperlight_wasm_macro/src/wasmguest.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use hyperlight_component_util::hl::{
3535
emit_hl_unmarshal_result,
3636
};
3737
use hyperlight_component_util::{resource, rtypes};
38+
use proc_macro::Ident;
3839
use proc_macro2::TokenStream;
3940
use quote::{format_ident, quote};
4041
use syn::ext::IdentExt;
@@ -154,7 +155,6 @@ fn emit_export_extern_decl<'a, 'b, 'c>(
154155
.iter()
155156
.map(|p| rtypes::emit_value(s, &p.ty))
156157
.collect::<Vec<_>>();
157-
let rwt = rtypes::emit_func_result(s, &ft.result);
158158
let (pds, pus) = ft.params.iter().enumerate()
159159
.map(|(i, p)| {
160160
let id = kebab_to_var(p.name.name);
@@ -166,7 +166,7 @@ fn emit_export_extern_decl<'a, 'b, 'c>(
166166
let get_instance = path.iter().map(|export| quote! {
167167
let instance_idx = Some(instance.get_export(&mut *store, instance_idx.as_ref(), #export).unwrap());
168168
}).collect::<Vec<_>>();
169-
let ret = format_ident!("ret");
169+
let (function_call, ret) = emit_wasm_function_call(s, &ft.result, pwts, pus);
170170
let marshal_result = emit_hl_marshal_result(s, ret.clone(), &ft.result);
171171
quote! {
172172
fn #n(fc: &::hyperlight_common::flatbuffer_wrappers::function_call::FunctionCall) -> ::hyperlight_guest::error::Result<::alloc::vec::Vec<u8>> {
@@ -176,8 +176,7 @@ fn emit_export_extern_decl<'a, 'b, 'c>(
176176
let instance_idx = None;
177177
#(#get_instance;)*
178178
let func_idx = instance.get_export(&mut *store, instance_idx.as_ref(), #nlit).unwrap();
179-
let #ret = instance.get_typed_func::<(#(#pwts,)*), (#rwt,)>(&mut *store, func_idx)?
180-
.call(&mut *store, (#(#pus,)*))?.0;
179+
#function_call
181180
::core::result::Result::Ok(::hyperlight_common::flatbuffer_wrappers::util::get_flatbuffer_result::<&[u8]>(&#marshal_result))
182181
}
183182
::hyperlight_guest_bin::guest_function::register::register_function(
@@ -206,6 +205,34 @@ fn emit_export_extern_decl<'a, 'b, 'c>(
206205
}
207206
}
208207

208+
fn emit_wasm_function_call(
209+
s: &mut State,
210+
result: &etypes::Result,
211+
pwts: Vec<TokenStream>,
212+
pus: Vec<TokenStream>,
213+
) -> (TokenStream, proc_macro2::Ident) {
214+
let ret = format_ident!("ret");
215+
216+
// if the result is empty we don't want a return result with `get_typed_func`
217+
let rwt = match result {
218+
etypes::Result::Named(rs) if rs.is_empty() => {
219+
quote! {
220+
instance.get_typed_func::<(#(#pwts,)*), ()>(&mut *store, func_idx)?
221+
.call(&mut *store, (#(#pus,)*))?;
222+
}
223+
}
224+
_ => {
225+
let r = rtypes::emit_func_result(s, result);
226+
quote! {
227+
let #ret = instance.get_typed_func::<(#(#pwts,)*), ((#r,))>(&mut *store, func_idx)?
228+
.call(&mut *store, (#(#pus,)*))?.0;
229+
}
230+
}
231+
};
232+
233+
(rwt, ret)
234+
}
235+
209236
// Emit code to register each export of the given instance with the
210237
// wasmtime linker, calling through Hyperlight.
211238
//

0 commit comments

Comments
 (0)