1eaa01d7bSTill Schneidereit /*
2eaa01d7bSTill Schneidereit Example of using `anyref` values.
3eaa01d7bSTill Schneidereit
4eaa01d7bSTill Schneidereit You can build the example using CMake:
5eaa01d7bSTill Schneidereit
6eaa01d7bSTill Schneidereit mkdir build && (cd build && cmake .. && \
7eaa01d7bSTill Schneidereit cmake --build . --target wasmtime-anyref-cpp)
8eaa01d7bSTill Schneidereit
9eaa01d7bSTill Schneidereit And then run it:
10eaa01d7bSTill Schneidereit
11eaa01d7bSTill Schneidereit build/wasmtime-anyref-cpp
12eaa01d7bSTill Schneidereit */
13eaa01d7bSTill Schneidereit
14eaa01d7bSTill Schneidereit #include <fstream>
15eaa01d7bSTill Schneidereit #include <iostream>
16eaa01d7bSTill Schneidereit #include <sstream>
17eaa01d7bSTill Schneidereit #include <wasmtime.hh>
18eaa01d7bSTill Schneidereit
19eaa01d7bSTill Schneidereit using namespace wasmtime;
20eaa01d7bSTill Schneidereit
readFile(const char * name)21eaa01d7bSTill Schneidereit std::string readFile(const char *name) {
22eaa01d7bSTill Schneidereit std::ifstream watFile;
23eaa01d7bSTill Schneidereit watFile.open(name);
24eaa01d7bSTill Schneidereit std::stringstream strStream;
25eaa01d7bSTill Schneidereit strStream << watFile.rdbuf();
26eaa01d7bSTill Schneidereit return strStream.str();
27eaa01d7bSTill Schneidereit }
28eaa01d7bSTill Schneidereit
main()29eaa01d7bSTill Schneidereit int main() {
30eaa01d7bSTill Schneidereit std::cout << "Initializing...\n";
31eaa01d7bSTill Schneidereit Config config;
32eaa01d7bSTill Schneidereit config.wasm_reference_types(true);
33eaa01d7bSTill Schneidereit config.wasm_function_references(true);
34eaa01d7bSTill Schneidereit config.wasm_gc(true);
35eaa01d7bSTill Schneidereit Engine engine(std::move(config));
36eaa01d7bSTill Schneidereit Store store(engine);
37eaa01d7bSTill Schneidereit
38eaa01d7bSTill Schneidereit std::cout << "Compiling module...\n";
39eaa01d7bSTill Schneidereit auto wat = readFile("examples/anyref.wat");
40eaa01d7bSTill Schneidereit Module module = Module::compile(engine, wat).unwrap();
41eaa01d7bSTill Schneidereit
42eaa01d7bSTill Schneidereit std::cout << "Instantiating module...\n";
43eaa01d7bSTill Schneidereit Instance instance = Instance::create(store, module, {}).unwrap();
44eaa01d7bSTill Schneidereit
45eaa01d7bSTill Schneidereit std::cout << "Creating new `anyref` from i31...\n";
46eaa01d7bSTill Schneidereit // Create an i31ref wrapping 1234
47eaa01d7bSTill Schneidereit auto cx = store.context();
48eaa01d7bSTill Schneidereit AnyRef i31 = AnyRef::i31(cx, 1234);
49eaa01d7bSTill Schneidereit Val anyref_val(i31);
50adff9d9dSAlex Crichton auto opt_any = anyref_val.anyref();
51eaa01d7bSTill Schneidereit if (!opt_any || !opt_any->u31(cx) || *opt_any->u31(cx) != 1234) {
52eaa01d7bSTill Schneidereit std::cerr << "> Error creating i31 anyref\n";
53eaa01d7bSTill Schneidereit return 1;
54eaa01d7bSTill Schneidereit }
55eaa01d7bSTill Schneidereit
56eaa01d7bSTill Schneidereit std::cout << "Touching `anyref` table...\n";
57eaa01d7bSTill Schneidereit Table table = std::get<Table>(*instance.get(store, "table"));
58eaa01d7bSTill Schneidereit table.set(store, 3, anyref_val).unwrap();
59eaa01d7bSTill Schneidereit auto elem_opt = table.get(store, 3);
60eaa01d7bSTill Schneidereit if (!elem_opt) {
61eaa01d7bSTill Schneidereit std::cerr << "> Error getting table element\n";
62eaa01d7bSTill Schneidereit return 1;
63eaa01d7bSTill Schneidereit }
64adff9d9dSAlex Crichton auto elem_any = elem_opt->anyref();
65eaa01d7bSTill Schneidereit if (!elem_any || !elem_any->u31(cx) || *elem_any->u31(cx) != 1234) {
66eaa01d7bSTill Schneidereit std::cerr << "> Error verifying table element\n";
67eaa01d7bSTill Schneidereit return 1;
68eaa01d7bSTill Schneidereit }
69eaa01d7bSTill Schneidereit
70eaa01d7bSTill Schneidereit std::cout << "Touching `anyref` global...\n";
71eaa01d7bSTill Schneidereit Global global = std::get<Global>(*instance.get(store, "global"));
72eaa01d7bSTill Schneidereit global.set(store, anyref_val).unwrap();
73eaa01d7bSTill Schneidereit Val global_val = global.get(store);
74adff9d9dSAlex Crichton auto global_any = global_val.anyref();
75eaa01d7bSTill Schneidereit if (!global_any || !global_any->u31(cx) || *global_any->u31(cx) != 1234) {
76eaa01d7bSTill Schneidereit std::cerr << "> Error verifying global value\n";
77eaa01d7bSTill Schneidereit return 1;
78eaa01d7bSTill Schneidereit }
79eaa01d7bSTill Schneidereit
80eaa01d7bSTill Schneidereit std::cout << "Passing `anyref` into func...\n";
81eaa01d7bSTill Schneidereit Func take_anyref = std::get<Func>(*instance.get(store, "take_anyref"));
82eaa01d7bSTill Schneidereit take_anyref.call(store, {anyref_val}).unwrap();
83eaa01d7bSTill Schneidereit
84eaa01d7bSTill Schneidereit std::cout << "Getting `anyref` from func...\n";
85eaa01d7bSTill Schneidereit Func return_anyref = std::get<Func>(*instance.get(store, "return_anyref"));
86eaa01d7bSTill Schneidereit auto results = return_anyref.call(store, {}).unwrap();
87eaa01d7bSTill Schneidereit if (results.size() != 1) {
88eaa01d7bSTill Schneidereit std::cerr << "> Unexpected number of results\n";
89eaa01d7bSTill Schneidereit return 1;
90eaa01d7bSTill Schneidereit }
91adff9d9dSAlex Crichton auto ret_any = results[0].anyref();
92eaa01d7bSTill Schneidereit if (!ret_any || !ret_any->u31(cx) || *ret_any->u31(cx) != 42) {
93eaa01d7bSTill Schneidereit std::cerr << "> Error verifying returned anyref\n";
94eaa01d7bSTill Schneidereit return 1;
95eaa01d7bSTill Schneidereit }
96eaa01d7bSTill Schneidereit
97eaa01d7bSTill Schneidereit std::cout << "GCing within the store...\n";
98*b34556f9SNick Fitzgerald if (!store.context().gc()) {
99*b34556f9SNick Fitzgerald std::cerr << "> Error while collecting garbage\n";
100*b34556f9SNick Fitzgerald return 1;
101*b34556f9SNick Fitzgerald }
102eaa01d7bSTill Schneidereit
103eaa01d7bSTill Schneidereit std::cout << "Done.\n";
104eaa01d7bSTill Schneidereit return 0;
105eaa01d7bSTill Schneidereit }
106