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