[https://wasmer.io/](https://wasmer.io/) - [[WASI]]準拠の[[WASM]]ランタイム - ドキュメント: [https://docs.rs/wasmer/latest/wasmer/](https://docs.rs/wasmer/latest/wasmer/) - Rust API - Example: [https://github.com/wasmerio/wasmer/tree/master/examples](https://github.com/wasmerio/wasmer/tree/master/examples) - ```サンプルコード, use std::{env, process::exit}; use tokio::runtime::Runtime; use wasmer::{Store, Module}; use wasmer_wasix::WasiEnv; fn main() { let args: Vec<String> = env::args().collect(); if args.len() != 2 { exit(1) } let rt = Runtime::new().expect("Error: Tokio Runtime"); rt.block_on(async { // Load let wasm_filename = &args[1]; let wasm_bytes = std::fs::read(wasm_filename).expect("Error: Wasmファイルの読み込みに失敗"); // Create Store let mut store = Store::default(); // Compile let module = Module::new(&store, wasm_bytes).expect("Error: コンパイル失敗"); // wasi(x) env let wasi_env_builder = WasiEnv::builder("progname"); let (instance, env) = wasi_env_builder.instantiate(module, &mut store).expect("Error: インスタンス化に失敗"); let start_func = instance.exports.get_function("_start").expect("Error: _start関数がない"); let result = start_func.call(&mut store, &[]); match result { Ok(v) => { println!("Success: {:?}", v); } Err(e) => { println!("Runtime error: {}", e.message()); } } }) } ``` - C API - [https://github.com/wasmerio/wasmer/tree/master/lib/c-api](https://github.com/wasmerio/wasmer/tree/master/lib/c-api) - ドキュメント: [https://wasmerio.github.io/wasmer/crates/doc/wasmer_c_api/](https://wasmerio.github.io/wasmer/crates/doc/wasmer_c_api/) - Examples: [https://github.com/wasmerio/wasmer/tree/master/lib/c-api/examples](https://github.com/wasmerio/wasmer/tree/master/lib/c-api/examples) - ```サンプルコード, #include <malloc/_malloc.h> #include <stdio.h> #include <stddef.h> #include <string.h> #include "headers/wasm.h" #include "headers/wasmer.h" void print_wasmer_error() { int error_len = wasmer_last_error_length(); if (error_len > 0) { printf("Error len: `%d`\n", error_len); char *error_str = malloc(error_len); wasmer_last_error_message(error_str, error_len); fprintf(stderr, "Error str: `%s`\n", error_str); free(error_str); } } int main(int argc, const char* argv[]) { // Args check // ./runner file.wasm func_name if (argc <= 2) { fprintf(stderr, "Error: argc <= 2\n"); return 1; } // Init wasm_engine_t* engine = wasm_engine_new(); wasm_store_t* store = wasm_store_new(engine); // Setup WASI wasi_config_t* config = wasi_config_new("prog_name"); // Load binary FILE* file = fopen(argv[1], "rb"); if (!file) { fprintf(stderr, "Cannot open %s\nFailed to load wasm...\n", argv[1]); 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) { fprintf(stderr, "Error: initializing module\n"); return 1; } fclose(file); // Create module (Compile) wasm_module_t* module = wasm_module_new(store, &binary); if (!module) { fprintf(stderr, "Error: compiling module\n"); return 1; } wasm_byte_vec_delete(&binary); // Init wasi env wasi_env_t* wasi_env = wasi_env_new(store, config); if (!wasi_env) { fprintf(stderr, "Error: building WASI env\n"); return 1; } // WASI Imports wasm_extern_vec_t imports; bool get_imports_result = wasi_get_imports(store, wasi_env, module, &imports); if (!get_imports_result) { fprintf(stderr, "Failed to getting wasi imports\n"); return 1; } wasm_instance_t* instance = wasm_instance_new(store, module, &imports, NULL); if (!instance) { fprintf(stderr, "Error instantiating module\n"); print_wasmer_error(); return 1; } if (!wasi_env_initialize_instance(wasi_env, store, instance)) { fprintf(stderr, "Error initializing wasi env memory"); print_wasmer_error(); return 1; } wasm_extern_vec_t exports; wasm_instance_exports(instance, &exports); wasm_exporttype_vec_t export_types; wasm_module_exports(module, &export_types); for (size_t i = 0; i < export_types.size; i++) { wasm_exporttype_t* exptype = export_types.data[i]; if (wasm_externtype_kind(wasm_exporttype_type(exptype)) == WASM_EXTERN_FUNC) { const wasm_name_t* exp_name = wasm_exporttype_name(exptype); char *func_name = malloc(exp_name->size + 1); for (size_t j = 0; j < exp_name->size; j++) { func_name[j] = exp_name->data[j]; } func_name[exp_name->size] = '\0'; if (strcmp(func_name, argv[2]) == 0) { // hit fprintf(stderr, "calling...\n"); wasm_val_t func_res_val[1] = { WASM_INIT_VAL }; wasm_val_vec_t func_res = WASM_ARRAY_VEC(func_res_val); wasm_func_t* target_func = wasm_extern_as_func(exports.data[i]); if (wasm_func_call(target_func, NULL, &func_res)) { fprintf(stderr, "Failed calling the add function\n"); print_wasmer_error(); return 1; } printf("%s: %d\n", func_name, func_res_val[0].of.i32); wasm_func_delete(target_func); } free(func_name); } } // Shut down wasi_env_delete(wasi_env); wasm_module_delete(module); wasm_instance_delete(instance); wasm_store_delete(store); wasm_engine_delete(engine); fprintf(stderr, "bye\n"); } ```