/** * \file wasmtime/config.hh */ #ifndef WASMTIME_CONFIG_HH #define WASMTIME_CONFIG_HH #include #include #include #include #include namespace wasmtime { /// \brief Strategies passed to `Config::strategy` enum class Strategy { /// Automatically selects the compilation strategy Auto = WASMTIME_STRATEGY_AUTO, /// Requires Cranelift to be used for compilation Cranelift = WASMTIME_STRATEGY_CRANELIFT, }; /// \brief Values passed to `Config::cranelift_opt_level` enum class OptLevel { /// No extra optimizations performed None = WASMTIME_OPT_LEVEL_NONE, /// Optimize for speed Speed = WASMTIME_OPT_LEVEL_SPEED, /// Optimize for speed and generated code size SpeedAndSize = WASMTIME_OPT_LEVEL_SPEED_AND_SIZE, }; /// \brief Values passed to `Config::profiler` enum class ProfilingStrategy { /// No profiling enabled None = WASMTIME_PROFILING_STRATEGY_NONE, /// Profiling hooks via perf's jitdump Jitdump = WASMTIME_PROFILING_STRATEGY_JITDUMP, /// Profiling hooks via VTune Vtune = WASMTIME_PROFILING_STRATEGY_VTUNE, /// Profiling hooks via perfmap Perfmap = WASMTIME_PROFILING_STRATEGY_PERFMAP, }; #ifdef WASMTIME_FEATURE_POOLING_ALLOCATOR /** * \brief Pool allocation configuration for Wasmtime. * * For more information be sure to consult the [rust * documentation](https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html). */ class PoolAllocationConfig { WASMTIME_OWN_WRAPPER(PoolAllocationConfig, wasmtime_pooling_allocation_config); PoolAllocationConfig() : ptr(wasmtime_pooling_allocation_config_new()) {} /// \brief Configures the maximum number of “unused warm slots” to retain in /// the pooling allocator. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_unused_warm_slots. void max_unused_warm_slots(uint32_t max) { wasmtime_pooling_allocation_config_max_unused_warm_slots_set(ptr.get(), max); } /// \brief The target number of decommits to do per batch. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.decommit_batch_size. void decommit_batch_size(size_t batch_size) { wasmtime_pooling_allocation_config_decommit_batch_size_set(ptr.get(), batch_size); } #ifdef WASMTIME_FEATURE_ASYNC /// \brief How much memory, in bytes, to keep resident for async stacks /// allocated with the pooling allocator. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.async_stack_keep_resident. void async_stack_keep_resident(size_t size) { wasmtime_pooling_allocation_config_async_stack_keep_resident_set(ptr.get(), size); } #endif // WASMTIME_FEATURE_ASYNC /// \brief How much memory, in bytes, to keep resident for each linear memory /// after deallocation. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.linear_memory_keep_resident. void linear_memory_keep_resident(size_t size) { wasmtime_pooling_allocation_config_linear_memory_keep_resident_set( ptr.get(), size); } /// \brief How much memory, in bytes, to keep resident for each table after /// deallocation. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.table_keep_resident. void table_keep_resident(size_t size) { wasmtime_pooling_allocation_config_table_keep_resident_set(ptr.get(), size); } /// \brief The maximum number of concurrent component instances supported /// (default is 1000). /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.total_component_instances. void total_component_instances(uint32_t count) { wasmtime_pooling_allocation_config_total_component_instances_set(ptr.get(), count); } /// \brief The maximum size, in bytes, allocated for a component instance’s /// VMComponentContext metadata. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_component_instance_size. void max_component_instance_size(size_t size) { wasmtime_pooling_allocation_config_max_component_instance_size_set( ptr.get(), size); } /// \brief The maximum number of core instances a single component may contain /// (default is unlimited). /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_core_instances_per_component. void max_core_instances_per_component(uint32_t count) { wasmtime_pooling_allocation_config_max_core_instances_per_component_set( ptr.get(), count); } /// \brief The maximum number of Wasm linear memories that a single component /// may transitively contain (default is unlimited). /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_memories_per_component. void max_memories_per_component(uint32_t count) { wasmtime_pooling_allocation_config_max_memories_per_component_set(ptr.get(), count); } /// \brief The maximum number of tables that a single component may /// transitively contain (default is unlimited). /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_tables_per_component. void max_tables_per_component(uint32_t count) { wasmtime_pooling_allocation_config_max_tables_per_component_set(ptr.get(), count); } /// \brief The maximum number of concurrent Wasm linear memories supported /// (default is 1000). /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.total_memories. void total_memories(uint32_t count) { wasmtime_pooling_allocation_config_total_memories_set(ptr.get(), count); } /// \brief The maximum number of concurrent tables supported (default is /// 1000). /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.total_tables. void total_tables(uint32_t count) { wasmtime_pooling_allocation_config_total_tables_set(ptr.get(), count); } #ifdef WASMTIME_FEATURE_ASYNC /// \brief The maximum number of execution stacks allowed for asynchronous /// execution, when enabled (default is 1000). /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.total_stacks. void total_stacks(uint32_t count) { wasmtime_pooling_allocation_config_total_stacks_set(ptr.get(), count); } #endif // WASMTIME_FEATURE_ASYNC /// \brief The maximum number of concurrent core instances supported (default /// is 1000). /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.total_core_instances. void total_core_instances(uint32_t count) { wasmtime_pooling_allocation_config_total_core_instances_set(ptr.get(), count); } /// \brief The maximum size, in bytes, allocated for a core instance’s /// VMContext metadata. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_core_instance_size. void max_core_instance_size(size_t size) { wasmtime_pooling_allocation_config_max_core_instance_size_set(ptr.get(), size); } /// \brief The maximum number of defined tables for a core module (default is /// 1). /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_tables_per_module. void max_tables_per_module(uint32_t tables) { wasmtime_pooling_allocation_config_max_tables_per_module_set(ptr.get(), tables); } /// \brief The maximum table elements for any table defined in a module /// (default is 20000). /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.table_elements. void table_elements(size_t elements) { wasmtime_pooling_allocation_config_table_elements_set(ptr.get(), elements); } /// \brief The maximum number of defined linear memories for a module (default /// is 1). /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_memories_per_module. void max_memories_per_module(uint32_t memories) { wasmtime_pooling_allocation_config_max_memories_per_module_set(ptr.get(), memories); } /// \brief The maximum byte size that any WebAssembly linear memory may grow /// to. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_memory_size. void max_memory_size(size_t bytes) { wasmtime_pooling_allocation_config_max_memory_size_set(ptr.get(), bytes); } /// \brief The maximum number of concurrent GC heaps supported (default is /// 1000). /// /// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.total_gc_heaps. void total_gc_heaps(uint32_t count) { wasmtime_pooling_allocation_config_total_gc_heaps_set(ptr.get(), count); } }; #endif // WASMTIME_FEATURE_POOLING_ALLOCATOR /** * \brief Configuration for Wasmtime. * * This class is used to configure Wasmtime's compilation and various other * settings such as enabled WebAssembly proposals. * * For more information be sure to consult the [rust * documentation](https://docs.wasmtime.dev/api/wasmtime/struct.Config.html). */ class Config { WASMTIME_OWN_WRAPPER(Config, wasm_config); /// \brief Creates configuration with all the default settings. Config() : ptr(wasm_config_new()) {} /// \brief Configures whether dwarf debuginfo is emitted for assisting /// in-process debugging. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.debug_info void debug_info(bool enable) { wasmtime_config_debug_info_set(ptr.get(), enable); } /// \brief Configures whether epochs are enabled which can be used to /// interrupt currently executing WebAssembly. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.epoch_interruption void epoch_interruption(bool enable) { wasmtime_config_epoch_interruption_set(ptr.get(), enable); } /// \brief Configures whether WebAssembly code will consume fuel and trap when /// it runs out. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.consume_fuel void consume_fuel(bool enable) { wasmtime_config_consume_fuel_set(ptr.get(), enable); } /// \brief Configures the maximum amount of native stack wasm can consume. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.max_wasm_stack void max_wasm_stack(size_t stack) { wasmtime_config_max_wasm_stack_set(ptr.get(), stack); } #ifdef WASMTIME_FEATURE_THREADS /// \brief Configures whether the WebAssembly threads proposal is enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_threads void wasm_threads(bool enable) { wasmtime_config_wasm_threads_set(ptr.get(), enable); } #endif // WASMTIME_FEATURE_THREADS /// \brief Configures whether wasm shared memories can be created. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.shared_memory void shared_memory(bool enable) { wasmtime_config_shared_memory_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly tail call proposal is enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_tail_call void wasm_tail_call(bool enable) { wasmtime_config_wasm_tail_call_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly reference types proposal is /// enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_reference_types void wasm_reference_types(bool enable) { wasmtime_config_wasm_reference_types_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly simd proposal is enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_simd void wasm_simd(bool enable) { wasmtime_config_wasm_simd_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly relaxed simd proposal is enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_relaxed_simd void wasm_relaxed_simd(bool enable) { wasmtime_config_wasm_relaxed_simd_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly relaxed simd proposal supports /// its deterministic behavior. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_relaxed_simd_deterministic void wasm_relaxed_simd_deterministic(bool enable) { wasmtime_config_wasm_relaxed_simd_deterministic_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly bulk memory proposal is enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_bulk_memory void wasm_bulk_memory(bool enable) { wasmtime_config_wasm_bulk_memory_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly multi value proposal is enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_multi_value void wasm_multi_value(bool enable) { wasmtime_config_wasm_multi_value_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly multi memory proposal is enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_multi_memory void wasm_multi_memory(bool enable) { wasmtime_config_wasm_multi_memory_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly memory64 proposal is enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_memory64 void wasm_memory64(bool enable) { wasmtime_config_wasm_memory64_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly Garbage Collection proposal will /// be enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_gc void wasm_gc(bool enable) { wasmtime_config_wasm_gc_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly function references proposal /// will be enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_function_references void wasm_function_references(bool enable) { wasmtime_config_wasm_function_references_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly wide arithmetic proposal will be /// enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_wide_arithmetic void wasm_wide_arithmetic(bool enable) { wasmtime_config_wasm_wide_arithmetic_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly exceptions proposal will be /// enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_exceptions void wasm_exceptions(bool enable) { wasmtime_config_wasm_exceptions_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly custom-page-sizes proposal will /// be enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_custom_page_sizes void wasm_custom_page_sizes(bool enable) { wasmtime_config_wasm_custom_page_sizes_set(ptr.get(), enable); } #ifdef WASMTIME_FEATURE_COMPONENT_MODEL /// \brief Configures whether the WebAssembly component model proposal will be /// enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_component_model void wasm_component_model(bool enable) { wasmtime_config_wasm_component_model_set(ptr.get(), enable); } /// \brief Configures whether the WebAssembly component model map type will be /// enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_component_model_map void wasm_component_model_map(bool enable) { wasmtime_config_wasm_component_model_map_set(ptr.get(), enable); } #endif // WASMTIME_FEATURE_COMPONENT_MODEL #ifdef WASMTIME_FEATURE_PARALLEL_COMPILATION /// \brief Configure whether wasmtime should compile a module using multiple /// threads. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.parallel_compilation void parallel_compilation(bool enable) { wasmtime_config_parallel_compilation_set(ptr.get(), enable); } #endif // WASMTIME_FEATURE_PARALLEL_COMPILATION #ifdef WASMTIME_FEATURE_COMPILER /// \brief Configures compilation strategy for wasm code. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.strategy void strategy(Strategy strategy) { wasmtime_config_strategy_set(ptr.get(), static_cast(strategy)); } /// \brief Configures whether cranelift's debug verifier is enabled /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.cranelift_debug_verifier void cranelift_debug_verifier(bool enable) { wasmtime_config_cranelift_debug_verifier_set(ptr.get(), enable); } /// \brief Configures whether cranelift's nan canonicalization /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.cranelift_nan_canonicalization void cranelift_nan_canonicalization(bool enable) { wasmtime_config_cranelift_nan_canonicalization_set(ptr.get(), enable); } /// \brief Configures cranelift's optimization level /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.cranelift_opt_level void cranelift_opt_level(OptLevel level) { wasmtime_config_cranelift_opt_level_set( ptr.get(), static_cast(level)); } /// \brief Enable the specified Cranelift flag /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.cranelift_flag_enable void cranelift_flag_enable(const std::string &flag) { wasmtime_config_cranelift_flag_enable(ptr.get(), flag.c_str()); } /// \brief Configure the specified Cranelift flag /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.cranelift_flag_set void cranelift_flag_set(const std::string &flag, const std::string &value) { wasmtime_config_cranelift_flag_set(ptr.get(), flag.c_str(), value.c_str()); } #endif // WASMTIME_FEATURE_COMPILER /// \brief Configures an active wasm profiler /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.profiler void profiler(ProfilingStrategy profiler) { wasmtime_config_profiler_set( ptr.get(), static_cast(profiler)); } /// \brief Configures the size of the initial linear memory allocation. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.memory_reservation void memory_reservation(size_t size) { wasmtime_config_memory_reservation_set(ptr.get(), size); } /// \brief Configures the size of the bytes to reserve beyond the end of /// linear memory to grow into. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.memory_reservation_for_growth void memory_reservation_for_growth(size_t size) { wasmtime_config_memory_reservation_for_growth_set(ptr.get(), size); } /// \brief Configures the size of memory's guard region /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.memory_guard_size void memory_guard_size(size_t size) { wasmtime_config_memory_guard_size_set(ptr.get(), size); } /// \brief Configures whether the base pointer of linear memory is allowed to /// move. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.memory_may_move void memory_may_move(bool enable) { wasmtime_config_memory_may_move_set(ptr.get(), enable); } /// \brief Configures whether CoW is enabled. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.memory_init_cow void memory_init_cow(bool enable) { wasmtime_config_memory_init_cow_set(ptr.get(), enable); } /// \brief Configures whether native unwind information is emitted. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.native_unwind_info void native_unwind_info(bool enable) { wasmtime_config_native_unwind_info_set(ptr.get(), enable); } /// \brief Configures whether mach ports are used on macOS /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.macos_use_mach_ports void macos_use_mach_ports(bool enable) { wasmtime_config_macos_use_mach_ports_set(ptr.get(), enable); } /// \brief Configures Wasmtime to not use signals-based trap handlers /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.signals_based_traps void signals_based_traps(bool enable) { wasmtime_config_signals_based_traps_set(ptr.get(), enable); } #ifdef WASMTIME_FEATURE_CACHE /// \brief Loads the default cache configuration present on the system. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.cache_config_load_default Result cache_load_default() { auto *error = wasmtime_config_cache_config_load(ptr.get(), nullptr); if (error != nullptr) { return Error(error); } return std::monostate(); } /// \brief Loads cache configuration from the specified filename. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.cache_config_load Result cache_load(const std::string &path) { auto *error = wasmtime_config_cache_config_load(ptr.get(), path.c_str()); if (error != nullptr) { return Error(error); } return std::monostate(); } #endif // WASMTIME_FEATURE_CACHE private: template static void raw_finalize(void *env) { std::unique_ptr ptr(reinterpret_cast(env)); } template static uint8_t *raw_get_memory(void *env, size_t *byte_size, size_t *byte_capacity) { M *memory = reinterpret_cast(env); return memory->get_memory(byte_size, byte_capacity); } template static wasmtime_error_t *raw_grow_memory(void *env, size_t new_size) { M *memory = reinterpret_cast(env); Result result = memory->grow_memory(new_size); if (!result) return result.err().capi_release(); return nullptr; } template static wasmtime_error_t * raw_new_memory(void *env, const wasm_memorytype_t *ty, size_t minimum, size_t maximum, size_t reserved_size_in_bytes, size_t guard_size_in_bytes, wasmtime_linear_memory_t *memory_ret) { using Memory = typename T::Memory; T *creator = reinterpret_cast(env); Result result = creator->new_memory(MemoryType::Ref(ty), minimum, maximum, reserved_size_in_bytes, guard_size_in_bytes); if (!result) { return result.err().capi_release(); } Memory memory = result.unwrap(); memory_ret->env = std::make_unique(memory).release(); memory_ret->finalizer = raw_finalize; memory_ret->get_memory = raw_get_memory; memory_ret->grow_memory = raw_grow_memory; return nullptr; } public: /// \brief Configures a custom memory creator for this configuration and /// eventual Engine. /// /// This can be used to use `creator` to allocate linear memories for the /// engine that this configuration will be used for. template void host_memory_creator(T creator) { wasmtime_memory_creator_t config = {0}; config.env = std::make_unique(creator).release(); config.finalizer = raw_finalize; config.new_memory = raw_new_memory; wasmtime_config_host_memory_creator_set(ptr.get(), &config); } #ifdef WASMTIME_FEATURE_POOLING_ALLOCATOR /// \brief Enables and configures the pooling allocation strategy. /// /// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.allocation_strategy void pooling_allocation_strategy(const PoolAllocationConfig &config) { wasmtime_pooling_allocation_strategy_set(ptr.get(), config.capi()); } #endif // WASMTIME_FEATURE_POOLING_ALLOCATOR /** * \brief Specifies whether support for concurrent execution of WebAssembly is * supported within this store. * * For more information see the Rust documentation at * https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.concurrency_support. */ void concurrency_support(bool enable) { wasmtime_config_concurrency_support_set(ptr.get(), enable); } }; } // namespace wasmtime #endif // WASMTIME_CONFIG_HH