Skip to content

Commit 5142374

Browse files
committed
account for call_host_function reading the return value
Signed-off-by: Jorge Prendes <jorge.prendes@gmail.com>
1 parent 20ea6c0 commit 5142374

4 files changed

Lines changed: 64 additions & 48 deletions

File tree

src/hyperlight_wasm_macro/src/wasmguest.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,11 @@ fn emit_import_extern_decl<'a, 'b, 'c>(
8787
};
8888
quote! {
8989
#li.func_wrap::<_, (#(#pts,)*), #rt>(#edkn, |_, (#(#pds,)*)| {
90-
call_host_function(
90+
let #ret = call_host_function::<Vec<u8>>(
9191
#fname,
9292
::core::option::Option::Some(vec![#(#pus,)*]),
9393
::hyperlight_common::flatbuffer_wrappers::function_types::ReturnType::VecBytes,
9494
).unwrap();
95-
let #ret = ::hyperlight_guest_bin::host_comm::get_host_return_value::<Vec<u8>>().unwrap();
9695
::core::result::Result::Ok(#ur)
9796
});
9897
}

src/wasm_runtime/src/hostfuncs.rs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ limitations under the License.
1515
*/
1616

1717
use alloc::collections::BTreeMap;
18-
use alloc::format;
1918
use alloc::string::{String, ToString};
2019
use alloc::vec::Vec;
2120

@@ -88,21 +87,16 @@ pub(crate) fn hostfunc_type(d: &HostFunctionDefinition, e: &Engine) -> Result<Fu
8887
ReturnType::Void => {}
8988
ReturnType::Int | ReturnType::UInt => results.push(ValType::I32),
9089
ReturnType::Long | ReturnType::ULong => results.push(ValType::I64),
91-
/* hyperlight_guest_bin::host_function_call::get_host_value_return_as_{bool,float,double,string} are missing */
92-
// TODO: this comment is outdated, these are now implemented. Implement the other types
90+
ReturnType::Bool => results.push(ValType::I32),
91+
ReturnType::Float => results.push(ValType::F32),
92+
ReturnType::Double => results.push(ValType::F64),
93+
ReturnType::String => results.push(ValType::I32),
94+
// TODO: this comment about using i64 for VecBytes doesn't seem to match with what
95+
// hl_return_to_val was doing, check if this is still correct.
9396
/* For compatibility with old host, we return
9497
* a packed i64 with a (wasm32) pointer in the lower half and
9598
* a length in the upper half. */
9699
ReturnType::VecBytes => results.push(ValType::I64),
97-
_ => {
98-
return Err(HyperlightGuestError::new(
99-
ErrorCode::GuestError,
100-
format!(
101-
"Host function return type {:?} must be (u)int or (u)long, if present",
102-
d.return_type
103-
),
104-
));
105-
}
106100
}
107101
Ok(FuncType::new(e, params, results))
108102
}
@@ -121,7 +115,39 @@ pub(crate) fn call(
121115
marshal::val_to_hl_param(&mut c, |c, n| c.get_export(n), s, t)
122116
})
123117
.collect();
124-
call_host_function::<ReturnValue>(&d.function_name, Some(params), d.return_type)
118+
119+
let rv = call_host_function::<ReturnValue>(&d.function_name, Some(params), d.return_type)
125120
.expect("Host function call failed");
126-
marshal::hl_return_to_val(&mut c, |c, n| c.get_export(n), &d.return_type, rs)
121+
122+
assert!(
123+
return_type_from_val(&rv) == d.return_type,
124+
"Host function return type mismatch"
125+
);
126+
127+
if rs.is_empty() {
128+
assert!(
129+
d.return_type == ReturnType::Void,
130+
"Host function return type mismatch"
131+
);
132+
return Ok(());
133+
}
134+
135+
rs[0] = marshal::hl_return_to_val(&mut c, |c, n| c.get_export(n), rv)?;
136+
137+
Ok(())
138+
}
139+
140+
fn return_type_from_val(val: &ReturnValue) -> ReturnType {
141+
match val {
142+
ReturnValue::Int(_) => ReturnType::Int,
143+
ReturnValue::UInt(_) => ReturnType::UInt,
144+
ReturnValue::Long(_) => ReturnType::Long,
145+
ReturnValue::ULong(_) => ReturnType::ULong,
146+
ReturnValue::Float(_) => ReturnType::Float,
147+
ReturnValue::Double(_) => ReturnType::Double,
148+
ReturnValue::String(_) => ReturnType::String,
149+
ReturnValue::VecBytes(_) => ReturnType::VecBytes,
150+
ReturnValue::Bool(_) => ReturnType::Bool,
151+
ReturnValue::Void(_) => ReturnType::Void,
152+
}
127153
}

src/wasm_runtime/src/marshal.rs

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@ use alloc::vec::Vec;
2222
use alloc::{format, vec};
2323

2424
use hyperlight_common::flatbuffer_wrappers::function_types::{
25-
ParameterType, ParameterValue, ReturnType,
25+
ParameterType, ParameterValue, ReturnType, ReturnValue,
2626
};
2727
use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode;
2828
use hyperlight_common::flatbuffer_wrappers::util::get_flatbuffer_result;
2929
use hyperlight_guest::error::{HyperlightGuestError, Result};
30-
use hyperlight_guest_bin::host_comm::get_host_return_value;
3130
use wasmtime::{AsContextMut, Extern, Val};
3231

3332
fn malloc<C: AsContextMut>(
@@ -252,34 +251,29 @@ pub fn val_to_hl_param<'a, C: AsContextMut>(
252251
pub fn hl_return_to_val<C: AsContextMut>(
253252
ctx: &mut C,
254253
get_export: impl Fn(&mut C, &str) -> Option<Extern>,
255-
rt: &ReturnType,
256-
ret: &mut [Val],
257-
) -> Result<()> {
258-
match rt {
259-
ReturnType::Void => get_host_return_value::<()>()?,
260-
ReturnType::Int => {
261-
ret[0] = Val::I32(get_host_return_value::<i32>()?);
262-
}
263-
ReturnType::Long => {
264-
ret[0] = Val::I64(get_host_return_value::<i64>()?);
265-
}
266-
ReturnType::UInt => {
267-
ret[0] = Val::I32(get_host_return_value::<u32>()? as i32);
268-
}
269-
ReturnType::ULong => {
270-
ret[0] = Val::I64(get_host_return_value::<u64>()? as i64);
254+
rv: ReturnValue,
255+
) -> Result<Val> {
256+
match rv {
257+
ReturnValue::Int(i) => Ok(Val::I32(i)),
258+
ReturnValue::UInt(u) => Ok(Val::I32(u as i32)),
259+
ReturnValue::Long(l) => Ok(Val::I64(l)),
260+
ReturnValue::ULong(u) => Ok(Val::I64(u as i64)),
261+
ReturnValue::Bool(b) => Ok(Val::I32(if b { 1 } else { 0 })),
262+
ReturnValue::Float(f) => Ok(Val::F32(f.to_bits())),
263+
ReturnValue::Double(f) => Ok(Val::F64(f.to_bits())),
264+
ReturnValue::String(s) => {
265+
let s = CString::new(s.as_str()).unwrap();
266+
let nbytes = s.count_bytes() + 1; // include the NUL terminator
267+
let addr = malloc(ctx, &get_export, nbytes)?;
268+
write(ctx, &get_export, addr, s.as_bytes_with_nul())?;
269+
Ok(Val::I32(addr))
271270
}
272-
/* hyperlight_guest_bin::host_comm::get_host_value_return_as_{bool,float,double,string} are missing */
273-
// TODO: this comment is outdated, implement these
274-
ReturnType::VecBytes => {
275-
let b = get_host_return_value::<Vec<u8>>()?;
271+
ReturnValue::VecBytes(b) => {
276272
let addr = malloc(ctx, &get_export, b.len())?;
277273
write(ctx, &get_export, addr, b.as_ref())?;
278-
ret[0] = Val::I32(addr);
279-
}
280-
_ => {
281-
panic!("unimplemented");
274+
Ok(Val::I32(addr))
275+
// TODO: check that the next parameter is the correct length
282276
}
277+
ReturnValue::Void(()) => Ok(Val::I32(0)),
283278
}
284-
Ok(())
285279
}

src/wasm_runtime/src/wasip1.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use alloc::vec::Vec;
2222

2323
use hyperlight_common::flatbuffer_wrappers::function_types::{ParameterValue, ReturnType};
2424
use hyperlight_guest::error::Result;
25-
use hyperlight_guest_bin::host_comm::{call_host_function, get_host_return_value};
25+
use hyperlight_guest_bin::host_comm::call_host_function;
2626
use wasmtime::{Caller, Extern, Linker};
2727

2828
pub(crate) fn register_handlers<T>(linker: &mut Linker<T>) -> Result<()> {
@@ -63,16 +63,13 @@ pub(crate) fn register_handlers<T>(linker: &mut Linker<T>) -> Result<()> {
6363
let Ok(str) = core::str::from_utf8(&string_bytes) else {
6464
return -2;
6565
};
66-
let Ok(()) = call_host_function(
66+
let Ok(written) = call_host_function::<i32>(
6767
"HostPrint",
6868
Some(Vec::from(&[ParameterValue::String(str.to_string())])),
6969
ReturnType::Int,
7070
) else {
7171
return -3;
7272
};
73-
let Ok(written) = get_host_return_value::<i32>() else {
74-
return -4;
75-
};
7673
total_written += written;
7774
}
7875
memory

0 commit comments

Comments
 (0)