Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/examples/multi.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-multi
8
9
Also note that this example was taken from
10
https://github.com/WebAssembly/wasm-c-api/blob/master/example/multi.c
11
originally
12
*/
13
14
#include <inttypes.h>
15
#include <stdio.h>
16
#include <stdlib.h>
17
#include <string.h>
18
#include <wasm.h>
19
#include <wasmtime.h>
20
21
static void exit_with_error(const char *message, wasmtime_error_t *error,
22
wasm_trap_t *trap);
23
24
// A function to be called from Wasm code.
25
wasm_trap_t *callback(void *env, wasmtime_caller_t *caller,
26
const wasmtime_val_t *args, size_t nargs,
27
wasmtime_val_t *results, size_t nresults) {
28
printf("Calling back...\n");
29
printf("> %" PRIu32 " %" PRIu64 "\n", args[0].of.i32, args[1].of.i64);
30
printf("\n");
31
32
results[0] = args[1];
33
results[1] = args[0];
34
return NULL;
35
}
36
37
// A function closure.
38
wasm_trap_t *closure_callback(void *env, wasmtime_caller_t *caller,
39
const wasmtime_val_t *args, size_t nargs,
40
wasmtime_val_t *results, size_t nresults) {
41
int i = *(int *)env;
42
printf("Calling back closure...\n");
43
printf("> %d\n", i);
44
45
results[0].kind = WASMTIME_I32;
46
results[0].of.i32 = (int32_t)i;
47
return NULL;
48
}
49
50
int main(int argc, const char *argv[]) {
51
// Initialize.
52
printf("Initializing...\n");
53
wasm_engine_t *engine = wasm_engine_new();
54
wasmtime_store_t *store = wasmtime_store_new(engine, NULL, NULL);
55
wasmtime_context_t *context = wasmtime_store_context(store);
56
57
// Load our input file to parse it next
58
FILE *file = fopen("examples/multi.wat", "r");
59
if (!file) {
60
printf("> Error loading file!\n");
61
return 1;
62
}
63
fseek(file, 0L, SEEK_END);
64
size_t file_size = ftell(file);
65
fseek(file, 0L, SEEK_SET);
66
wasm_byte_vec_t wat;
67
wasm_byte_vec_new_uninitialized(&wat, file_size);
68
if (fread(wat.data, file_size, 1, file) != 1) {
69
printf("> Error loading module!\n");
70
return 1;
71
}
72
fclose(file);
73
74
// Parse the wat into the binary wasm format
75
wasm_byte_vec_t binary;
76
wasmtime_error_t *error = wasmtime_wat2wasm(wat.data, wat.size, &binary);
77
if (error != NULL)
78
exit_with_error("failed to parse wat", error, NULL);
79
wasm_byte_vec_delete(&wat);
80
81
// Compile.
82
printf("Compiling module...\n");
83
wasmtime_module_t *module = NULL;
84
error =
85
wasmtime_module_new(engine, (uint8_t *)binary.data, binary.size, &module);
86
if (error)
87
exit_with_error("failed to compile module", error, NULL);
88
wasm_byte_vec_delete(&binary);
89
90
// Create external print functions.
91
printf("Creating callback...\n");
92
wasm_functype_t *callback_type =
93
wasm_functype_new_2_2(wasm_valtype_new_i32(), wasm_valtype_new_i64(),
94
wasm_valtype_new_i64(), wasm_valtype_new_i32());
95
wasmtime_func_t callback_func;
96
wasmtime_func_new(context, callback_type, callback, NULL, NULL,
97
&callback_func);
98
wasm_functype_delete(callback_type);
99
100
// Instantiate.
101
printf("Instantiating module...\n");
102
wasmtime_extern_t imports[1];
103
imports[0].kind = WASMTIME_EXTERN_FUNC;
104
imports[0].of.func = callback_func;
105
wasmtime_instance_t instance;
106
wasm_trap_t *trap = NULL;
107
error = wasmtime_instance_new(context, module, imports, 1, &instance, &trap);
108
if (error != NULL || trap != NULL)
109
exit_with_error("failed to instantiate", error, trap);
110
wasmtime_module_delete(module);
111
112
// Extract export.
113
printf("Extracting export...\n");
114
wasmtime_extern_t run;
115
bool ok = wasmtime_instance_export_get(context, &instance, "g", 1, &run);
116
assert(ok);
117
assert(run.kind == WASMTIME_EXTERN_FUNC);
118
119
// Call.
120
printf("Calling export...\n");
121
wasmtime_val_t args[2];
122
args[0].kind = WASMTIME_I32;
123
args[0].of.i32 = 1;
124
args[1].kind = WASMTIME_I64;
125
args[1].of.i64 = 2;
126
wasmtime_val_t results[2];
127
error = wasmtime_func_call(context, &run.of.func, args, 2, results, 2, &trap);
128
if (error != NULL || trap != NULL)
129
exit_with_error("failed to call run", error, trap);
130
131
// Print result.
132
printf("Printing result...\n");
133
printf("> %" PRIu64 " %" PRIu32 "\n", results[0].of.i64, results[1].of.i32);
134
135
assert(results[0].kind == WASMTIME_I64);
136
assert(results[0].of.i64 == 2);
137
assert(results[1].kind == WASMTIME_I32);
138
assert(results[1].of.i32 == 1);
139
140
// Shut down.
141
printf("Shutting down...\n");
142
wasmtime_store_delete(store);
143
wasm_engine_delete(engine);
144
145
// All done.
146
printf("Done.\n");
147
return 0;
148
}
149
150
static void exit_with_error(const char *message, wasmtime_error_t *error,
151
wasm_trap_t *trap) {
152
fprintf(stderr, "error: %s\n", message);
153
wasm_byte_vec_t error_message;
154
if (error != NULL) {
155
wasmtime_error_message(error, &error_message);
156
wasmtime_error_delete(error);
157
} else {
158
wasm_trap_message(trap, &error_message);
159
wasm_trap_delete(trap);
160
}
161
fprintf(stderr, "%.*s\n", (int)error_message.size, error_message.data);
162
wasm_byte_vec_delete(&error_message);
163
exit(1);
164
}
165
166