xref: /wasmtime-44.0.1/examples/gcd.c (revision f9f8a4df)
1 /*
2 Example of instantiating of the WebAssembly module and invoking its exported
3 function.
4 
5 You can compile and run this example on Linux with:
6 
7    cargo build --release -p wasmtime-c-api
8    cc examples/gcd.c \
9        -I crates/c-api/include \
10        -I crates/c-api/wasm-c-api/include \
11        target/release/libwasmtime.a \
12        -lpthread -ldl -lm \
13        -o gcd
14    ./gcd
15 
16 Note that on Windows and macOS the command will be similar, but you'll need
17 to tweak the `-lpthread` and such annotations.
18 
19 You can also build using cmake:
20 
21 mkdir build && cd build && cmake .. && cmake --build . --target wasmtime-gcd
22 */
23 
24 #include <assert.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <wasm.h>
28 #include <wasmtime.h>
29 
30 static void exit_with_error(const char *message, wasmtime_error_t *error,
31                             wasm_trap_t *trap);
32 
33 int main() {
34   int ret = 0;
35   // Set up our context
36   wasm_engine_t *engine = wasm_engine_new();
37   assert(engine != NULL);
38   wasmtime_store_t *store = wasmtime_store_new(engine, NULL, NULL);
39   assert(store != NULL);
40   wasmtime_context_t *context = wasmtime_store_context(store);
41 
42   // Load our input file to parse it next
43   FILE *file = fopen("examples/gcd.wat", "r");
44   if (!file) {
45     printf("> Error loading file!\n");
46     return 1;
47   }
48   fseek(file, 0L, SEEK_END);
49   size_t file_size = ftell(file);
50   fseek(file, 0L, SEEK_SET);
51   wasm_byte_vec_t wat;
52   wasm_byte_vec_new_uninitialized(&wat, file_size);
53   if (fread(wat.data, file_size, 1, file) != 1) {
54     printf("> Error loading module!\n");
55     return 1;
56   }
57   fclose(file);
58 
59   // Parse the wat into the binary wasm format
60   wasm_byte_vec_t wasm;
61   wasmtime_error_t *error = wasmtime_wat2wasm(wat.data, wat.size, &wasm);
62   if (error != NULL)
63     exit_with_error("failed to parse wat", error, NULL);
64   wasm_byte_vec_delete(&wat);
65 
66   // Compile and instantiate our module
67   wasmtime_module_t *module = NULL;
68   error = wasmtime_module_new(engine, (uint8_t *)wasm.data, wasm.size, &module);
69   if (module == NULL)
70     exit_with_error("failed to compile module", error, NULL);
71   wasm_byte_vec_delete(&wasm);
72 
73   wasm_trap_t *trap = NULL;
74   wasmtime_instance_t instance;
75   error = wasmtime_instance_new(context, module, NULL, 0, &instance, &trap);
76   if (error != NULL || trap != NULL)
77     exit_with_error("failed to instantiate", error, trap);
78 
79   // Lookup our `gcd` export function
80   wasmtime_extern_t gcd;
81   bool ok = wasmtime_instance_export_get(context, &instance, "gcd", 3, &gcd);
82   assert(ok);
83   assert(gcd.kind == WASMTIME_EXTERN_FUNC);
84 
85   // And call it!
86   int a = 6;
87   int b = 27;
88   wasmtime_val_t params[2];
89   params[0].kind = WASMTIME_I32;
90   params[0].of.i32 = a;
91   params[1].kind = WASMTIME_I32;
92   params[1].of.i32 = b;
93   wasmtime_val_t results[1];
94   error =
95       wasmtime_func_call(context, &gcd.of.func, params, 2, results, 1, &trap);
96   if (error != NULL || trap != NULL)
97     exit_with_error("failed to call gcd", error, trap);
98   assert(results[0].kind == WASMTIME_I32);
99 
100   printf("gcd(%d, %d) = %d\n", a, b, results[0].of.i32);
101 
102   // Clean up after ourselves at this point
103   ret = 0;
104 
105   wasmtime_module_delete(module);
106   wasmtime_store_delete(store);
107   wasm_engine_delete(engine);
108   return ret;
109 }
110 
111 static void exit_with_error(const char *message, wasmtime_error_t *error,
112                             wasm_trap_t *trap) {
113   fprintf(stderr, "error: %s\n", message);
114   wasm_byte_vec_t error_message;
115   if (error != NULL) {
116     wasmtime_error_message(error, &error_message);
117   } else {
118     wasm_trap_message(trap, &error_message);
119   }
120   fprintf(stderr, "%.*s\n", (int)error_message.size, error_message.data);
121   wasm_byte_vec_delete(&error_message);
122   exit(1);
123 }
124