Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/examples/hello.c
3056 views
1
/*
2
Example of instantiating of the WebAssembly module and invoking its exported
3
function.
4
5
You can build using cmake:
6
7
mkdir build && cd build && cmake .. && cmake --build . --target wasmtime-hello
8
*/
9
10
#include <assert.h>
11
#include <stdio.h>
12
#include <stdlib.h>
13
#include <wasm.h>
14
#include <wasmtime.h>
15
16
static void exit_with_error(const char *message, wasmtime_error_t *error,
17
wasm_trap_t *trap);
18
19
static wasm_trap_t *hello_callback(void *env, wasmtime_caller_t *caller,
20
const wasmtime_val_t *args, size_t nargs,
21
wasmtime_val_t *results, size_t nresults) {
22
(void)env;
23
(void)caller;
24
(void)args;
25
(void)nargs;
26
(void)results;
27
(void)nresults;
28
printf("Calling back...\n");
29
printf("> Hello World!\n");
30
return NULL;
31
}
32
33
int main() {
34
int ret = 0;
35
// Set up our compilation context. Note that we could also work with a
36
// `wasm_config_t` here to configure what feature are enabled and various
37
// compilation settings.
38
printf("Initializing...\n");
39
wasm_engine_t *engine = wasm_engine_new();
40
assert(engine != NULL);
41
42
// With an engine we can create a *store* which is a long-lived group of wasm
43
// modules. Note that we allocate some custom data here to live in the store,
44
// but here we skip that and specify NULL.
45
wasmtime_store_t *store = wasmtime_store_new(engine, NULL, NULL);
46
assert(store != NULL);
47
wasmtime_context_t *context = wasmtime_store_context(store);
48
49
// Read our input file, which in this case is a wasm text file.
50
FILE *file = fopen("examples/hello.wat", "r");
51
assert(file != NULL);
52
fseek(file, 0L, SEEK_END);
53
size_t file_size = ftell(file);
54
fseek(file, 0L, SEEK_SET);
55
wasm_byte_vec_t wat;
56
wasm_byte_vec_new_uninitialized(&wat, file_size);
57
if (fread(wat.data, file_size, 1, file) != 1) {
58
printf("> Error loading module!\n");
59
return 1;
60
}
61
fclose(file);
62
63
// Parse the wat into the binary wasm format
64
wasm_byte_vec_t wasm;
65
wasmtime_error_t *error = wasmtime_wat2wasm(wat.data, wat.size, &wasm);
66
if (error != NULL)
67
exit_with_error("failed to parse wat", error, NULL);
68
wasm_byte_vec_delete(&wat);
69
70
// Now that we've got our binary webassembly we can compile our module.
71
printf("Compiling module...\n");
72
wasmtime_module_t *module = NULL;
73
error = wasmtime_module_new(engine, (uint8_t *)wasm.data, wasm.size, &module);
74
wasm_byte_vec_delete(&wasm);
75
if (error != NULL)
76
exit_with_error("failed to compile module", error, NULL);
77
78
// Next up we need to create the function that the wasm module imports. Here
79
// we'll be hooking up a thunk function to the `hello_callback` native
80
// function above. Note that we can assign custom data, but we just use NULL
81
// for now).
82
printf("Creating callback...\n");
83
wasm_functype_t *hello_ty = wasm_functype_new_0_0();
84
wasmtime_func_t hello;
85
wasmtime_func_new(context, hello_ty, hello_callback, NULL, NULL, &hello);
86
wasm_functype_delete(hello_ty);
87
88
// With our callback function we can now instantiate the compiled module,
89
// giving us an instance we can then execute exports from. Note that
90
// instantiation can trap due to execution of the `start` function, so we need
91
// to handle that here too.
92
printf("Instantiating module...\n");
93
wasm_trap_t *trap = NULL;
94
wasmtime_instance_t instance;
95
wasmtime_extern_t import;
96
import.kind = WASMTIME_EXTERN_FUNC;
97
import.of.func = hello;
98
error = wasmtime_instance_new(context, module, &import, 1, &instance, &trap);
99
if (error != NULL || trap != NULL)
100
exit_with_error("failed to instantiate", error, trap);
101
102
// Lookup our `run` export function
103
printf("Extracting export...\n");
104
wasmtime_extern_t run;
105
bool ok = wasmtime_instance_export_get(context, &instance, "run", 3, &run);
106
assert(ok);
107
assert(run.kind == WASMTIME_EXTERN_FUNC);
108
109
// And call it!
110
printf("Calling export...\n");
111
error = wasmtime_func_call(context, &run.of.func, NULL, 0, NULL, 0, &trap);
112
if (error != NULL || trap != NULL)
113
exit_with_error("failed to call function", error, trap);
114
115
// Clean up after ourselves at this point
116
printf("All finished!\n");
117
ret = 0;
118
119
wasmtime_module_delete(module);
120
wasmtime_store_delete(store);
121
wasm_engine_delete(engine);
122
return ret;
123
}
124
125
static void exit_with_error(const char *message, wasmtime_error_t *error,
126
wasm_trap_t *trap) {
127
fprintf(stderr, "error: %s\n", message);
128
wasm_byte_vec_t error_message;
129
if (error != NULL) {
130
wasmtime_error_message(error, &error_message);
131
wasmtime_error_delete(error);
132
} else {
133
wasm_trap_message(trap, &error_message);
134
wasm_trap_delete(trap);
135
}
136
fprintf(stderr, "%.*s\n", (int)error_message.size, error_message.data);
137
wasm_byte_vec_delete(&error_message);
138
exit(1);
139
}
140
141