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 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 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