Skip to main content

wasmedge_sys/
config.rs

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