Skip to content

Commit fa6eda4

Browse files
committed
support host function calls in call_{imported,indirect}
1 parent d768887 commit fa6eda4

File tree

1 file changed

+66
-5
lines changed
  • crates/wasmi/src/engine/executor/handler

1 file changed

+66
-5
lines changed

crates/wasmi/src/engine/executor/handler/exec.rs

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ use crate::{
2626
update_instance,
2727
},
2828
},
29+
utils::unreachable_unchecked,
2930
EngineFunc,
3031
ResumableHostTrapError,
3132
ResumableOutOfFuelError,
3233
},
3334
errors::{FuelError, MemoryError},
3435
func::FuncEntity,
3536
ir::{self, Slot, SlotSpan},
36-
store::StoreError,
37+
store::{CallHooks, StoreError},
3738
TrapCode,
3839
};
3940
use core::cmp;
@@ -249,9 +250,39 @@ pub fn call_imported(
249250
(callee_ip, callee_sp, mem0, mem0_len, instance)
250251
}
251252
FuncEntity::Host(host_func) => {
253+
debug_assert_eq!(params.len(), host_func.len_params());
254+
let trampoline = *host_func.trampoline();
255+
let (sp, params_results) =
256+
match state
257+
.stack
258+
.prepare_host_frame(caller_ip, params, host_func.len_results())
259+
{
260+
Ok(params_results) => params_results,
261+
Err(trap) => done!(state, trap),
262+
};
263+
match state.store.call_host_func(
264+
trampoline,
265+
Some(instance),
266+
params_results,
267+
CallHooks::Call,
268+
) {
269+
Ok(()) => {}
270+
Err(StoreError::External(error)) => {
271+
done!(
272+
state,
273+
DoneReason::Host(ResumableHostTrapError::new(error, func, params.span()))
274+
)
275+
}
276+
Err(StoreError::Internal(error)) => unsafe {
277+
unreachable_unchecked!(
278+
"internal interpreter error while executing host function: {error}"
279+
)
280+
},
281+
}
282+
(caller_ip, sp, mem0, mem0_len, instance)
252283
}
253284
};
254-
dispatch!(state, callee_ip, sp, mem0, mem0_len, instance)
285+
dispatch!(state, ip, sp, mem0, mem0_len, instance)
255286
}
256287

257288
pub fn call_indirect(
@@ -296,8 +327,37 @@ pub fn call_indirect(
296327
update_instance(state.store, instance, callee_instance, mem0, mem0_len);
297328
(callee_ip, callee_sp, mem0, mem0_len, instance)
298329
}
299-
FuncEntity::Host(_func) => {
300-
todo!()
330+
FuncEntity::Host(host_func) => {
331+
debug_assert_eq!(params.len(), host_func.len_params());
332+
let trampoline = *host_func.trampoline();
333+
let (sp, params_results) =
334+
match state
335+
.stack
336+
.prepare_host_frame(caller_ip, params, host_func.len_results())
337+
{
338+
Ok(params_results) => params_results,
339+
Err(trap) => done!(state, trap),
340+
};
341+
match state.store.call_host_func(
342+
trampoline,
343+
Some(instance),
344+
params_results,
345+
CallHooks::Call,
346+
) {
347+
Ok(()) => {}
348+
Err(StoreError::External(error)) => {
349+
done!(
350+
state,
351+
DoneReason::Host(ResumableHostTrapError::new(error, func, params.span()))
352+
)
353+
}
354+
Err(StoreError::Internal(error)) => unsafe {
355+
unreachable_unchecked!(
356+
"internal interpreter error while executing host function: {error}"
357+
)
358+
},
359+
}
360+
(caller_ip, sp, mem0, mem0_len, instance)
301361
}
302362
};
303363
dispatch!(state, callee_ip, sp, mem0, mem0_len, instance)
@@ -351,7 +411,8 @@ pub fn return_call_imported(
351411
update_instance(state.store, instance, callee_instance, mem0, mem0_len);
352412
(callee_ip, callee_sp, mem0, mem0_len, instance)
353413
}
354-
FuncEntity::Host(host_func) => {
414+
FuncEntity::Host(_host_func) => {
415+
todo!()
355416
}
356417
};
357418
dispatch!(state, callee_ip, sp, mem0, mem0_len, instance)

0 commit comments

Comments
 (0)