Yury Delendik
5 years ago
committed by
GitHub
7 changed files with 286 additions and 4 deletions
@ -0,0 +1,99 @@ |
|||
#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; |
|||
} |
@ -0,0 +1,13 @@ |
|||
// 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.
@ -0,0 +1,45 @@ |
|||
// WebAssembly C API extension for Wasmtime
|
|||
|
|||
#ifndef WASMTIME_API_H |
|||
#define WASMTIME_API_H |
|||
|
|||
#include <wasm.h> |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
typedef uint8_t wasmtime_strategy_t; |
|||
enum wasmtime_strategy_enum { // Strategy
|
|||
WASMTIME_STRATEGY_AUTO, |
|||
WASMTIME_STRATEGY_CRANELIFT, |
|||
WASMTIME_STRATEGY_LIGHTBEAM, |
|||
}; |
|||
|
|||
typedef uint8_t wasmtime_opt_level_t; |
|||
enum wasmtime_opt_level_enum { // OptLevel
|
|||
WASMTIME_OPT_LEVEL_NONE, |
|||
WASMTIME_OPT_LEVEL_SPEED, |
|||
WASMTIME_OPT_LEVEL_SPEED_AND_SIZE, |
|||
}; |
|||
|
|||
#define WASMTIME_CONFIG_PROP(name, ty) \ |
|||
WASM_API_EXTERN void wasmtime_config_##name##_set(wasm_config_t*, ty); |
|||
|
|||
WASMTIME_CONFIG_PROP(debug_info, bool) |
|||
WASMTIME_CONFIG_PROP(wasm_threads, bool) |
|||
WASMTIME_CONFIG_PROP(wasm_reference_types, bool) |
|||
WASMTIME_CONFIG_PROP(wasm_simd, bool) |
|||
WASMTIME_CONFIG_PROP(wasm_bulk_memory, bool) |
|||
WASMTIME_CONFIG_PROP(wasm_multi_value, bool) |
|||
WASMTIME_CONFIG_PROP(strategy, wasmtime_strategy_t) |
|||
WASMTIME_CONFIG_PROP(cranelift_debug_verifier, bool) |
|||
WASMTIME_CONFIG_PROP(cranelift_opt_level, wasmtime_opt_level_t) |
|||
|
|||
///////////////////////////////////////////////////////////////////////////////
|
|||
|
|||
#ifdef __cplusplus |
|||
} // extern "C"
|
|||
#endif |
|||
|
|||
#endif // WASMTIME_API_H
|
@ -0,0 +1,88 @@ |
|||
//! This file defines the extern "C" API extension, which are specific
|
|||
//! to the wasmtime implementation.
|
|||
|
|||
use crate::wasm_config_t; |
|||
use wasmtime::{OptLevel, Strategy}; |
|||
|
|||
#[repr(u8)] |
|||
#[derive(Clone)] |
|||
pub enum wasmtime_strategy_t { |
|||
WASMTIME_STRATEGY_AUTO, |
|||
WASMTIME_STRATEGY_CRANELIFT, |
|||
WASMTIME_STRATEGY_LIGHTBEAM, |
|||
} |
|||
|
|||
#[repr(u8)] |
|||
#[derive(Clone)] |
|||
pub enum wasmtime_opt_level_t { |
|||
WASMTIME_OPT_LEVEL_NONE, |
|||
WASMTIME_OPT_LEVEL_SPEED, |
|||
WASMTIME_OPT_LEVEL_SPEED_AND_SIZE, |
|||
} |
|||
|
|||
#[no_mangle] |
|||
pub unsafe extern "C" fn wasmtime_config_debug_info_set(c: *mut wasm_config_t, enable: bool) { |
|||
(*c).config.debug_info(enable); |
|||
} |
|||
|
|||
#[no_mangle] |
|||
pub unsafe extern "C" fn wasmtime_config_wasm_threads_set(c: *mut wasm_config_t, enable: bool) { |
|||
(*c).config.wasm_threads(enable); |
|||
} |
|||
|
|||
#[no_mangle] |
|||
pub unsafe extern "C" fn wasmtime_config_wasm_reference_types_set( |
|||
c: *mut wasm_config_t, |
|||
enable: bool, |
|||
) { |
|||
(*c).config.wasm_reference_types(enable); |
|||
} |
|||
|
|||
#[no_mangle] |
|||
pub unsafe extern "C" fn wasmtime_config_wasm_simd_set(c: *mut wasm_config_t, enable: bool) { |
|||
(*c).config.wasm_simd(enable); |
|||
} |
|||
|
|||
#[no_mangle] |
|||
pub unsafe extern "C" fn wasmtime_config_wasm_bulk_memory_set(c: *mut wasm_config_t, enable: bool) { |
|||
(*c).config.wasm_bulk_memory(enable); |
|||
} |
|||
|
|||
#[no_mangle] |
|||
pub unsafe extern "C" fn wasmtime_config_wasm_multi_value_set(c: *mut wasm_config_t, enable: bool) { |
|||
(*c).config.wasm_multi_value(enable); |
|||
} |
|||
|
|||
#[no_mangle] |
|||
pub unsafe extern "C" fn wasmtime_config_strategy_set( |
|||
c: *mut wasm_config_t, |
|||
strategy: wasmtime_strategy_t, |
|||
) { |
|||
use wasmtime_strategy_t::*; |
|||
drop((*c).config.strategy(match strategy { |
|||
WASMTIME_STRATEGY_AUTO => Strategy::Auto, |
|||
WASMTIME_STRATEGY_CRANELIFT => Strategy::Cranelift, |
|||
WASMTIME_STRATEGY_LIGHTBEAM => Strategy::Lightbeam, |
|||
})); |
|||
} |
|||
|
|||
#[no_mangle] |
|||
pub unsafe extern "C" fn wasmtime_config_cranelift_debug_verifier_set( |
|||
c: *mut wasm_config_t, |
|||
enable: bool, |
|||
) { |
|||
(*c).config.cranelift_debug_verifier(enable); |
|||
} |
|||
|
|||
#[no_mangle] |
|||
pub unsafe extern "C" fn wasmtime_config_cranelift_opt_level_set( |
|||
c: *mut wasm_config_t, |
|||
opt_level: wasmtime_opt_level_t, |
|||
) { |
|||
use wasmtime_opt_level_t::*; |
|||
(*c).config.cranelift_opt_level(match opt_level { |
|||
WASMTIME_OPT_LEVEL_NONE => OptLevel::None, |
|||
WASMTIME_OPT_LEVEL_SPEED => OptLevel::Speed, |
|||
WASMTIME_OPT_LEVEL_SPEED_AND_SIZE => OptLevel::SpeedAndSize, |
|||
}); |
|||
} |
Loading…
Reference in new issue