1#include <iostream>
2#include <fstream>
3#include <cstdlib>
4#include <string>
5#include <cinttypes>
6
7#include "wasm.hh"
8
9
10// A function to be called from Wasm code.
11auto hello_callback(
12  const wasm::Val args[], wasm::Val results[]
13) -> wasm::own<wasm::Trap> {
14  std::cout << "Calling back..." << std::endl;
15  std::cout << "> Hello world!" << std::endl;
16  return nullptr;
17}
18
19
20void run() {
21  // Initialize.
22  std::cout << "Initializing..." << std::endl;
23  auto engine = wasm::Engine::make();
24  auto store_ = wasm::Store::make(engine.get());
25  auto store = store_.get();
26
27  // Load binary.
28  std::cout << "Loading binary..." << std::endl;
29  std::ifstream file("hello.wasm");
30  file.seekg(0, std::ios_base::end);
31  auto file_size = file.tellg();
32  file.seekg(0);
33  auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
34  file.read(binary.get(), file_size);
35  file.close();
36  if (file.fail()) {
37    std::cout << "> Error loading module!" << std::endl;
38    exit(1);
39  }
40
41  // Compile.
42  std::cout << "Compiling module..." << std::endl;
43  auto module = wasm::Module::make(store, binary);
44  if (!module) {
45    std::cout << "> Error compiling module!" << std::endl;
46    exit(1);
47  }
48
49  // Create external print functions.
50  std::cout << "Creating callback..." << std::endl;
51  auto hello_type = wasm::FuncType::make(
52    wasm::ownvec<wasm::ValType>::make(), wasm::ownvec<wasm::ValType>::make()
53  );
54  auto hello_func = wasm::Func::make(store, hello_type.get(), hello_callback);
55
56  // Instantiate.
57  std::cout << "Instantiating module..." << std::endl;
58  wasm::Extern* imports[] = {hello_func.get()};
59  auto instance = wasm::Instance::make(store, module.get(), imports);
60  if (!instance) {
61    std::cout << "> Error instantiating module!" << std::endl;
62    exit(1);
63  }
64
65  // Extract export.
66  std::cout << "Extracting export..." << std::endl;
67  auto exports = instance->exports();
68  if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) {
69    std::cout << "> Error accessing export!" << std::endl;
70    exit(1);
71  }
72  auto run_func = exports[0]->func();
73
74  // Call.
75  std::cout << "Calling export..." << std::endl;
76  if (run_func->call()) {
77    std::cout << "> Error calling function!" << std::endl;
78    exit(1);
79  }
80
81  // Shut down.
82  std::cout << "Shutting down..." << std::endl;
83}
84
85
86int main(int argc, const char* argv[]) {
87  run();
88  std::cout << "Done." << std::endl;
89  return 0;
90}
91
92