Move all examples to a top-level directory (#1286)
* 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.
This commit is contained in:
@@ -1,171 +0,0 @@
|
||||
###############################################################################
|
||||
# Configuration
|
||||
|
||||
# Inherited from wasm-c-api/Makefile to just run C examples
|
||||
|
||||
WASM_FLAGS = -DWASM_API_DEBUG # -DWASM_API_DEBUG_LOG
|
||||
C_FLAGS = ${WASM_FLAGS} -Wall -Werror -ggdb -O -fsanitize=address
|
||||
CC_FLAGS = -std=c++11 ${C_FLAGS}
|
||||
LD_FLAGS = -fsanitize-memory-track-origins -fsanitize-memory-use-after-dtor
|
||||
|
||||
C_COMP = clang
|
||||
|
||||
WASMTIME_API_MODE = debug
|
||||
|
||||
|
||||
# Base directories
|
||||
WASMTIME_API_DIR = ..
|
||||
WASM_DIR = wasm-c-api
|
||||
EXAMPLE_DIR = ${WASM_DIR}/example
|
||||
OUT_DIR = ${WASM_DIR}/out
|
||||
|
||||
# Example config
|
||||
EXAMPLE_OUT = ${OUT_DIR}/example
|
||||
EXAMPLES = \
|
||||
hello \
|
||||
callback \
|
||||
trap \
|
||||
start \
|
||||
reflect \
|
||||
global \
|
||||
table \
|
||||
memory \
|
||||
hostref \
|
||||
finalize \
|
||||
serialize \
|
||||
threads \
|
||||
# multi \
|
||||
|
||||
# Wasm config
|
||||
WASM_INCLUDE = ${WASM_DIR}/include
|
||||
WASM_SRC = ${WASM_DIR}/src
|
||||
WASM_OUT = ${OUT_DIR}
|
||||
WASM_C_LIBS = wasm-bin wasm-rust-api
|
||||
WASM_CC_LIBS = $(error unsupported C++)
|
||||
|
||||
|
||||
# Compiler config
|
||||
ifeq (${WASMTIME_API_MODE},release)
|
||||
CARGO_BUILD_FLAGS = --release
|
||||
else
|
||||
CARGO_BUILD_FLAGS =
|
||||
endif
|
||||
|
||||
ifeq (${C_COMP},clang)
|
||||
CC_COMP = clang++
|
||||
LD_GROUP_START =
|
||||
LD_GROUP_END =
|
||||
else ifeq (${C_COMP},gcc)
|
||||
CC_COMP = g++
|
||||
LD_GROUP_START = -Wl,--start-group
|
||||
LD_GROUP_END = -Wl,--end-group
|
||||
else
|
||||
$(error C_COMP set to unknown compiler, must be clang or gcc)
|
||||
endif
|
||||
|
||||
WASMTIME_BIN_DIR = ${WASMTIME_API_DIR}/../../target/${WASMTIME_API_MODE}
|
||||
WASMTIME_C_LIB_DIR = ${WASMTIME_BIN_DIR}
|
||||
WASMTIME_C_LIBS = wasmtime
|
||||
WASMTIME_CC_LIBS = $(error unsupported c++)
|
||||
|
||||
WASMTIME_C_BINS = ${WASMTIME_C_LIBS:%=${WASMTIME_C_LIB_DIR}/lib%.a}
|
||||
|
||||
###############################################################################
|
||||
# Examples
|
||||
#
|
||||
# To build Wasm APIs and run all examples:
|
||||
# make all
|
||||
#
|
||||
# To run only C examples:
|
||||
# make c
|
||||
#
|
||||
# To run only C++ examples:
|
||||
# make cc
|
||||
#
|
||||
# To run individual C example (e.g. hello):
|
||||
# make run-hello-c
|
||||
#
|
||||
# To run individual C++ example (e.g. hello):
|
||||
# make run-hello-cc
|
||||
#
|
||||
|
||||
.PHONY: all cc c
|
||||
all: cc c
|
||||
cc: ${EXAMPLES:%=run-%-cc}
|
||||
c: ${EXAMPLES:%=run-%-c}
|
||||
|
||||
# Running a C / C++ example
|
||||
run-%-c: ${EXAMPLE_OUT}/%-c ${EXAMPLE_OUT}/%.wasm
|
||||
@echo ==== C ${@:run-%-c=%} ====; \
|
||||
cd ${EXAMPLE_OUT}; ./${@:run-%=%}
|
||||
@echo ==== Done ====
|
||||
|
||||
run-%-cc: ${EXAMPLE_OUT}/%-cc ${EXAMPLE_OUT}/%.wasm
|
||||
@echo ==== C++ ${@:run-%-cc=%} ====; \
|
||||
cd ${EXAMPLE_OUT}; ./${@:run-%=%}
|
||||
@echo ==== Done ====
|
||||
|
||||
# Compiling C / C++ example
|
||||
${EXAMPLE_OUT}/%-c.o: ${EXAMPLE_DIR}/%.c ${WASM_INCLUDE}/wasm.h
|
||||
mkdir -p ${EXAMPLE_OUT}
|
||||
${C_COMP} -c ${C_FLAGS} -I. -I${WASM_INCLUDE} $< -o $@
|
||||
|
||||
${EXAMPLE_OUT}/%-cc.o: ${EXAMPLE_DIR}/%.cc ${WASM_INCLUDE}/wasm.hh
|
||||
mkdir -p ${EXAMPLE_OUT}
|
||||
${CC_COMP} -c ${CC_FLAGS} -I. -I${WASM_INCLUDE} $< -o $@
|
||||
|
||||
# Linking C / C++ example
|
||||
.PRECIOUS: ${EXAMPLES:%=${EXAMPLE_OUT}/%-c}
|
||||
${EXAMPLE_OUT}/%-c: ${EXAMPLE_OUT}/%-c.o ${WASMTIME_C_BINS}
|
||||
${CC_COMP} ${CC_FLAGS} ${LD_FLAGS} $< -o $@ \
|
||||
${LD_GROUP_START} \
|
||||
${WASMTIME_C_BINS} \
|
||||
${LD_GROUP_END} \
|
||||
-ldl -pthread
|
||||
|
||||
# Installing Wasm binaries
|
||||
.PRECIOUS: ${EXAMPLES:%=${EXAMPLE_OUT}/%.wasm}
|
||||
${EXAMPLE_OUT}/%.wasm: ${EXAMPLE_DIR}/%.wasm
|
||||
cp $< $@
|
||||
|
||||
###############################################################################
|
||||
# Wasm C / C++ API
|
||||
#
|
||||
# To build both C / C++ APIs:
|
||||
# make wasm
|
||||
|
||||
.PHONY: wasm wasm-c wasm-cc
|
||||
wasm: wasm-c wasm-cc
|
||||
wasm-c: ${WASMTIME_C_BIN}
|
||||
wasm-cc: ${WASMTIME_CC_BIN}
|
||||
|
||||
${WASMTIME_C_BINS}: CARGO_RUN
|
||||
cd ${WASMTIME_API_DIR}; cargo build --lib ${CARGO_BUILD_FLAGS}
|
||||
|
||||
.PHONY: CARGO_RUN
|
||||
CARGO_RUN:
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Clean-up
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf ${OUT_DIR}
|
||||
|
||||
###############################################################################
|
||||
# Other examples
|
||||
|
||||
WASM_EXT_INCLUDE = ${WASMTIME_API_DIR}/include
|
||||
|
||||
run-config-debug-c: ${EXAMPLE_OUT}/config-debug-c ${EXAMPLE_OUT}/fib-wasm.wasm
|
||||
@echo ==== C config ====; \
|
||||
cd ${EXAMPLE_OUT}; ./config-debug-c
|
||||
@echo ==== Done ====
|
||||
|
||||
${EXAMPLE_OUT}/fib-wasm.wasm: fib-wasm.wasm
|
||||
cp $< $@
|
||||
|
||||
${EXAMPLE_OUT}/config-debug-c.o: config-debug.c ${WASM_INCLUDE}/wasm.h ${WASM_EXT_INCLUDE}/wasmtime.h
|
||||
mkdir -p ${EXAMPLE_OUT}
|
||||
${C_COMP} -c ${C_FLAGS} -I. -I${WASM_INCLUDE} -I${WASM_EXT_INCLUDE} $< -o $@
|
||||
@@ -1,99 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <wasm.h>
|
||||
#include "wasmtime.h"
|
||||
|
||||
#define own
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
// Configuring engine to support generating of DWARF info.
|
||||
// lldb can be used to attach to the program and observe
|
||||
// original fib-wasm.c source code and variables.
|
||||
wasm_config_t* config = wasm_config_new();
|
||||
wasmtime_config_debug_info_set(config, true);
|
||||
|
||||
// Initialize.
|
||||
printf("Initializing...\n");
|
||||
wasm_engine_t* engine = wasm_engine_new_with_config(config);
|
||||
wasm_store_t* store = wasm_store_new(engine);
|
||||
|
||||
// Load binary.
|
||||
printf("Loading binary...\n");
|
||||
FILE* file = fopen("fib-wasm.wasm", "r");
|
||||
if (!file) {
|
||||
printf("> Error loading module!\n");
|
||||
return 1;
|
||||
}
|
||||
fseek(file, 0L, SEEK_END);
|
||||
size_t file_size = ftell(file);
|
||||
fseek(file, 0L, SEEK_SET);
|
||||
wasm_byte_vec_t binary;
|
||||
wasm_byte_vec_new_uninitialized(&binary, file_size);
|
||||
if (fread(binary.data, file_size, 1, file) != 1) {
|
||||
printf("> Error loading module!\n");
|
||||
return 1;
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
// Compile.
|
||||
printf("Compiling module...\n");
|
||||
own wasm_module_t* module = wasm_module_new(store, &binary);
|
||||
if (!module) {
|
||||
printf("> Error compiling module!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wasm_byte_vec_delete(&binary);
|
||||
|
||||
// Instantiate.
|
||||
printf("Instantiating module...\n");
|
||||
own wasm_instance_t* instance =
|
||||
wasm_instance_new(store, module, NULL, NULL);
|
||||
if (!instance) {
|
||||
printf("> Error instantiating module!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Extract export.
|
||||
printf("Extracting export...\n");
|
||||
own wasm_extern_vec_t exports;
|
||||
wasm_instance_exports(instance, &exports);
|
||||
if (exports.size == 0) {
|
||||
printf("> Error accessing exports!\n");
|
||||
return 1;
|
||||
}
|
||||
// Getting second export (first is memory).
|
||||
const wasm_func_t* run_func = wasm_extern_as_func(exports.data[1]);
|
||||
if (run_func == NULL) {
|
||||
printf("> Error accessing export!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wasm_module_delete(module);
|
||||
wasm_instance_delete(instance);
|
||||
|
||||
// Call.
|
||||
printf("Calling fib...\n");
|
||||
wasm_val_t params[1] = { {.kind = WASM_I32, .of = {.i32 = 6}} };
|
||||
wasm_val_t results[1];
|
||||
if (wasm_func_call(run_func, params, results)) {
|
||||
printf("> Error calling function!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wasm_extern_vec_delete(&exports);
|
||||
|
||||
printf("> fib(6) = %d\n", results[0].of.i32);
|
||||
|
||||
// Shut down.
|
||||
printf("Shutting down...\n");
|
||||
wasm_store_delete(store);
|
||||
wasm_engine_delete(engine);
|
||||
|
||||
// All done.
|
||||
printf("Done.\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
// Compile with:
|
||||
// clang --target=wasm32 fib-wasm.c -o fib-wasm.wasm -g \
|
||||
// -Wl,--no-entry,--export=fib -nostdlib -fdebug-prefix-map=$PWD=.
|
||||
|
||||
int fib(int n) {
|
||||
int i, t, a = 0, b = 1;
|
||||
for (i = 0; i < n; i++) {
|
||||
t = a;
|
||||
a = b;
|
||||
b += t;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
Binary file not shown.
@@ -9,6 +9,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define own
|
||||
|
||||
typedef uint8_t wasmtime_strategy_t;
|
||||
enum wasmtime_strategy_enum { // Strategy
|
||||
WASMTIME_STRATEGY_AUTO,
|
||||
@@ -51,13 +53,15 @@ WASMTIME_CONFIG_PROP(cranelift_opt_level, wasmtime_opt_level_t)
|
||||
// optional.
|
||||
//
|
||||
// Returns `true` if conversion succeeded, or `false` if it failed.
|
||||
bool wasmtime_wat2wasm(
|
||||
WASM_API_EXTERN bool wasmtime_wat2wasm(
|
||||
wasm_engine_t *engine,
|
||||
const wasm_byte_vec_t *wat,
|
||||
own wasm_byte_vec_t *ret,
|
||||
own wasm_byte_vec_t *error_message,
|
||||
own wasm_byte_vec_t *error_message
|
||||
);
|
||||
|
||||
#undef own
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user