Skip to main content

wasmedge_sdk/
config.rs

1//! Defines the structs used to construct configurations.
2
3use std::sync::Arc;
4
5use crate::WasmEdgeResult;
6#[cfg(feature = "aot")]
7use crate::{CompilerOptimizationLevel, CompilerOutputFormat};
8use wasmedge_sys as sys;
9use wasmedge_types::{RunMode, WasmStandard};
10
11/// Defines a builder for creating a [Config].
12#[derive(Debug, Default)]
13pub struct ConfigBuilder {
14    common_config: CommonConfigOptions,
15    stat_config: Option<StatisticsConfigOptions>,
16    #[cfg(feature = "aot")]
17    compiler_config: Option<CompilerConfigOptions>,
18    runtime_config: Option<RuntimeConfigOptions>,
19}
20impl ConfigBuilder {
21    /// Creates a new [ConfigBuilder] with the given [CommonConfigOptions] setting.
22    pub fn new(options: CommonConfigOptions) -> Self {
23        Self {
24            common_config: options,
25            stat_config: None,
26            #[cfg(feature = "aot")]
27            compiler_config: None,
28            runtime_config: None,
29        }
30    }
31
32    /// Sets the [StatisticsConfigOptions] for the [ConfigBuilder].
33    ///
34    /// # Argument
35    ///
36    /// - `options` specifies the [StatisticsConfigOptions] settings to set.
37    pub fn with_statistics_config(self, options: StatisticsConfigOptions) -> Self {
38        Self {
39            stat_config: Some(options),
40            ..self
41        }
42    }
43
44    /// Sets the [RuntimeConfigOptions] for the [ConfigBuilder].
45    ///
46    /// # Argument
47    ///
48    /// - `options` specifies the [RuntimeConfigOptions] settings to set.
49    pub fn with_runtime_config(self, options: RuntimeConfigOptions) -> Self {
50        Self {
51            runtime_config: Some(options),
52            ..self
53        }
54    }
55
56    /// Sets the [CompilerConfigOptions] for the [ConfigBuilder].
57    ///
58    /// # Argument
59    ///
60    /// - `options` specifies the [CompilerConfigOptions] settings to set.
61    #[cfg(feature = "aot")]
62    #[cfg_attr(docsrs, doc(cfg(feature = "aot")))]
63    pub fn with_compiler_config(self, options: CompilerConfigOptions) -> Self {
64        Self {
65            compiler_config: Some(options),
66            ..self
67        }
68    }
69
70    /// Creates a new [Config] from the [ConfigBuilder].
71    ///
72    /// # Errors
73    ///
74    /// If fail to create a [Config], then an error is returned.
75    pub fn build(self) -> WasmEdgeResult<Config> {
76        let mut inner = sys::Config::create()?;
77        inner.mutable_globals(self.common_config.mutable_globals);
78        inner.non_trap_conversions(self.common_config.non_trap_conversions);
79        inner.sign_extension_operators(self.common_config.sign_extension_operators);
80        inner.multi_value(self.common_config.multi_value);
81        inner.bulk_memory_operations(self.common_config.bulk_memory_operations);
82        inner.simd(self.common_config.simd);
83        inner.relax_simd(self.common_config.relax_simd);
84        inner.multi_memories(self.common_config.multi_memories);
85        inner.threads(self.common_config.threads);
86        inner.tail_call(self.common_config.tail_call);
87        inner.extended_const(self.common_config.extended_const);
88        inner.annotations(self.common_config.annotations);
89        inner.memory64(self.common_config.memory64);
90        inner.exception_handling(self.common_config.exception_handling);
91        inner.component_model(self.common_config.component_model);
92        // The GC proposal depends on FunctionReferences, and both depend on ReferenceTypes.
93        // Apply the dependents first, so that disabling a dependency is not silently ignored
94        // by the runtime while a dependent is still enabled.
95        inner.gc(self.common_config.gc);
96        inner.function_references(self.common_config.function_references);
97        inner.reference_types(self.common_config.reference_types);
98        inner.set_run_mode(self.common_config.run_mode);
99
100        if let Some(stat_config) = self.stat_config {
101            inner.count_instructions(stat_config.count_instructions);
102            inner.measure_cost(stat_config.measure_cost);
103            inner.measure_time(stat_config.measure_time);
104        }
105        #[cfg(feature = "aot")]
106        if let Some(compiler_config) = self.compiler_config {
107            inner.set_aot_compiler_output_format(compiler_config.out_format);
108            inner.set_aot_optimization_level(compiler_config.opt_level);
109            inner.dump_ir(compiler_config.dump_ir);
110            inner.generic_binary(compiler_config.generic_binary);
111            inner.interruptible(compiler_config.interruptible);
112        }
113        if let Some(runtim_config) = self.runtime_config {
114            inner.set_max_memory_pages(runtim_config.max_memory_pages);
115            inner.allow_afunix(runtim_config.allow_afunix);
116        }
117
118        Ok(Config {
119            inner: Arc::new(inner),
120        })
121    }
122}
123
124/// Defines [Config] struct used to check/set the configuration options.
125///
126/// # Example
127///
128/// The following code shows how to create a [Config] with [ConfigBuilder].
129///
130/// ```rust
131///
132/// use wasmedge_sdk::{config::{Config, ConfigBuilder, CommonConfigOptions, StatisticsConfigOptions, RuntimeConfigOptions}};
133/// use wasmedge_types::{CompilerOutputFormat, CompilerOptimizationLevel};
134///
135/// let common_options = CommonConfigOptions::default()
136///     .bulk_memory_operations(true)
137///     .multi_value(true)
138///     .mutable_globals(true)
139///     .non_trap_conversions(true)
140///     .reference_types(true)
141///     .sign_extension_operators(true)
142///     .simd(true);
143///
144/// let stat_options = StatisticsConfigOptions::default()
145///     .count_instructions(true)
146///     .measure_cost(true)
147///     .measure_time(true);
148///
149/// let runtime_options = RuntimeConfigOptions::default().max_memory_pages(1024);
150///
151///
152/// let result = ConfigBuilder::new(common_options)
153///     .with_statistics_config(stat_options)
154///     .with_runtime_config(runtime_options)
155///     .build();
156/// assert!(result.is_ok());
157/// let config = result.unwrap();
158/// ```
159#[derive(Debug, Clone)]
160pub struct Config {
161    pub(crate) inner: Arc<sys::Config>,
162}
163impl Config {
164    /// Returns the number of the memory pages available.
165    pub fn max_memory_pages(&self) -> u32 {
166        self.inner.get_max_memory_pages()
167    }
168
169    /// Checks if the ImportExportMutGlobals option turns on or not.
170    pub fn mutable_globals_enabled(&self) -> bool {
171        self.inner.mutable_globals_enabled()
172    }
173
174    /// Checks if the NonTrapFloatToIntConversions option turns on or not.
175    pub fn non_trap_conversions_enabled(&self) -> bool {
176        self.inner.non_trap_conversions_enabled()
177    }
178
179    /// Checks if the SignExtensionOperators option turns on or not.
180    pub fn sign_extension_operators_enabled(&self) -> bool {
181        self.inner.sign_extension_operators_enabled()
182    }
183
184    /// Checks if the MultiValue option turns on or not.
185    pub fn multi_value_enabled(&self) -> bool {
186        self.inner.multi_value_enabled()
187    }
188
189    /// Checks if the BulkMemoryOperations option turns on or not.
190    pub fn bulk_memory_operations_enabled(&self) -> bool {
191        self.inner.bulk_memory_operations_enabled()
192    }
193
194    /// Checks if the ReferenceTypes option turns on or not.
195    pub fn reference_types_enabled(&self) -> bool {
196        self.inner.reference_types_enabled()
197    }
198
199    /// Checks if the SIMD option turns on or not.
200    pub fn simd_enabled(&self) -> bool {
201        self.inner.simd_enabled()
202    }
203
204    /// Checks if the RelaxSIMD option turns on or not.
205    pub fn relax_simd_enabled(&self) -> bool {
206        self.inner.relax_simd_enabled()
207    }
208
209    /// Checks if the MultiMemories option turns on or not.
210    pub fn multi_memories_enabled(&self) -> bool {
211        self.inner.multi_memories_enabled()
212    }
213
214    /// Checks if the Threads option turns on or not.
215    pub fn threads_enabled(&self) -> bool {
216        self.inner.threads_enabled()
217    }
218
219    /// Checks if the TailCall option turns on or not.
220    pub fn tail_call_enabled(&self) -> bool {
221        self.inner.tail_call_enabled()
222    }
223
224    /// Checks if the ExtendedConst option turns on or not.
225    pub fn extended_const_enabled(&self) -> bool {
226        self.inner.extended_const_enabled()
227    }
228
229    /// Checks if the Annotations option turns on or not.
230    pub fn annotations_enabled(&self) -> bool {
231        self.inner.annotations_enabled()
232    }
233
234    /// Checks if the Memory64 option turns on or not.
235    pub fn memory64_enabled(&self) -> bool {
236        self.inner.memory64_enabled()
237    }
238
239    /// Checks if the ExceptionHandling option turns on or not.
240    pub fn exception_handling_enabled(&self) -> bool {
241        self.inner.exception_handling_enabled()
242    }
243
244    /// Checks if the GC option turns on or not.
245    pub fn gc_enabled(&self) -> bool {
246        self.inner.gc_enabled()
247    }
248
249    /// Checks if the FunctionReferences option turns on or not.
250    pub fn function_references_enabled(&self) -> bool {
251        self.inner.function_references_enabled()
252    }
253
254    /// Checks if the Component option turns on or not.
255    pub fn component_model_enabled(&self) -> bool {
256        self.inner.component_model_enabled()
257    }
258
259    /// Checks if the `AF_UNIX` sockets option turns on or not.
260    pub fn allow_afunix_enabled(&self) -> bool {
261        self.inner.allow_afunix_enabled()
262    }
263
264    /// Checks if the `ForceInterpreter` option turns on or not.
265    #[deprecated(note = "use `run_mode` instead")]
266    pub fn interpreter_mode_enabled(&self) -> bool {
267        #[allow(deprecated)]
268        self.inner.interpreter_mode_enabled()
269    }
270
271    /// Returns the execution mode.
272    pub fn run_mode(&self) -> RunMode {
273        self.inner.get_run_mode()
274    }
275
276    /// Returns the optimization level of AOT compiler.
277    #[cfg(feature = "aot")]
278    #[cfg_attr(docsrs, doc(cfg(feature = "aot")))]
279    pub fn optimization_level(&self) -> CompilerOptimizationLevel {
280        self.inner.get_aot_optimization_level()
281    }
282
283    /// Returns the output binary format of AOT compiler.
284    #[cfg(feature = "aot")]
285    #[cfg_attr(docsrs, doc(cfg(feature = "aot")))]
286    pub fn out_format(&self) -> CompilerOutputFormat {
287        self.inner.get_aot_compiler_output_format()
288    }
289
290    /// Checks if the dump IR option turns on or not.
291    #[cfg(feature = "aot")]
292    #[cfg_attr(docsrs, doc(cfg(feature = "aot")))]
293    pub fn dump_ir_enabled(&self) -> bool {
294        self.inner.dump_ir_enabled()
295    }
296
297    /// Checks if the generic binary option of AOT compiler turns on or not.
298    #[cfg(feature = "aot")]
299    #[cfg_attr(docsrs, doc(cfg(feature = "aot")))]
300    pub fn generic_binary_enabled(&self) -> bool {
301        self.inner.generic_binary_enabled()
302    }
303
304    /// Checks if the `Interruptible` option of AOT Compiler turns on or not.
305    #[cfg(feature = "aot")]
306    #[cfg_attr(docsrs, doc(cfg(feature = "aot")))]
307    pub fn interruptible_enabled(&self) -> bool {
308        self.inner.interruptible_enabled()
309    }
310
311    /// Checks if the instruction counting option turns on or not.
312    pub fn instruction_counting_enabled(&self) -> bool {
313        self.inner.is_instruction_counting()
314    }
315
316    /// Checks if the cost measuring option turns on or not.
317    pub fn cost_measuring_enabled(&self) -> bool {
318        self.inner.is_cost_measuring()
319    }
320
321    /// Checks if the cost measuring option turns on or not.
322    pub fn time_measuring_enabled(&self) -> bool {
323        self.inner.is_time_measuring()
324    }
325}
326
327/// Defines the common configuration options.
328///
329/// [CommonConfigOptions] is used to set the common configuration options, which are
330///     
331///  - `ImportExportMutGlobals` supports mutable imported and exported globals.
332///
333///    Also see [Import/Export Mutable Globals Proposal](https://github.com/WebAssembly/mutable-global/blob/master/proposals/mutable-global/Overview.md#importexport-mutable-globals).
334///
335///  - `NonTrapFloatToIntConversions` supports the non-trapping float-to-int conversion.
336///
337///    Also see [Non-trapping Float-to-int Conversions Proposal](https://github.com/WebAssembly/spec/blob/main/proposals/nontrapping-float-to-int-conversion/Overview.md).
338///
339///  - `SignExtensionOperators` supports new integer instructions for sign-extending 8-bit, 16-bit, and 32-bit values.
340///     
341///    Also see [Sign-extension Operators Proposal](https://github.com/WebAssembly/spec/blob/main/proposals/sign-extension-ops/Overview.md).
342///
343///  - `MultiValue` supports functions and instructions with multiple return values, and blocks with inputs.
344///     
345///    Also see [Multi-value Extension](https://github.com/WebAssembly/spec/blob/main/proposals/multi-value/Overview.md).
346///
347///  - `BulkMemoryOperations` supports bulk memory operations.
348///
349///    Also see [Bulk Memory Operations Proposal](https://github.com/WebAssembly/spec/blob/main/proposals/bulk-memory-operations/Overview.md#motivation-for-bulk-memory-operations).
350///
351///  - `ReferenceTypes` supports reference types.
352///
353///    Also see [Reference Types Proposal](https://github.com/WebAssembly/spec/blob/main/proposals/reference-types/Overview.md).
354///
355///  - `SIMD` supports 128-bit packed SIMD extension to WebAssembly.
356///
357///    Also see [SIMD Proposal](https://github.com/WebAssembly/spec/blob/main/proposals/simd/SIMD.md).
358///
359///  - `RelaxSIMD` supports the relaxed SIMD instructions.
360///
361///    Also see [Relaxed SIMD Proposal](https://github.com/WebAssembly/relaxed-simd/blob/main/proposals/relaxed-simd/Overview.md).
362///
363///  - `MultiMemories` enables the use of multiple memories within a single Wasm module.
364///
365///    Also see [Multiple Memories Proposal](https://github.com/WebAssembly/multi-memory/blob/main/proposals/multi-memory/Overview.md).
366///
367///  - `Threads` supports the threading feature.
368///
369///    Also see [Threading Proposal](https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md).
370///
371///  - `TailCall` supports tail call optimization.
372///
373///    Also see [Tail Call Proposal](https://github.com/WebAssembly/tail-call/blob/master/proposals/tail-call/Overview.md).
374///
375///  - `ExtendedConst` supports extended constant expressions.
376///
377///    Also see [Extended Const Expressions Proposal](https://github.com/WebAssembly/extended-const/blob/main/proposals/extended-const/Overview.md).
378///
379///  - `Annotations` supports annotations in the WASM text format.
380///
381///    Also see [Annotations Proposal](https://github.com/WebAssembly/annotations/blob/master/proposals/annotations/Overview.md).
382///
383///  - `Memory64` supports 64-bit memory indexes.
384///
385///    Also see [Memory64 Proposal](https://github.com/WebAssembly/memory64/blob/main/proposals/memory64/Overview.md).
386///
387///  - `ExceptionHandling` supports exception handling.
388///
389///    Also see [Exception Handling Proposal](https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md).
390///
391///  - `FunctionReferences` supports typed function references for WebAssembly.
392///
393///    Also see [Function References Proposal](https://github.com/WebAssembly/function-references/blob/master/proposals/function-references/Overview.md).
394///
395///  - `GC` supports garbage collection.
396///
397///    Also see [GC Proposal](https://github.com/WebAssembly/gc/blob/main/proposals/gc/Overview.md).
398///
399///  - `Component` supports the WebAssembly component model. The support is experimental.
400///
401///    Also see [Component Model Proposal](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md).
402#[derive(Debug, Clone, Copy)]
403pub struct CommonConfigOptions {
404    mutable_globals: bool,
405    non_trap_conversions: bool,
406    sign_extension_operators: bool,
407    multi_value: bool,
408    bulk_memory_operations: bool,
409    reference_types: bool,
410    simd: bool,
411    relax_simd: bool,
412    multi_memories: bool,
413    threads: bool,
414    gc: bool,
415    tail_call: bool,
416    extended_const: bool,
417    annotations: bool,
418    memory64: bool,
419    exception_handling: bool,
420    function_references: bool,
421    component_model: bool,
422    run_mode: RunMode,
423}
424impl CommonConfigOptions {
425    /// Creates a new instance of [CommonConfigOptions].
426    ///
427    /// The default options match the default proposal set of WasmEdge 0.17.1, which enables all
428    /// the proposals of the WebAssembly 3.0 standard:
429    /// * mutable_globals: true,
430    /// * non_trap_conversions: true,
431    /// * sign_extension_operators: true,
432    /// * multi_value: true,
433    /// * bulk_memory_operations: true,
434    /// * reference_types: true,
435    /// * simd: true,
436    /// * relax_simd: true,
437    /// * multi_memories: true,
438    /// * threads: false,
439    /// * gc: true,
440    /// * tail_call: true,
441    /// * extended_const: true,
442    /// * annotations: false,
443    /// * memory64: true,
444    /// * exception_handling: true,
445    /// * function_references: true,
446    /// * component_model: false,
447    /// * run_mode: RunMode::Interpreter,
448    pub fn new() -> Self {
449        Self {
450            mutable_globals: true,
451            non_trap_conversions: true,
452            sign_extension_operators: true,
453            multi_value: true,
454            bulk_memory_operations: true,
455            reference_types: true,
456            simd: true,
457            relax_simd: true,
458            multi_memories: true,
459            threads: false,
460            gc: true,
461            tail_call: true,
462            extended_const: true,
463            annotations: false,
464            memory64: true,
465            exception_handling: true,
466            function_references: true,
467            component_model: false,
468            run_mode: RunMode::Interpreter,
469        }
470    }
471
472    /// Creates a new instance of [CommonConfigOptions] with the proposal preset of the given
473    /// WebAssembly standard.
474    ///
475    /// The proposals that do not belong to the given standard, such as `Annotations`, `Threads`,
476    /// and `Component`, are disabled.
477    ///
478    /// # Argument
479    ///
480    /// - `standard` specifies the WebAssembly standard whose proposal preset is applied.
481    pub fn from_wasm_standard(standard: WasmStandard) -> Self {
482        let wasm1 = Self {
483            mutable_globals: true,
484            non_trap_conversions: false,
485            sign_extension_operators: false,
486            multi_value: false,
487            bulk_memory_operations: false,
488            reference_types: false,
489            simd: false,
490            relax_simd: false,
491            multi_memories: false,
492            threads: false,
493            gc: false,
494            tail_call: false,
495            extended_const: false,
496            annotations: false,
497            memory64: false,
498            exception_handling: false,
499            function_references: false,
500            component_model: false,
501            run_mode: RunMode::Interpreter,
502        };
503        match standard {
504            WasmStandard::Wasm1 => wasm1,
505            WasmStandard::Wasm2 => Self {
506                non_trap_conversions: true,
507                sign_extension_operators: true,
508                multi_value: true,
509                bulk_memory_operations: true,
510                reference_types: true,
511                simd: true,
512                ..wasm1
513            },
514            WasmStandard::Wasm3 => Self {
515                non_trap_conversions: true,
516                sign_extension_operators: true,
517                multi_value: true,
518                bulk_memory_operations: true,
519                reference_types: true,
520                simd: true,
521                relax_simd: true,
522                tail_call: true,
523                extended_const: true,
524                function_references: true,
525                gc: true,
526                multi_memories: true,
527                exception_handling: true,
528                memory64: true,
529                ..wasm1
530            },
531        }
532    }
533
534    /// Enables or disables the ImportExportMutGlobals option.
535    ///
536    /// # Argument
537    ///
538    /// - `enable` specifies if the option turns on or not.
539    pub fn mutable_globals(self, enable: bool) -> Self {
540        Self {
541            mutable_globals: enable,
542            ..self
543        }
544    }
545
546    /// Enables or disables the NonTrapFloatToIntConversions option.
547    ///
548    /// # Argument
549    ///
550    /// - `enable` specifies if the option turns on or not.
551    pub fn non_trap_conversions(self, enable: bool) -> Self {
552        Self {
553            non_trap_conversions: enable,
554            ..self
555        }
556    }
557
558    /// Enables or disables the SignExtensionOperators option.
559    ///
560    /// # Argument
561    ///
562    /// - `enable` specifies if the option turns on or not.
563    pub fn sign_extension_operators(self, enable: bool) -> Self {
564        Self {
565            sign_extension_operators: enable,
566            ..self
567        }
568    }
569
570    /// Enables or disables the MultiValue option.
571    ///
572    /// # Argument
573    ///
574    /// - `enable` specifies if the option turns on or not.
575    pub fn multi_value(self, enable: bool) -> Self {
576        Self {
577            multi_value: enable,
578            ..self
579        }
580    }
581
582    /// Enables or disables the BulkMemoryOperations option.
583    ///
584    /// # Argument
585    ///
586    /// - `enable` specifies if the option turns on or not.
587    pub fn bulk_memory_operations(self, enable: bool) -> Self {
588        Self {
589            bulk_memory_operations: enable,
590            ..self
591        }
592    }
593
594    /// Enables or disables the ReferenceTypes option.
595    ///
596    /// # Argument
597    ///
598    /// - `enable` specifies if the option turns on or not.
599    pub fn reference_types(self, enable: bool) -> Self {
600        Self {
601            reference_types: enable,
602            ..self
603        }
604    }
605
606    /// Enables or disables the SIMD option.
607    ///
608    /// # Argument
609    ///
610    /// - `enable` specifies if the option turns on or not.
611    pub fn simd(self, enable: bool) -> Self {
612        Self {
613            simd: enable,
614            ..self
615        }
616    }
617
618    /// Enables or disables the RelaxSIMD option.
619    ///
620    /// # Argument
621    ///
622    /// - `enable` specifies if the option turns on or not.
623    pub fn relax_simd(self, enable: bool) -> Self {
624        Self {
625            relax_simd: enable,
626            ..self
627        }
628    }
629
630    /// Enables or disables the MultiMemories option.
631    ///
632    /// # Argument
633    ///
634    /// - `enable` specifies if the option turns on or not.
635    pub fn multi_memories(self, enable: bool) -> Self {
636        Self {
637            multi_memories: enable,
638            ..self
639        }
640    }
641
642    /// Enables or disables the Threads option.
643    ///
644    /// # Argument
645    ///
646    /// - `enable` specifies if the option turns on or not.
647    pub fn threads(self, enable: bool) -> Self {
648        Self {
649            threads: enable,
650            ..self
651        }
652    }
653
654    /// Enables or disables the GC option.
655    ///
656    /// The GC proposal depends on the FunctionReferences and ReferenceTypes proposals: while GC
657    /// is enabled, the runtime keeps both dependencies enabled and ignores disabling them.
658    ///
659    /// # Argument
660    ///
661    /// - `enable` specifies if the option turns on or not.
662    pub fn gc(self, enable: bool) -> Self {
663        Self { gc: enable, ..self }
664    }
665
666    /// Enables or disables the TailCall option.
667    ///
668    /// # Argument
669    ///
670    /// - `enable` specifies if the option turns on or not.
671    pub fn tail_call(self, enable: bool) -> Self {
672        Self {
673            tail_call: enable,
674            ..self
675        }
676    }
677
678    /// Enables or disables the ExtendedConst option.
679    ///
680    /// # Argument
681    ///
682    /// - `enable` specifies if the option turns on or not.
683    pub fn extended_const(self, enable: bool) -> Self {
684        Self {
685            extended_const: enable,
686            ..self
687        }
688    }
689
690    /// Enables or disables the Annotations option.
691    ///
692    /// # Argument
693    ///
694    /// - `enable` specifies if the option turns on or not.
695    pub fn annotations(self, enable: bool) -> Self {
696        Self {
697            annotations: enable,
698            ..self
699        }
700    }
701
702    /// Enables or disables the Memory64 option.
703    ///
704    /// # Argument
705    ///
706    /// - `enable` specifies if the option turns on or not.
707    pub fn memory64(self, enable: bool) -> Self {
708        Self {
709            memory64: enable,
710            ..self
711        }
712    }
713
714    /// Enables or disables the ExceptionHandling option.
715    ///
716    /// # Argument
717    ///
718    /// - `enable` specifies if the option turns on or not.
719    pub fn exception_handling(self, enable: bool) -> Self {
720        Self {
721            exception_handling: enable,
722            ..self
723        }
724    }
725
726    /// Enables or disables the FunctionReferences option.
727    ///
728    /// The FunctionReferences proposal depends on the ReferenceTypes proposal: while
729    /// FunctionReferences is enabled, the runtime keeps ReferenceTypes enabled and ignores
730    /// disabling it. Disabling FunctionReferences is ignored while the GC proposal stays enabled.
731    ///
732    /// # Argument
733    ///
734    /// * `enable` - Whether the option turns on or not.
735    pub fn function_references(self, enable: bool) -> Self {
736        Self {
737            function_references: enable,
738            ..self
739        }
740    }
741
742    /// Enables or disables the Component option.
743    ///
744    /// Notice that the WebAssembly component model support in WasmEdge is experimental.
745    ///
746    /// # Argument
747    ///
748    /// - `enable` specifies if the option turns on or not.
749    pub fn component_model(self, enable: bool) -> Self {
750        Self {
751            component_model: enable,
752            ..self
753        }
754    }
755
756    /// Enables or disables the `ForceInterpreter` option.
757    ///
758    /// # Argument
759    ///
760    /// * `enable` - Whether the option turns on or not.
761    #[deprecated(
762        note = "use `run_mode` instead; since WasmEdge 0.17.0, passing `false` is a no-op"
763    )]
764    pub fn interpreter_mode(self, enable: bool) -> Self {
765        // Keep the historical "don't force" semantic: only `true` selects the
766        // interpreter; `false` leaves the current mode untouched.
767        if enable {
768            self.run_mode(RunMode::Interpreter)
769        } else {
770            self
771        }
772    }
773
774    /// Sets the execution mode: interpreter, JIT, or AOT. By default, the mode is
775    /// [RunMode::Interpreter].
776    ///
777    /// Since WasmEdge 0.17.0, only [RunMode::Aot] loads the AOT custom sections from a universal
778    /// WASM file or `dlopen`s a shared-library WASM artifact; in the other modes, the AOT data is
779    /// ignored and the WASM runs in the selected engine.
780    ///
781    /// # Argument
782    ///
783    /// * `mode` - The execution mode to set.
784    pub fn run_mode(self, mode: RunMode) -> Self {
785        Self {
786            run_mode: mode,
787            ..self
788        }
789    }
790}
791impl Default for CommonConfigOptions {
792    /// Creates a new default instance of [CommonConfigOptions].
793    ///
794    /// The default options match the default proposal set of WasmEdge 0.17.1, which enables all
795    /// the proposals of the WebAssembly 3.0 standard:
796    /// * mutable_globals: true,
797    /// * non_trap_conversions: true,
798    /// * sign_extension_operators: true,
799    /// * multi_value: true,
800    /// * bulk_memory_operations: true,
801    /// * reference_types: true,
802    /// * simd: true,
803    /// * relax_simd: true,
804    /// * multi_memories: true,
805    /// * threads: false,
806    /// * gc: true,
807    /// * tail_call: true,
808    /// * extended_const: true,
809    /// * annotations: false,
810    /// * memory64: true,
811    /// * exception_handling: true,
812    /// * function_references: true,
813    /// * component_model: false,
814    /// * run_mode: RunMode::Interpreter,
815    fn default() -> Self {
816        Self::new()
817    }
818}
819
820/// Defines a group of configuration options for AOT compiler.
821///
822/// [CompilerConfigOptions] is used to set the AOT compiler related configuration options, which are
823///
824///  - Compiler Optimization Levels
825///    - `O0` performs as many optimizations as possible.
826///    
827///    - `O1` optimizes quickly without destroying debuggability  
828///    - `02` optimizes for fast execution as much as possible without triggering significant incremental
829///      compile time or code size growth  
830///    - `O3` optimizes for fast execution as much as possible  
831///    - `Os` optimizes for small code size as much as possible without triggering significant incremental
832///      compile time or execution time slowdowns  
833///    - `Oz` optimizes for small code size as much as possible  
834///  - Compiler Output Formats
835///    - `Native` specifies the output format is native dynamic library (`*.wasm.so`)  
836///    - `Wasm` specifies the output format is WebAssembly with AOT compiled codes in custom section (`*.wasm`).
837///  
838///  - `dump_ir` determines if AOT compiler generates IR or not  
839///  - `generic_binary` determines if AOT compiler generates the generic binary or not.
840///  - `interruptible` determines if AOT compiler generates interruptible binary or not.
841///  
842///  The configuration options above are only effective to [AOT compiler](crate::Compiler).
843#[cfg(feature = "aot")]
844#[cfg_attr(docsrs, doc(cfg(feature = "aot")))]
845#[derive(Debug, Clone, Copy)]
846pub struct CompilerConfigOptions {
847    out_format: CompilerOutputFormat,
848    opt_level: CompilerOptimizationLevel,
849    dump_ir: bool,
850    generic_binary: bool,
851    interruptible: bool,
852}
853#[cfg(feature = "aot")]
854#[cfg_attr(docsrs, doc(cfg(feature = "aot")))]
855impl CompilerConfigOptions {
856    /// Creates a new instance of [CompilerConfigOptions].
857    pub fn new() -> Self {
858        Self {
859            out_format: CompilerOutputFormat::Wasm,
860            opt_level: CompilerOptimizationLevel::O3,
861            dump_ir: false,
862            generic_binary: false,
863            interruptible: false,
864        }
865    }
866
867    /// Sets the output binary format of AOT compiler.
868    ///
869    /// # Argument
870    ///
871    /// - `format` specifies the format of the output binary.
872    pub fn out_format(self, format: CompilerOutputFormat) -> Self {
873        Self {
874            out_format: format,
875            ..self
876        }
877    }
878
879    /// Sets the optimization level of AOT compiler.
880    ///
881    /// # Argument
882    ///
883    /// - `level` specifies the optimization level of AOT compiler.
884    pub fn optimization_level(self, level: CompilerOptimizationLevel) -> Self {
885        Self {
886            opt_level: level,
887            ..self
888        }
889    }
890
891    /// Sets the dump IR option of AOT compiler.
892    ///
893    /// # Argument
894    ///
895    /// - `enable` specifies if dump ir or not.
896    pub fn dump_ir(self, enable: bool) -> Self {
897        Self {
898            dump_ir: enable,
899            ..self
900        }
901    }
902
903    /// Sets the generic binary option of AOT compiler.
904    ///
905    /// # Argument
906    ///
907    /// - `enable` specifies if generate the generic binary or not when perform AOT compilation.
908    pub fn generic_binary(self, enable: bool) -> Self {
909        Self {
910            generic_binary: enable,
911            ..self
912        }
913    }
914
915    /// Enables or Disables the `Interruptible` option of AOT compiler.
916    ///
917    /// This option determines to generate interruptible binary or not when compilation in AOT compiler.
918    ///
919    /// # Argument
920    ///
921    /// - `enable` specifies if turn on the `Interruptible` option.
922    pub fn interruptible(self, enable: bool) -> Self {
923        Self {
924            interruptible: enable,
925            ..self
926        }
927    }
928}
929#[cfg(feature = "aot")]
930#[cfg_attr(docsrs, doc(cfg(feature = "aot")))]
931impl Default for CompilerConfigOptions {
932    fn default() -> Self {
933        Self::new()
934    }
935}
936
937/// Defines a group of runtime configuration options.
938///
939/// [RuntimeConfigOptions] is used to set the runtime configuration options, which are
940///
941/// - `maximum_memory_page` limits the page size of [Memory](crate::Memory). This option is only effective to
942///   [Executor](crate::Executor).
943///
944/// - `allow_afunix` allows the use of `AF_UNIX` sockets in the WASI socket implementation.
945#[derive(Debug, Clone, Copy)]
946pub struct RuntimeConfigOptions {
947    max_memory_pages: u32,
948    allow_afunix: bool,
949}
950impl RuntimeConfigOptions {
951    /// Creates a new instance of [RuntimeConfigOptions].
952    ///
953    /// The default options are:
954    /// * max_memory_pages: 65536,
955    /// * allow_afunix: false,
956    pub fn new() -> Self {
957        Self {
958            max_memory_pages: 65536,
959            allow_afunix: false,
960        }
961    }
962
963    /// Sets the maximum number of the memory pages available.
964    ///
965    /// # Argument
966    ///
967    /// - `count` specifies the page count (64KB per page).
968    pub fn max_memory_pages(self, count: u32) -> Self {
969        Self {
970            max_memory_pages: count,
971            ..self
972        }
973    }
974
975    /// Allows or disallows the use of `AF_UNIX` sockets in the WASI socket implementation.
976    ///
977    /// # Argument
978    ///
979    /// - `enable` specifies if the option turns on or not.
980    pub fn allow_afunix(self, enable: bool) -> Self {
981        Self {
982            allow_afunix: enable,
983            ..self
984        }
985    }
986}
987impl Default for RuntimeConfigOptions {
988    fn default() -> Self {
989        Self::new()
990    }
991}
992
993/// Defines a group of the statistics configuration options.
994///
995/// [StatisticsConfigOptions] is used to set the statistics configuration options, which are
996///
997///  - `count_instructions` determines if measuring the count of instructions when running a compiled or pure WASM.
998///   
999///  - `measure_cost` determines if measuring the instruction costs when running a compiled or pure WASM.
1000///   
1001///  - `measure_time` determines if measuring the running time when running a compiled or pure WASM.
1002#[derive(Debug, Default, Clone, Copy)]
1003pub struct StatisticsConfigOptions {
1004    count_instructions: bool,
1005    measure_cost: bool,
1006    measure_time: bool,
1007}
1008impl StatisticsConfigOptions {
1009    /// Creates a new instance of [StatisticsConfigOptions].
1010    pub fn new() -> Self {
1011        Self::default()
1012    }
1013
1014    /// Sets the instruction counting option.
1015    ///
1016    /// # Argument
1017    ///
1018    /// - `enable` specifies if support instruction counting or not when execution after AOT compilation.
1019    pub fn count_instructions(self, enable: bool) -> Self {
1020        Self {
1021            count_instructions: enable,
1022            ..self
1023        }
1024    }
1025
1026    /// Sets the cost measuring option.
1027    ///
1028    /// # Argument
1029    ///
1030    /// - `enable` specifies if support cost measuring or not when execution after AOT compilation.
1031    pub fn measure_cost(self, enable: bool) -> Self {
1032        Self {
1033            measure_cost: enable,
1034            ..self
1035        }
1036    }
1037
1038    /// Sets the time measuring option.
1039    ///
1040    /// # Argument
1041    ///
1042    /// - `enable` specifies if support time measuring or not when execution after AOT compilation.
1043    pub fn measure_time(self, enable: bool) -> Self {
1044        Self {
1045            measure_time: enable,
1046            ..self
1047        }
1048    }
1049}
1050
1051#[cfg(test)]
1052mod proposal_tests {
1053    use super::*;
1054
1055    /// The default configuration must match the default proposal set of WasmEdge 0.17.1.
1056    #[test]
1057    fn test_config_defaults_match_runtime() {
1058        let config = ConfigBuilder::new(CommonConfigOptions::default())
1059            .build()
1060            .unwrap();
1061
1062        // enabled by default in WasmEdge 0.17.1
1063        assert!(config.mutable_globals_enabled());
1064        assert!(config.non_trap_conversions_enabled());
1065        assert!(config.sign_extension_operators_enabled());
1066        assert!(config.multi_value_enabled());
1067        assert!(config.bulk_memory_operations_enabled());
1068        assert!(config.reference_types_enabled());
1069        assert!(config.simd_enabled());
1070        assert!(config.relax_simd_enabled());
1071        assert!(config.tail_call_enabled());
1072        assert!(config.extended_const_enabled());
1073        assert!(config.function_references_enabled());
1074        assert!(config.gc_enabled());
1075        assert!(config.multi_memories_enabled());
1076        assert!(config.exception_handling_enabled());
1077        assert!(config.memory64_enabled());
1078
1079        // disabled by default in WasmEdge 0.17.1
1080        assert!(!config.threads_enabled());
1081        assert!(!config.annotations_enabled());
1082        assert!(!config.component_model_enabled());
1083        assert!(!config.allow_afunix_enabled());
1084
1085        assert_eq!(config.run_mode(), RunMode::Interpreter);
1086        assert_eq!(config.max_memory_pages(), 65536);
1087
1088        // the built defaults must be identical to a fresh runtime configuration
1089        let runtime_defaults = sys::Config::create().unwrap();
1090        assert_eq!(
1091            config.mutable_globals_enabled(),
1092            runtime_defaults.mutable_globals_enabled()
1093        );
1094        assert_eq!(
1095            config.non_trap_conversions_enabled(),
1096            runtime_defaults.non_trap_conversions_enabled()
1097        );
1098        assert_eq!(
1099            config.sign_extension_operators_enabled(),
1100            runtime_defaults.sign_extension_operators_enabled()
1101        );
1102        assert_eq!(
1103            config.multi_value_enabled(),
1104            runtime_defaults.multi_value_enabled()
1105        );
1106        assert_eq!(
1107            config.bulk_memory_operations_enabled(),
1108            runtime_defaults.bulk_memory_operations_enabled()
1109        );
1110        assert_eq!(
1111            config.reference_types_enabled(),
1112            runtime_defaults.reference_types_enabled()
1113        );
1114        assert_eq!(config.simd_enabled(), runtime_defaults.simd_enabled());
1115        assert_eq!(
1116            config.relax_simd_enabled(),
1117            runtime_defaults.relax_simd_enabled()
1118        );
1119        assert_eq!(
1120            config.tail_call_enabled(),
1121            runtime_defaults.tail_call_enabled()
1122        );
1123        assert_eq!(
1124            config.extended_const_enabled(),
1125            runtime_defaults.extended_const_enabled()
1126        );
1127        assert_eq!(
1128            config.function_references_enabled(),
1129            runtime_defaults.function_references_enabled()
1130        );
1131        assert_eq!(config.gc_enabled(), runtime_defaults.gc_enabled());
1132        assert_eq!(
1133            config.multi_memories_enabled(),
1134            runtime_defaults.multi_memories_enabled()
1135        );
1136        assert_eq!(
1137            config.exception_handling_enabled(),
1138            runtime_defaults.exception_handling_enabled()
1139        );
1140        assert_eq!(
1141            config.memory64_enabled(),
1142            runtime_defaults.memory64_enabled()
1143        );
1144        assert_eq!(config.threads_enabled(), runtime_defaults.threads_enabled());
1145        assert_eq!(
1146            config.annotations_enabled(),
1147            runtime_defaults.annotations_enabled()
1148        );
1149        assert_eq!(
1150            config.component_model_enabled(),
1151            runtime_defaults.component_model_enabled()
1152        );
1153        assert_eq!(
1154            config.allow_afunix_enabled(),
1155            runtime_defaults.allow_afunix_enabled()
1156        );
1157    }
1158
1159    /// Disabling ReferenceTypes together with its dependents must not be silently ignored:
1160    /// the dependents (GC, FunctionReferences) must be disabled before the dependency.
1161    #[test]
1162    fn test_config_disable_proposals_in_dependency_order() {
1163        let config = ConfigBuilder::new(
1164            CommonConfigOptions::default()
1165                .gc(false)
1166                .function_references(false)
1167                .reference_types(false),
1168        )
1169        .build()
1170        .unwrap();
1171
1172        assert!(!config.gc_enabled());
1173        assert!(!config.function_references_enabled());
1174        assert!(!config.reference_types_enabled());
1175    }
1176
1177    /// While GC stays enabled, the runtime keeps its dependencies enabled.
1178    #[test]
1179    fn test_config_gc_keeps_dependencies_enabled() {
1180        let config = ConfigBuilder::new(
1181            CommonConfigOptions::default()
1182                .gc(true)
1183                .function_references(false)
1184                .reference_types(false),
1185        )
1186        .build()
1187        .unwrap();
1188
1189        assert!(config.gc_enabled());
1190        assert!(config.function_references_enabled());
1191        assert!(config.reference_types_enabled());
1192    }
1193
1194    #[test]
1195    fn test_config_wasm_standard_presets() {
1196        // WASM 1.0
1197        let config =
1198            ConfigBuilder::new(CommonConfigOptions::from_wasm_standard(WasmStandard::Wasm1))
1199                .build()
1200                .unwrap();
1201        assert!(config.mutable_globals_enabled());
1202        assert!(!config.non_trap_conversions_enabled());
1203        assert!(!config.sign_extension_operators_enabled());
1204        assert!(!config.multi_value_enabled());
1205        assert!(!config.bulk_memory_operations_enabled());
1206        assert!(!config.reference_types_enabled());
1207        assert!(!config.simd_enabled());
1208        assert!(!config.relax_simd_enabled());
1209        assert!(!config.tail_call_enabled());
1210        assert!(!config.extended_const_enabled());
1211        assert!(!config.function_references_enabled());
1212        assert!(!config.gc_enabled());
1213        assert!(!config.multi_memories_enabled());
1214        assert!(!config.exception_handling_enabled());
1215        assert!(!config.memory64_enabled());
1216
1217        // WASM 2.0
1218        let config =
1219            ConfigBuilder::new(CommonConfigOptions::from_wasm_standard(WasmStandard::Wasm2))
1220                .build()
1221                .unwrap();
1222        assert!(config.mutable_globals_enabled());
1223        assert!(config.non_trap_conversions_enabled());
1224        assert!(config.sign_extension_operators_enabled());
1225        assert!(config.multi_value_enabled());
1226        assert!(config.bulk_memory_operations_enabled());
1227        assert!(config.reference_types_enabled());
1228        assert!(config.simd_enabled());
1229        assert!(!config.relax_simd_enabled());
1230        assert!(!config.tail_call_enabled());
1231        assert!(!config.gc_enabled());
1232        assert!(!config.memory64_enabled());
1233
1234        // WASM 3.0: matches the WasmEdge 0.17.1 defaults
1235        let config =
1236            ConfigBuilder::new(CommonConfigOptions::from_wasm_standard(WasmStandard::Wasm3))
1237                .build()
1238                .unwrap();
1239        let defaults = ConfigBuilder::new(CommonConfigOptions::default())
1240            .build()
1241            .unwrap();
1242        assert_eq!(
1243            config.mutable_globals_enabled(),
1244            defaults.mutable_globals_enabled()
1245        );
1246        assert_eq!(
1247            config.non_trap_conversions_enabled(),
1248            defaults.non_trap_conversions_enabled()
1249        );
1250        assert_eq!(
1251            config.sign_extension_operators_enabled(),
1252            defaults.sign_extension_operators_enabled()
1253        );
1254        assert_eq!(config.multi_value_enabled(), defaults.multi_value_enabled());
1255        assert_eq!(
1256            config.bulk_memory_operations_enabled(),
1257            defaults.bulk_memory_operations_enabled()
1258        );
1259        assert_eq!(
1260            config.reference_types_enabled(),
1261            defaults.reference_types_enabled()
1262        );
1263        assert_eq!(config.simd_enabled(), defaults.simd_enabled());
1264        assert_eq!(config.relax_simd_enabled(), defaults.relax_simd_enabled());
1265        assert_eq!(config.tail_call_enabled(), defaults.tail_call_enabled());
1266        assert_eq!(
1267            config.extended_const_enabled(),
1268            defaults.extended_const_enabled()
1269        );
1270        assert_eq!(
1271            config.function_references_enabled(),
1272            defaults.function_references_enabled()
1273        );
1274        assert_eq!(config.gc_enabled(), defaults.gc_enabled());
1275        assert_eq!(
1276            config.multi_memories_enabled(),
1277            defaults.multi_memories_enabled()
1278        );
1279        assert_eq!(
1280            config.exception_handling_enabled(),
1281            defaults.exception_handling_enabled()
1282        );
1283        assert_eq!(config.memory64_enabled(), defaults.memory64_enabled());
1284        assert_eq!(config.threads_enabled(), defaults.threads_enabled());
1285        assert_eq!(config.annotations_enabled(), defaults.annotations_enabled());
1286        assert_eq!(
1287            config.component_model_enabled(),
1288            defaults.component_model_enabled()
1289        );
1290    }
1291
1292    #[test]
1293    fn test_config_toggle_new_proposals() {
1294        let config = ConfigBuilder::new(
1295            CommonConfigOptions::default()
1296                .relax_simd(false)
1297                .extended_const(false)
1298                .exception_handling(false)
1299                .memory64(false)
1300                .annotations(true)
1301                .component_model(true),
1302        )
1303        .with_runtime_config(RuntimeConfigOptions::default().allow_afunix(true))
1304        .build()
1305        .unwrap();
1306
1307        assert!(!config.relax_simd_enabled());
1308        assert!(!config.extended_const_enabled());
1309        assert!(!config.exception_handling_enabled());
1310        assert!(!config.memory64_enabled());
1311        assert!(config.annotations_enabled());
1312        assert!(config.component_model_enabled());
1313        assert!(config.allow_afunix_enabled());
1314    }
1315}
1316
1317#[cfg(test)]
1318#[cfg(feature = "aot")]
1319mod tests {
1320    use super::*;
1321
1322    #[test]
1323    fn test_config_create() {
1324        let common_options = CommonConfigOptions::default()
1325            .bulk_memory_operations(true)
1326            .multi_value(true)
1327            .mutable_globals(true)
1328            .non_trap_conversions(true)
1329            .reference_types(true)
1330            .sign_extension_operators(true)
1331            .simd(true)
1332            .multi_memories(true)
1333            .run_mode(RunMode::Aot);
1334
1335        let compiler_options = CompilerConfigOptions::default()
1336            .dump_ir(true)
1337            .generic_binary(true)
1338            .interruptible(true)
1339            .optimization_level(CompilerOptimizationLevel::O0)
1340            .out_format(CompilerOutputFormat::Native);
1341
1342        let stat_options = StatisticsConfigOptions::default()
1343            .count_instructions(true)
1344            .measure_cost(true)
1345            .measure_time(true);
1346
1347        let runtime_options = RuntimeConfigOptions::default().max_memory_pages(1024);
1348
1349        let result = ConfigBuilder::new(common_options)
1350            .with_statistics_config(stat_options)
1351            .with_compiler_config(compiler_options)
1352            .with_runtime_config(runtime_options)
1353            .build();
1354        assert!(result.is_ok());
1355        let config = result.unwrap();
1356
1357        // check common config options
1358        assert!(config.bulk_memory_operations_enabled());
1359        assert!(config.multi_value_enabled());
1360        assert!(config.mutable_globals_enabled());
1361        assert!(config.non_trap_conversions_enabled());
1362        assert!(config.reference_types_enabled());
1363        assert!(config.sign_extension_operators_enabled());
1364        assert!(config.simd_enabled());
1365        assert!(config.multi_memories_enabled());
1366        assert_eq!(config.run_mode(), RunMode::Aot);
1367
1368        // check compiler config options
1369        assert!(config.dump_ir_enabled());
1370        assert!(config.generic_binary_enabled());
1371        assert!(config.interruptible_enabled());
1372        assert_eq!(config.optimization_level(), CompilerOptimizationLevel::O0);
1373        assert_eq!(config.out_format(), CompilerOutputFormat::Native);
1374
1375        // check statistics config options
1376        assert!(config.instruction_counting_enabled());
1377        assert!(config.cost_measuring_enabled());
1378        assert!(config.time_measuring_enabled());
1379
1380        // check runtime config options
1381        assert_eq!(config.max_memory_pages(), 1024);
1382    }
1383
1384    #[test]
1385    fn test_config_copy() {
1386        let common_config = CommonConfigOptions::default()
1387            .simd(false)
1388            .multi_memories(true);
1389        let compiler_config =
1390            CompilerConfigOptions::default().optimization_level(CompilerOptimizationLevel::O0);
1391        let stat_config = StatisticsConfigOptions::default().measure_time(false);
1392        let runtime_config = RuntimeConfigOptions::default().max_memory_pages(1024);
1393
1394        let result = ConfigBuilder::new(common_config)
1395            .with_statistics_config(stat_config)
1396            .with_compiler_config(compiler_config)
1397            .with_runtime_config(runtime_config)
1398            .build();
1399        assert!(result.is_ok());
1400        let config = result.unwrap();
1401        assert!(!config.simd_enabled());
1402        assert!(config.multi_memories_enabled());
1403        assert_eq!(config.optimization_level(), CompilerOptimizationLevel::O0);
1404        assert!(!config.time_measuring_enabled());
1405        assert_eq!(config.max_memory_pages(), 1024);
1406
1407        // make a copy
1408        let config_copied = config.clone();
1409        assert!(!config_copied.simd_enabled());
1410        assert!(config_copied.multi_memories_enabled());
1411        assert_eq!(
1412            config_copied.optimization_level(),
1413            CompilerOptimizationLevel::O0
1414        );
1415        assert!(!config.time_measuring_enabled());
1416        assert_eq!(config_copied.max_memory_pages(), 1024);
1417    }
1418}