* Move all examples to a top-level directory This commit moves all API examples (Rust and C) to a top-level `examples` directory. This is intended to make it more discoverable and conventional as to where examples are located. Additionally all examples are now available in both Rust and C to see how to execute the example in the language you're familiar with. The intention is that as more languages are supported we'd add more languages as examples here too. Each example is also accompanied by either a `*.wat` file which is parsed as input, or a Rust project in a `wasm` folder which is compiled as input. A simple driver crate was also added to `crates/misc` which executes all the examples on CI, ensuring the C and Rust examples all execute successfully.
119 lines
3.0 KiB
C
119 lines
3.0 KiB
C
/*
|
|
Example of instantiating of the WebAssembly module and invoking its exported
|
|
function.
|
|
|
|
You can compile and run this example on Linux with:
|
|
|
|
cargo build --release -p wasmtime
|
|
cc examples/gcd.c \
|
|
-I crates/c-api/include \
|
|
-I crates/c-api/wasm-c-api/include \
|
|
target/release/libwasmtime.a \
|
|
-lpthread -ldl -lm \
|
|
-o gcd
|
|
./gcd
|
|
|
|
Note that on Windows and macOS the command will be similar, but you'll need
|
|
to tweak the `-lpthread` and such annotations.
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <wasm.h>
|
|
#include <wasmtime.h>
|
|
|
|
static void print_trap(wasm_trap_t *trap);
|
|
|
|
int main() {
|
|
int ret = 0;
|
|
// Set up our context
|
|
wasm_engine_t *engine = wasm_engine_new();
|
|
assert(engine != NULL);
|
|
wasm_store_t *store = wasm_store_new(engine);
|
|
assert(store != NULL);
|
|
|
|
// Load our input file to parse it next
|
|
FILE* file = fopen("examples/gcd.wat", "r");
|
|
if (!file) {
|
|
printf("> Error loading file!\n");
|
|
return 1;
|
|
}
|
|
fseek(file, 0L, SEEK_END);
|
|
size_t file_size = ftell(file);
|
|
fseek(file, 0L, SEEK_SET);
|
|
wasm_byte_vec_t wat;
|
|
wasm_byte_vec_new_uninitialized(&wat, file_size);
|
|
if (fread(wat.data, file_size, 1, file) != 1) {
|
|
printf("> Error loading module!\n");
|
|
return 1;
|
|
}
|
|
fclose(file);
|
|
|
|
// Parse the wat into the binary wasm format
|
|
wasm_byte_vec_t wasm, error;
|
|
if (wasmtime_wat2wasm(engine, &wat, &wasm, &error) == 0) {
|
|
fprintf(stderr, "failed to parse wat %.*s\n", (int) error.size, error.data);
|
|
goto free_store;
|
|
}
|
|
wasm_byte_vec_delete(&wat);
|
|
|
|
// Compile and instantiate our module
|
|
wasm_module_t *module = wasm_module_new(store, &wasm);
|
|
wasm_byte_vec_delete(&wasm);
|
|
assert(module != NULL);
|
|
wasm_trap_t *trap = NULL;
|
|
wasm_instance_t *instance = wasm_instance_new(store, module, NULL, &trap);
|
|
if (instance == NULL) {
|
|
print_trap(trap);
|
|
goto free_module;
|
|
}
|
|
|
|
// Lookup our `gcd` export function
|
|
wasm_extern_vec_t externs;
|
|
wasm_instance_exports(instance, &externs);
|
|
assert(externs.size == 1);
|
|
wasm_func_t *gcd = wasm_extern_as_func(externs.data[0]);
|
|
assert(gcd != NULL);
|
|
|
|
// And call it!
|
|
int a = 6;
|
|
int b = 27;
|
|
wasm_val_t params[2];
|
|
wasm_val_t results[1];
|
|
params[0].kind = WASM_I32;
|
|
params[0].of.i32 = a;
|
|
params[1].kind = WASM_I32;
|
|
params[1].of.i32 = b;
|
|
trap = wasm_func_call(gcd, params, results);
|
|
if (trap != NULL) {
|
|
print_trap(trap);
|
|
goto free_instance;
|
|
}
|
|
assert(results[0].kind == WASM_I32);
|
|
|
|
printf("gcd(%d, %d) = %d\n", a, b, results[0].of.i32);
|
|
|
|
// Clean up after ourselves at this point
|
|
ret = 0;
|
|
|
|
free_instance:
|
|
wasm_extern_vec_delete(&externs);
|
|
wasm_instance_delete(instance);
|
|
free_module:
|
|
wasm_module_delete(module);
|
|
free_store:
|
|
wasm_store_delete(store);
|
|
wasm_engine_delete(engine);
|
|
return ret;
|
|
}
|
|
|
|
static void print_trap(wasm_trap_t *trap) {
|
|
assert(trap != NULL);
|
|
wasm_message_t message;
|
|
wasm_trap_message(trap, &message);
|
|
fprintf(stderr, "failed to instantiate module %.*s\n", (int) message.size, message.data);
|
|
wasm_byte_vec_delete(&message);
|
|
wasm_trap_delete(trap);
|
|
}
|