xref: /wasmtime-44.0.1/examples/anyref.cc (revision b34556f9)
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