diff --git a/src/config.zig b/src/config.zig index f9450af..864c7b0 100644 --- a/src/config.zig +++ b/src/config.zig @@ -1,30 +1,214 @@ -// https://github.com/bytecodealliance/wasmtime/blob/main/crates/c-api/include/wasmtime/config.h +const Error = @import("./error.zig").Error; -/// Global engine configuration +/// Global configuration options used to create an `Engine` and customize its +/// behavior. This is exposed as a builder-like interface and is primarily +/// consumed by `Engine.init`. /// -/// This structure represents global configuration used when constructing an -/// `Engine`. Configuration is safe to share between threads. Typically you'll -/// create a config object and immediately pass it into -/// `Engine.initWithConfig`, however. +/// The validation of `Config` is deferred until the engine is being built, +/// thus a problematic config may cause `Engine.init` to fail. /// -/// For more information about configuration see the Rust documentation as -/// well at https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Config.html. +/// For more information on what each of these settings do and their default +/// values, see https://docs.rs/wasmtime/11.0.1/wasmtime/struct.Config.html. pub const Config = opaque { /// Creates a new empty configuration object. /// - /// The object returned is owned by the caller and will need to be deleted - /// with `deinit`. May return `error.ConfigInit` if a configuration object - /// could not be allocated. + /// The object returned is owned by the caller and will need to be deleted with `deinit`. + /// + /// May return `error.ConfigInit` if a configuration object could not be allocated. pub fn init() !*Config { return wasm_config_new() orelse error.ConfigInit; } + /// Deletes a configuration object. pub fn deinit(self: *Config) void { wasm_config_delete(self); } - // TODO: More bindings! + /// Configures whether DWARF debug information will be emitted during compilation. + pub fn debugInfo(self: *Config, enabled: bool) void { + wasmtime_config_debug_info_set(self, enabled); + } + + /// Configures whether execution of WebAssembly will “consume fuel” to + /// either halt or yield execution as desired. + pub fn comsumeFuel(self: *Config, enabled: bool) void { + wasmtime_config_consume_fuel_set(self, enabled); + } + + /// Configures whether to enable epoch-based interruption. + pub fn epochInterruption(self: *Config, enabled: bool) void { + wasmtime_config_epoch_interruption_set(self, enabled); + } + + /// Configures the maximum amount of stack space available for executing WebAssembly code. + pub fn maxWasmStack(self: *Config, value: usize) void { + wasmtime_config_max_wasm_stack_set(self, value); + } + + /// Configures whether the WebAssembly threads proposal will be enabled for compilation. + pub fn wasmThreads(self: *Config, enabled: bool) void { + wasmtime_config_wasm_threads_set(self, enabled); + } + + /// Configures whether the WebAssembly reference types proposal will be enabled for compilation. + pub fn wasmReferenceTypes(self: *Config, enabled: bool) void { + wasmtime_config_wasm_reference_types_set(self, enabled); + } + + /// Configures whether the WebAssembly SIMD proposal will be enabled for compilation. + pub fn wasmSimd(self: *Config, enabled: bool) void { + wasmtime_config_wasm_simd_set(self, enabled); + } + + /// Configures whether the WebAssembly Relaxed SIMD proposal will be enabled for compilation. + pub fn wasmRelaxedSimd(self: *Config, enabled: bool) void { + wasmtime_config_wasm_relaxed_simd_set(self, enabled); + } + + /// This option can be used to control the behavior of the relaxed SIMD proposal’s instructions. + pub fn wasmRelaxedSimdDeterministic(self: *Config, enabled: bool) void { + wasmtime_config_wasm_relaxed_simd_deterministic_set(self, enabled); + } + + /// Configures whether the WebAssembly bulk memory operations proposal will be enabled for compilation. + pub fn wasmBulkMemory(self: *Config, enabled: bool) void { + wasmtime_config_wasm_bulk_memory_set(self, enabled); + } + + /// Configures whether the WebAssembly multi-value proposal will be enabled for compilation. + pub fn wasmMultiValue(self: *Config, enabled: bool) void { + wasmtime_config_wasm_multi_value_set(self, enabled); + } + + /// Configures whether the WebAssembly multi-memory proposal will be enabled for compilation. + pub fn wasmMultiMemory(self: *Config, enabled: bool) void { + wasmtime_config_wasm_multi_memory_set(self, enabled); + } + + /// Configures whether the WebAssembly memory64 proposal will be enabled for compilation. + pub fn wasmMemory64(self: *Config, enabled: bool) void { + wasmtime_config_wasm_memory64_set(self, enabled); + } + + /// Configures which compilation strategy will be used for wasm modules. + pub fn strategy(self: *Config, value: Strategy) void { + wasmtime_config_strategy_set(self, value); + } + + /// Creates a default profiler based on the profiling strategy chosen. + pub fn profiler(self: *Config, value: ProfilingStrategy) void { + wasmtime_config_profiler_set(self, value); + } + + /// Configures whether the debug verifier of Cranelift is enabled or not. + pub fn craneliftDebugVerifier(self: *Config, enabled: bool) void { + wasmtime_config_cranelift_debug_verifier_set(self, enabled); + } + + /// Configures whether Cranelift should perform a NaN-canonicalization pass. + pub fn craneliftNanCanonicalization(self: *Config, enabled: bool) void { + wasmtime_config_cranelift_nan_canonicalization_set(self, enabled); + } + + /// Configures the Cranelift code generator optimization level. + pub fn craneliftOptLevel(self: *Config, value: OptLevel) void { + wasmtime_config_cranelift_opt_level_set(self, value); + } + + /// Configure wether wasmtime should compile a module using multiple threads. + pub fn parallelCompilation(self: *Config, enabled: bool) void { + wasmtime_config_parallel_compilation_set(self, enabled); + } + + /// Indicates that the “static” style of memory should always be used. + pub fn staticMemoryForced(self: *Config, enabled: bool) void { + wasmtime_config_static_memory_forced_set(self, enabled); + } + + /// Configures the maximum size, in bytes, where a linear memory is + /// considered static, above which it’ll be considered dynamic. + pub fn staticMemoryMaximumSize(self: *Config, value: u64) void { + wasmtime_config_static_memory_maximum_size_set(self, value); + } + + /// Configures the size, in bytes, of the guard region used at the end of + /// a static memory’s address space reservation. + pub fn staticMemoryGuardMaximumSize(self: *Config, value: u64) void { + wasmtime_config_static_memory_guard_size_set(self, value); + } + + /// Configures the size, in bytes, of the guard region used at the end of + /// a dynamic memory’s address space reservation. + pub fn dynamicMemoryGuardMaximumSize(self: *Config, value: u64) void { + wasmtime_config_dynamic_memory_guard_size_set(self, value); + } extern "c" fn wasm_config_new() ?*Config; extern "c" fn wasm_config_delete(*Config) void; + extern "c" fn wasmtime_config_debug_info_set(*Config, bool) void; + extern "c" fn wasmtime_config_consume_fuel_set(*Config, bool) void; + extern "c" fn wasmtime_config_epoch_interruption_set(*Config, bool) void; + extern "c" fn wasmtime_config_max_wasm_stack_set(*Config, usize) void; + extern "c" fn wasmtime_config_wasm_threads_set(*Config, bool) void; + extern "c" fn wasmtime_config_wasm_reference_types_set(*Config, bool) void; + extern "c" fn wasmtime_config_wasm_simd_set(*Config, bool) void; + extern "c" fn wasmtime_config_wasm_relaxed_simd_set(*Config, bool) void; + extern "c" fn wasmtime_config_wasm_relaxed_simd_deterministic_set(*Config, bool) void; + extern "c" fn wasmtime_config_wasm_bulk_memory_set(*Config, bool) void; + extern "c" fn wasmtime_config_wasm_multi_value_set(*Config, bool) void; + extern "c" fn wasmtime_config_wasm_multi_memory_set(*Config, bool) void; + extern "c" fn wasmtime_config_wasm_memory64_set(*Config, bool) void; + extern "c" fn wasmtime_config_strategy_set(*Config, Strategy) void; + extern "c" fn wasmtime_config_parallel_compilation_set(*Config, bool) void; + extern "c" fn wasmtime_config_cranelift_debug_verifier_set(*Config, bool) void; + extern "c" fn wasmtime_config_cranelift_nan_canonicalization_set(*Config, bool) void; + extern "c" fn wasmtime_config_cranelift_opt_level_set(*Config, OptLevel) void; + extern "c" fn wasmtime_config_profiler_set(*Config, ProfilingStrategy) void; + extern "c" fn wasmtime_config_static_memory_forced_set(*Config, bool) void; + extern "c" fn wasmtime_config_static_memory_maximum_size_set(*Config, u64) void; + extern "c" fn wasmtime_config_static_memory_guard_size_set(*Config, u64) void; + extern "c" fn wasmtime_config_dynamic_memory_guard_size_set(*Config, u64) void; + // extern "c" fn wasmtime_config_cache_config_load(*Config, [*:0]const u8) ?*Error; +}; + +/// Different ways that Wasmtime can compile WebAssembly. +/// The default value is `.auto`. +pub const Strategy = enum(u8) { + /// Automatically picks the compilation backend, currently always + /// defaulting to Cranelift. + auto, + /// Indicates that Wasmtime will unconditionally use Cranelift to compile + /// WebAssembly code. + cranelift, +}; + +/// Different ways Wasmtime can optimize generated code. +/// The default value is `.speed`. +pub const OptLevel = enum(u8) { + /// Generated code will not be optimized at all. + none, + /// Generated code will be optimized purely for speed. + speed, + /// Generated code will be optimized, but some speed optimizations are + /// disabled if they cause the generated code to be significantly larger. + speed_and_size, +}; + +/// Different ways to profile JIT code. +/// The default value is `.none`. +pub const ProfilingStrategy = enum(u8) { + /// No profiling is enabled at runtime. + none, + /// Linux's "jitdump" support in `perf` is enabled and when Wasmtime is + /// run under `perf` necessary calls will be made to profile generated JIT + /// code. + jitdump, + /// Support for VTune will be enabled and the VTune runtime will be + /// informed, at runtime, about JIT code. Note that this isn't always + /// enabled at build time. + vtune, + /// Linux's simple "perfmap" support in `perf` is enabled and when + /// Wasmtime is run under `perf` necessary calls will be made to profile + /// generated JIT code. + perfmap, }; diff --git a/src/engine.zig b/src/engine.zig index 51b3039..2727ccb 100644 --- a/src/engine.zig +++ b/src/engine.zig @@ -4,8 +4,8 @@ const Config = @import("./config.zig").Config; /// /// An engine is typically global in a program and contains all the /// configuration necessary for compiling wasm code. From an engine you'll -/// typically create a `Store`. Engines are created with `initDefault` or -/// `initWithConfig`. +/// typically create a `Store`. Engines are created with `init` or +/// `initDefault`. /// /// An engine is safe to share between threads. Multiple stores can be created /// within the same engine with each store living on a separate thread. @@ -14,15 +14,6 @@ const Config = @import("./config.zig").Config; /// Engines are reference counted internally so `deinit` can be called at any /// time after a `Store` has been created from one. pub const Engine = opaque { - /// Creates a new engine with the default configuration. - /// - /// The object returned is owned by the caller and will need to be deleted - /// with `deinit`. This may return `error.ModuleInit` if the engine could - /// not be allocated. - pub fn initDefault() !*Engine { - return wasm_engine_new() orelse error.ModuleInit; - } - /// Creates a new engine with the specified configuration. /// /// This function will take ownership of the configuration specified @@ -30,10 +21,19 @@ pub const Engine = opaque { /// `Config.deinit` on the argument. The object returned is owned by the /// caller and will need to be deleted with `deinit`. This may return /// `error.ModuleInit` if the engine could not be allocated. - pub fn initWithConfig(config: *Config) !*Engine { + pub fn init(config: *Config) !*Engine { return wasm_engine_new_with_config(config) orelse error.ModuleInit; } + /// Creates a new engine with the default configuration. + /// + /// The object returned is owned by the caller and will need to be deleted + /// with `deinit`. This may return `error.ModuleInit` if the engine could + /// not be allocated. + pub fn initDefault() !*Engine { + return wasm_engine_new() orelse error.ModuleInit; + } + pub fn deinit(self: *Engine) void { wasm_engine_delete(self); }