1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <inttypes.h> 5 6 #include <wasm.h> 7 #include "wasmtime.h" 8 9 #define own 10 11 int main(int argc, const char* argv[]) { 12 // Configuring engine to support generating of DWARF info. 13 // lldb can be used to attach to the program and observe 14 // original fib-wasm.c source code and variables. 15 wasm_config_t* config = wasm_config_new(); 16 wasmtime_config_debug_info_set(config, true); 17 18 // Initialize. 19 printf("Initializing...\n"); 20 wasm_engine_t* engine = wasm_engine_new_with_config(config); 21 wasm_store_t* store = wasm_store_new(engine); 22 23 // Load binary. 24 printf("Loading binary...\n"); 25 FILE* file = fopen("target/wasm32-unknown-unknown/debug/fib.wasm", "rb"); 26 if (!file) { 27 printf("> Error opening module!\n"); 28 return 1; 29 } 30 fseek(file, 0L, SEEK_END); 31 size_t file_size = ftell(file); 32 fseek(file, 0L, SEEK_SET); 33 wasm_byte_vec_t binary; 34 wasm_byte_vec_new_uninitialized(&binary, file_size); 35 if (fread(binary.data, file_size, 1, file) != 1) { 36 printf("> Error reading module!\n"); 37 return 1; 38 } 39 fclose(file); 40 41 // Compile. 42 printf("Compiling module...\n"); 43 own wasm_module_t* module = wasm_module_new(store, &binary); 44 if (!module) { 45 printf("> Error compiling module!\n"); 46 return 1; 47 } 48 wasm_byte_vec_delete(&binary); 49 50 // Figure out which export is the `fib` export 51 wasm_exporttype_vec_t module_exports; 52 wasm_module_exports(module, &module_exports); 53 int fib_idx = -1; 54 for (int i = 0; i < module_exports.size; i++) { 55 const wasm_name_t *name = wasm_exporttype_name(module_exports.data[i]); 56 if (name->size != 3) 57 continue; 58 if (strncmp("fib", name->data, 3) != 0) 59 continue; 60 fib_idx = i; 61 break; 62 } 63 wasm_exporttype_vec_delete(&module_exports); 64 if (fib_idx == -1) { 65 printf("> Error finding `fib` export!\n"); 66 return 1; 67 } 68 69 // Instantiate. 70 printf("Instantiating module...\n"); 71 own wasm_instance_t* instance = 72 wasm_instance_new(store, module, NULL, NULL); 73 if (!instance) { 74 printf("> Error instantiating module!\n"); 75 return 1; 76 } 77 78 // Extract export. 79 printf("Extracting export...\n"); 80 own wasm_extern_vec_t exports; 81 wasm_instance_exports(instance, &exports); 82 if (exports.size == 0) { 83 printf("> Error accessing exports!\n"); 84 return 1; 85 } 86 // Getting second export (first is memory). 87 const wasm_func_t* run_func = wasm_extern_as_func(exports.data[fib_idx]); 88 if (run_func == NULL) { 89 printf("> Error accessing export!\n"); 90 return 1; 91 } 92 93 wasm_module_delete(module); 94 wasm_instance_delete(instance); 95 96 // Call. 97 printf("Calling fib...\n"); 98 wasm_val_t params[1] = { {.kind = WASM_I32, .of = {.i32 = 6}} }; 99 wasm_val_t results[1]; 100 if (wasm_func_call(run_func, params, results)) { 101 printf("> Error calling function!\n"); 102 return 1; 103 } 104 105 wasm_extern_vec_delete(&exports); 106 107 printf("> fib(6) = %d\n", results[0].of.i32); 108 109 // Shut down. 110 printf("Shutting down...\n"); 111 wasm_store_delete(store); 112 wasm_engine_delete(engine); 113 114 // All done. 115 printf("Done.\n"); 116 return 0; 117 } 118 119