1*13ebd6f5SMangoPeachGrape /* 2*13ebd6f5SMangoPeachGrape Example of instantiating of the WebAssembly module and invoking its exported 3*13ebd6f5SMangoPeachGrape function. 4*13ebd6f5SMangoPeachGrape 5*13ebd6f5SMangoPeachGrape You can compile and run this example on Linux with: 6*13ebd6f5SMangoPeachGrape 7*13ebd6f5SMangoPeachGrape cargo build --release -p wasmtime-c-api 8*13ebd6f5SMangoPeachGrape c++ examples/interrupt.cc -std=c++20 \ 9*13ebd6f5SMangoPeachGrape -I crates/c-api/include \ 10*13ebd6f5SMangoPeachGrape -I crates/c-api/wasm-c-api/include \ 11*13ebd6f5SMangoPeachGrape target/release/libwasmtime.a \ 12*13ebd6f5SMangoPeachGrape -lpthread -ldl -lm \ 13*13ebd6f5SMangoPeachGrape -o interrupt 14*13ebd6f5SMangoPeachGrape ./interrupt 15*13ebd6f5SMangoPeachGrape 16*13ebd6f5SMangoPeachGrape Note that on Windows and macOS the command will be similar, but you'll need 17*13ebd6f5SMangoPeachGrape to tweak the `-lpthread` and such annotations as well as the name of the 18*13ebd6f5SMangoPeachGrape `libwasmtime.a` file on Windows. 19*13ebd6f5SMangoPeachGrape */ 20*13ebd6f5SMangoPeachGrape 21*13ebd6f5SMangoPeachGrape #include <chrono> 22*13ebd6f5SMangoPeachGrape #include <fstream> 23*13ebd6f5SMangoPeachGrape #include <iostream> 24*13ebd6f5SMangoPeachGrape #include <sstream> 25*13ebd6f5SMangoPeachGrape #include <thread> 26*13ebd6f5SMangoPeachGrape #include <wasmtime.hh> 27*13ebd6f5SMangoPeachGrape 28*13ebd6f5SMangoPeachGrape using namespace wasmtime; 29*13ebd6f5SMangoPeachGrape readFile(const char * name)30*13ebd6f5SMangoPeachGrapestd::string readFile(const char *name) { 31*13ebd6f5SMangoPeachGrape std::ifstream watFile; 32*13ebd6f5SMangoPeachGrape watFile.open(name); 33*13ebd6f5SMangoPeachGrape std::stringstream strStream; 34*13ebd6f5SMangoPeachGrape strStream << watFile.rdbuf(); 35*13ebd6f5SMangoPeachGrape return strStream.str(); 36*13ebd6f5SMangoPeachGrape } 37*13ebd6f5SMangoPeachGrape main()38*13ebd6f5SMangoPeachGrapeint main() { 39*13ebd6f5SMangoPeachGrape // Enable interruptible code via `Config` and then create an interrupt 40*13ebd6f5SMangoPeachGrape // handle which we'll use later to interrupt running code. 41*13ebd6f5SMangoPeachGrape Config config; 42*13ebd6f5SMangoPeachGrape config.epoch_interruption(true); 43*13ebd6f5SMangoPeachGrape Engine engine(std::move(config)); 44*13ebd6f5SMangoPeachGrape Store store(engine); 45*13ebd6f5SMangoPeachGrape store.context().set_epoch_deadline(1); 46*13ebd6f5SMangoPeachGrape 47*13ebd6f5SMangoPeachGrape // Compile and instantiate a small example with an infinite loop. 48*13ebd6f5SMangoPeachGrape auto wat = readFile("examples/interrupt.wat"); 49*13ebd6f5SMangoPeachGrape Module module = Module::compile(engine, wat).unwrap(); 50*13ebd6f5SMangoPeachGrape Instance instance = Instance::create(store, module, {}).unwrap(); 51*13ebd6f5SMangoPeachGrape Func run = std::get<Func>(*instance.get(store, "run")); 52*13ebd6f5SMangoPeachGrape 53*13ebd6f5SMangoPeachGrape // Spin up a thread to send us an interrupt in a second 54*13ebd6f5SMangoPeachGrape std::thread t([engine{std::move(engine)}]() { 55*13ebd6f5SMangoPeachGrape std::this_thread::sleep_for(std::chrono::seconds(1)); 56*13ebd6f5SMangoPeachGrape std::cout << "Interrupting!\n"; 57*13ebd6f5SMangoPeachGrape engine.increment_epoch(); 58*13ebd6f5SMangoPeachGrape }); 59*13ebd6f5SMangoPeachGrape 60*13ebd6f5SMangoPeachGrape std::cout << "Entering infinite loop ...\n"; 61*13ebd6f5SMangoPeachGrape auto err = run.call(store, {}).err(); 62*13ebd6f5SMangoPeachGrape auto &trap = std::get<Trap>(err.data); 63*13ebd6f5SMangoPeachGrape 64*13ebd6f5SMangoPeachGrape std::cout << "trap: " << trap.message() << "\n"; 65*13ebd6f5SMangoPeachGrape t.join(); 66*13ebd6f5SMangoPeachGrape } 67