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