Search code examples
v8webassembly

How to stop embedded code execution from imported host function in wee8?


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.


Solution

  • 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.