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}