Is there a way in wee8 (v8's wasm api) to stop the execution of an embedded guest function from within an imported host function?
Example:
auto hostFunc(const wasm::Val args[], wasm::Val results[]) -> wasm::own<wasm::Trap> {
std::cout << "host called!" << std::endl;
if (<some condition>) {
// Stop the execution of the guest code, return control to host.
}
return nullptr;
}
Embedding code taken from v8's examples, minus some checks and prints (to make the snippet shorter).
void embedWasmCode(wasm::vec<byte_t> binary) {
auto store_ = wasm::Store::make(engine.get());
auto store = store_.get();
auto module = wasm::Module::make(store, binary);
auto func_type = wasm::FuncType::make(
wasm::ownvec<wasm::ValType>::make(),
wasm::ownvec<wasm::ValType>::make()
);
auto callback = wasm::Func::make(store, func_type.get(), hostFunc);
wasm::Extern* imports[] = {callback.get()};
auto instance = wasm::Instance::make(store, module.get(), imports);
auto exports = instance->exports();
auto run_func = exports[0]->func();
auto res = run_func->call();
// When the execution of run_func gets to the host function, the host function
// stops run_func's execution if some condition is met and execution returns
// to the host, here.
// ... more code
}
Wasmer for example has this functionality as documented here.
Yes there is a way, and of course it can be found in the examples.
From trap.cc:
auto fail_callback(
void* env, const wasm::Val args[], wasm::Val results[]
) -> wasm::own<wasm::Trap> {
std::cout << "Calling back..." << std::endl;
auto store = reinterpret_cast<wasm::Store*>(env);
auto message = wasm::Name::make(std::string("callback abort"));
return wasm::Trap::make(store, message);
}
By returning a trap object from a host function, execution of the guest code (which called the imported host function) will stop and control will return to the host.