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