fn rewrite_with_module_linking(
        &self,
        cx: &mut ModuleContext<'_>,
        store: &crate::Store,
        snapshot: &Snapshot,
        renames: &FuncRenames,
    ) -> Vec<u8> {
        let mut umbrella = wasm_encoder::Module::new();

        // Counts of various entities defined inside the umbrella module thus
        // far.
        let mut umbrella_funcs = 0;
        let mut umbrella_tables = 0;
        let mut umbrella_memories = 0;
        let mut umbrella_globals = 0;
        let mut umbrella_instances = 0;

        let (code_modules, num_code_modules) = rewrite_code_modules(cx);

        let root_state_module = rewrite_state_module(cx, store, cx.root(), &snapshot, 0);
        let mut modules = wasm_encoder::ModuleSection::new();
        modules.module(&root_state_module);
        let root_state_module_index = num_code_modules;

        // Imports that we will need to pass through from the umbrella to the
        // root instance.
        let import_sections: Vec<_> = cx
            .root()
            .initial_sections(cx)
            .filter(|s| s.id == SectionId::Import.into())
            .collect();

        // Instantiate the root state module by forwarding imports from the
        // umbrella to the root instantiation.
        //
        // There is some trickery for implicit instance imports. We forward the
        // implicit instance as an instantiation argument, since we can't
        // provide two-level instantiation arguments, which means we need to
        // determine when implicit imports are injected again.
        let mut instances = wasm_encoder::InstanceSection::new();
        let mut args = vec![];
        let mut imports = cx.root().imports(cx).iter().peekable();
        loop {
            let (module, is_two_level) = match imports.peek() {
                Some(imp) => (imp.module, imp.field.is_some()),
                None => break,
            };

            if is_two_level {
                args.push((module, wasm_encoder::Export::Instance(umbrella_instances)));
                umbrella_instances += 1;
            }
            while imports.peek().map_or(false, |imp| imp.module == module) {
                let imp = imports.next().unwrap();
                let export = match imp.ty {
                    wasmparser::ImportSectionEntryType::Function(_) => {
                        umbrella_funcs += 1;
                        wasm_encoder::Export::Function(umbrella_funcs - 1)
                    }
                    wasmparser::ImportSectionEntryType::Instance(_) => {
                        umbrella_instances += 1;
                        wasm_encoder::Export::Instance(umbrella_instances - 1)
                    }
                    _ => unreachable!(),
                };
                if !is_two_level {
                    args.push((module, export));
                }
            }
        }
        instances.instantiate(root_state_module_index, args.iter().cloned());
        let root_state_instance_index = umbrella_instances;
        umbrella_instances += 1;

        // Instantiate the root code module with the root state module.
        let root_module_index = cx.root().pre_order_index();
        args.push((
            "__wizer_state",
            wasm_encoder::Export::Instance(root_state_instance_index),
        ));
        instances.instantiate(root_module_index, args);
        let root_instance_index = umbrella_instances;
        umbrella_instances += 1;

        // Alias the root instance's exports and then re-export them.
        let mut aliases = wasm_encoder::AliasSection::new();
        let mut exports = wasm_encoder::ExportSection::new();
        for exp in cx.root().exports(cx) {
            if exp.field == self.init_func {
                continue;
            }

            if !renames.rename_src_to_dst.contains_key(exp.field)
                && renames.rename_dsts.contains(exp.field)
            {
                // A rename overwrites this export, and it is not renamed to
                // another export, so skip it.
                continue;
            }

            let kind = translate::item_kind(exp.kind);
            aliases.instance_export(root_instance_index, kind, exp.field);

            let field = renames
                .rename_src_to_dst
                .get(exp.field)
                .map_or(exp.field, |f| f.as_str());
            exports.export(
                field,
                match kind {
                    wasm_encoder::ItemKind::Function => {
                        umbrella_funcs += 1;
                        wasm_encoder::Export::Function(umbrella_funcs - 1)
                    }
                    wasm_encoder::ItemKind::Table => {
                        umbrella_tables += 1;
                        wasm_encoder::Export::Table(umbrella_tables - 1)
                    }
                    wasm_encoder::ItemKind::Memory => {
                        umbrella_memories += 1;
                        wasm_encoder::Export::Memory(umbrella_memories - 1)
                    }
                    wasm_encoder::ItemKind::Global => {
                        umbrella_globals += 1;
                        wasm_encoder::Export::Global(umbrella_globals - 1)
                    }
                    wasm_encoder::ItemKind::Instance => {
                        umbrella_instances += 1;
                        wasm_encoder::Export::Instance(umbrella_instances - 1)
                    }
                    wasm_encoder::ItemKind::Module => unreachable!(),
                },
            );
        }

        // NB: We encode the types last, even though it is the first section we
        // place in the umbrella module, since adding state imports may need to
        // define new instance types.
        let types = umbrella_type_section(cx);

        // Now combine all our sections together in the umbrella module.
        umbrella.section(&types);
        umbrella.section(&code_modules);
        umbrella.section(&modules);
        for s in import_sections {
            umbrella.section(s);
        }
        umbrella.section(&instances);
        umbrella.section(&aliases);
        umbrella.section(&exports);

        umbrella.finish()
    }
/// Rewrite a module linking bundle.
///
/// ## Code Shape
///
/// With module linking, we rewrite each module in the original bundle into
/// a *code module* that doesn't define any internal state (i.e. memories,
/// globals, and nested instances) and instead imports a *state instance*
/// that exports all of these things. For each instantiation, we have a
/// *state module* that defines the already-initialized state for that
/// instantiation, we instantiate that state module to create one such state
/// instance, and then use this as an import argument in the instantiation
/// of the original code module. This way, we do not duplicate shared code
/// bodies across multiple instantiations of the same module.
///
/// Note that the root module is also split out into a code module and state
/// module, even though it is never explicitly instantiated inside the
/// bundle.
///
/// The new root is an "umbrella" module that defines all the types used
/// within the whole bundle. Each nested module then aliases its types from
/// the umbrella module. The umbrella module aliases all exports of the
/// original root and re-exports them.
///
/// For example, given this input Wasm module:
///
/// ```wat
/// (module $A
///   (module $B
///     (memory $B_mem)
///     (global $B_glob (mut i32))
///     (func (export "f") ...)
///   )
///
///   (instance $x (instantiate $B))
///   (instance $y (instantiate $B))
///
///   (memory $A_mem)
///   (global $A_glob (mut i32))
///
///   (func (export "g") ...)
/// )
/// ```
///
/// and some post-initialization state, this rewrite pass will produce the
/// following pre-initialized module:
///
/// ```wat
/// (module $Umbrella
///   (module $A
///     ;; Locally defined state is replaced by a state instance import.
///     (import "__wizer_state"
///       (instance
///         (export "__wizer_memory_0" (memory $A_mem))
///         (export "__wizer_global_0" (global $A_glob (mut i32)))
///         (export "__wizer_instance_0" (instance $x (export "f" (func))))
///         (export "__wizer_instance_1" (instance $y (export "f" (func))))
///       )
///     )
///     (func (export "g") ...)
///   )
///
///   (module $B
///     ;; Locally defined state is replaced by a state instance import.
///     (import "__wizer_state"
///       (instance
///         (export "__wizer_memory_0" (memory $B_mem))
///         (export "__wizer_global_0" (global $B_glob (mut i32)))
///       )
///     )
///     (func (export "f") ...)
///   )
///
///   ;; Instantiations are replaced with specialized state modules that get
///   ;; instantiated exactly once to produce state instances, and finally
///   ;; the original instantiations are rewritten into instantiations of
///   ;; the corresponding code module with the state instance as an import
///   ;; argument.
///
///   ;; State module for `$A`.
///   (module $A_state_module
///     ;; State module for `$x`.
///     (module $x_state_module
///       (memory (export "__wizer_memory_0") (memory))
///       ;; Data segments to initialize the memory based on our snapshot
///       ;; would go here...
///
///       (global (export "__wizer_global_0")
///         (global (mut i32) (i32.const (; ...snapshot's initialized value goes here... ;)))
///       )
///     )
///
///     ;; State instance for `$x`.
///     (instance $x_state (instantiate $x_state_module))
///
///     ;; The instantiation of `$x` is now rewritten to use our state
///     ;; instance.
///     (instance $x (instantiate $B (import "__wizer_state" $x_state)))
///
///     ;; Same goes for the `$y` instantiation.
///     (module $y_state_module
///       (memory (export "__wizer_memory_0") (memory))
///       ;; Data segments...
///       (global (export "__wizer_global_0")
///         (global (mut i32) (i32.const (; ...snapshot's initialized value goes here... ;)))
///       )
///     )
///     (instance $y_state (instantiate $y_state_module))
///     (instance $y (instantiate $B (import "__wizer_state" $y_state)))
///
///     (memory $A_mem)
///     (global $A_glob (mut i32))
///   )
///
///   ;; State instance for `$A`.
///   (instance $a_state (instantiate $A_state_module))
///
///   ;; The state is now joined with the code.
///   (instance $a_instance (instantiate $A (import "__wizer_state" $a_state)))
///
///   ;; And finally we re-export all of our old root's exports.
///   (export "g" (func $a_instance "g"))
/// )
/// ```
///
/// ## Implementation
///
/// To implement this transformation, we first do a pre-order walk of the
/// module tree and emit the code modules as a flat sequence. Why a flat
/// sequence? The code modules cannot contain nested instantiations, because
/// nested instantiations are state that is not necessarily shared across
/// all instantiations of the outer module. And if we are already lifting
/// out nested instantiations, we need to also make nested modules available
/// for those lifted instantiations, and the easiest way to do that is to
/// flatten the code module tree (as opposed to re-exporting the nested
/// modules under well-known symbols). The pre-order traversal ensures that
/// the `Module::id` we assigned during the instrumentation phase matches
/// the module's place in the index space.
///
/// The state modules, however, remain a nested tree, and we emit them in a
/// traversal of the `Snapshot` instance tree. We can do this because,
/// unlike code modules, each state module is only instantiated exactly
/// once. The instantiations' references to nested modules become outer
/// aliases pointing to the module's position in the parent's flat sequence
/// of nested modules.
Rewrite a module linking bundle.
Rewrite a module linking bundle .
fn rewrite_with_module_linking(
        &self,
        cx: &mut ModuleContext<'_>,
        store: &crate::Store,
        snapshot: &Snapshot,
        renames: &FuncRenames,
    ) -> Vec<u8> {
        let mut umbrella = wasm_encoder::Module::new();
        // Counts of various entities defined inside the umbrella module thus
        // far.
        let mut umbrella_funcs = 0;
        let mut umbrella_tables = 0;
        let mut umbrella_memories = 0;
        let mut umbrella_globals = 0;
        let mut umbrella_instances = 0;
        let (code_modules, num_code_modules) = rewrite_code_modules(cx);
        let root_state_module = rewrite_state_module(cx, store, cx.root(), &snapshot, 0);
        let mut modules = wasm_encoder::ModuleSection::new();
        modules.module(&root_state_module);
        let root_state_module_index = num_code_modules;
        // Imports that we will need to pass through from the umbrella to the
        // root instance.
        let import_sections: Vec<_> = cx
            .root()
            .initial_sections(cx)
            .filter(|s| s.id == SectionId::Import.into())
            .collect();
        // Instantiate the root state module by forwarding imports from the
        // umbrella to the root instantiation.
        //
        // There is some trickery for implicit instance imports. We forward the
        // implicit instance as an instantiation argument, since we can't
        // provide two-level instantiation arguments, which means we need to
        // determine when implicit imports are injected again.
        let mut instances = wasm_encoder::InstanceSection::new();
        let mut args = vec![];
        let mut imports = cx.root().imports(cx).iter().peekable();
        loop {
            let (module, is_two_level) = match imports.peek() {
                Some(imp) => (imp.module, imp.field.is_some()),
                None => break,
            };
            if is_two_level {
                args.push((module, wasm_encoder::Export::Instance(umbrella_instances)));
                umbrella_instances += 1;
            }
            while imports.peek().map_or(false, |imp| imp.module == module) {
                let imp = imports.next().unwrap();
                let export = match imp.ty {
                    wasmparser::ImportSectionEntryType::Function(_) => {
                        umbrella_funcs += 1;
                        wasm_encoder::Export::Function(umbrella_funcs - 1)
                    }
                    wasmparser::ImportSectionEntryType::Instance(_) => {
                        umbrella_instances += 1;
                        wasm_encoder::Export::Instance(umbrella_instances - 1)
                    }
                    _ => unreachable!(),
                };
                if !is_two_level {
                    args.push((module, export));
                }
            }
        }
        instances.instantiate(root_state_module_index, args.iter().cloned());
        let root_state_instance_index = umbrella_instances;
        umbrella_instances += 1;
        // Instantiate the root code module with the root state module.
        let root_module_index = cx.root().pre_order_index();
        args.push((
            "__wizer_state",
            wasm_encoder::Export::Instance(root_state_instance_index),
        ));
        instances.instantiate(root_module_index, args);
        let root_instance_index = umbrella_instances;
        umbrella_instances += 1;
        // Alias the root instance's exports and then re-export them.
        let mut aliases = wasm_encoder::AliasSection::new();
        let mut exports = wasm_encoder::ExportSection::new();
        for exp in cx.root().exports(cx) {
            if exp.field == self.init_func {
                continue;
            }
            if !renames.rename_src_to_dst.contains_key(exp.field)
                && renames.rename_dsts.contains(exp.field)
            {
                // A rename overwrites this export, and it is not renamed to
                // another export, so skip it.
                continue;
            }
            let kind = translate::item_kind(exp.kind);
            aliases.instance_export(root_instance_index, kind, exp.field);
            let field = renames
                .rename_src_to_dst
                .get(exp.field)
                .map_or(exp.field, |f| f.as_str());
            exports.export(
                field,
                match kind {
                    wasm_encoder::ItemKind::Function => {
                        umbrella_funcs += 1;
                        wasm_encoder::Export::Function(umbrella_funcs - 1)
                    }
                    wasm_encoder::ItemKind::Table => {
                        umbrella_tables += 1;
                        wasm_encoder::Export::Table(umbrella_tables - 1)
                    }
                    wasm_encoder::ItemKind::Memory => {
                        umbrella_memories += 1;
                        wasm_encoder::Export::Memory(umbrella_memories - 1)
                    }
                    wasm_encoder::ItemKind::Global => {
                        umbrella_globals += 1;
                        wasm_encoder::Export::Global(umbrella_globals - 1)
                    }
                    wasm_encoder::ItemKind::Instance => {
                        umbrella_instances += 1;
                        wasm_encoder::Export::Instance(umbrella_instances - 1)
                    }
                    wasm_encoder::ItemKind::Module => unreachable!(),
                },
            );
        }
        // NB: We encode the types last, even though it is the first section we
        // place in the umbrella module, since adding state imports may need to
        // define new instance types.
        let types = umbrella_type_section(cx);
        // Now combine all our sections together in the umbrella module.
        umbrella.section(&types);
        umbrella.section(&code_modules);
        umbrella.section(&modules);
        for s in import_sections {
            umbrella.section(s);
        }
        umbrella.section(&instances);
        umbrella.section(&aliases);
        umbrella.section(&exports);
        umbrella.finish()
    }
fn rewrite_with_module_linking ( & self , cx : & mut ModuleContext < ' _ > , store : & crate :: Store , snapshot : & Snapshot , renames : & FuncRenames , ) -> Vec < u8 > { let mut umbrella = wasm_encoder :: Module :: new ( ) ; // Counts of various entities defined inside the umbrella module thus // far. let mut umbrella_funcs = 0 ; let mut umbrella_tables = 0 ; let mut umbrella_memories = 0 ; let mut umbrella_globals = 0 ; let mut umbrella_instances = 0 ; let ( code_modules , num_code_modules ) = rewrite_code_modules ( cx ) ; let root_state_module = rewrite_state_module ( cx , store , cx . root ( ) , & snapshot , 0 ) ; let mut modules = wasm_encoder :: ModuleSection :: new ( ) ; modules . module ( & root_state_module ) ; let root_state_module_index = num_code_modules ; // Imports that we will need to pass through from the umbrella to the // root instance. let import_sections : Vec < _ > = cx . root ( ) . initial_sections ( cx ) . filter ( | s | s . id == SectionId :: Import . into ( ) ) . collect ( ) ; // Instantiate the root state module by forwarding imports from the // umbrella to the root instantiation. // // There is some trickery for implicit instance imports. We forward the // implicit instance as an instantiation argument, since we can't // provide two-level instantiation arguments, which means we need to // determine when implicit imports are injected again. let mut instances = wasm_encoder :: InstanceSection :: new ( ) ; let mut args = vec ! [ ] ; let mut imports = cx . root ( ) . imports ( cx ) . iter ( ) . peekable ( ) ; loop { let ( module , is_two_level ) = match imports . peek ( ) { Some ( imp ) => ( imp . module , imp . field . is_some ( ) ) , None => break , } ; if is_two_level { args . push ( ( module , wasm_encoder :: Export :: Instance ( umbrella_instances ) ) ) ; umbrella_instances += 1 ; } while imports . peek ( ) . map_or ( false , | imp | imp . module == module ) { let imp = imports . next ( ) . unwrap ( ) ; let export = match imp . ty { wasmparser :: ImportSectionEntryType :: Function ( _ ) => { umbrella_funcs += 1 ; wasm_encoder :: Export :: Function ( umbrella_funcs - 1 ) } wasmparser :: ImportSectionEntryType :: Instance ( _ ) => { umbrella_instances += 1 ; wasm_encoder :: Export :: Instance ( umbrella_instances - 1 ) } _ => unreachable ! ( ) , } ; if ! is_two_level { args . push ( ( module , export ) ) ; } } } instances . instantiate ( root_state_module_index , args . iter ( ) . cloned ( ) ) ; let root_state_instance_index = umbrella_instances ; umbrella_instances += 1 ; // Instantiate the root code module with the root state module. let root_module_index = cx . root ( ) . pre_order_index ( ) ; args . push ( ( " " , wasm_encoder :: Export :: Instance ( root_state_instance_index ) , ) ) ; instances . instantiate ( root_module_index , args ) ; let root_instance_index = umbrella_instances ; umbrella_instances += 1 ; // Alias the root instance's exports and then re-export them. let mut aliases = wasm_encoder :: AliasSection :: new ( ) ; let mut exports = wasm_encoder :: ExportSection :: new ( ) ; for exp in cx . root ( ) . exports ( cx ) { if exp . field == self . init_func { continue ; } if ! renames . rename_src_to_dst . contains_key ( exp . field ) && renames . rename_dsts . contains ( exp . field ) { // A rename overwrites this export, and it is not renamed to // another export, so skip it. continue ; } let kind = translate :: item_kind ( exp . kind ) ; aliases . instance_export ( root_instance_index , kind , exp . field ) ; let field = renames . rename_src_to_dst . get ( exp . field ) . map_or ( exp . field , | f | f . as_str ( ) ) ; exports . export ( field , match kind { wasm_encoder :: ItemKind :: Function => { umbrella_funcs += 1 ; wasm_encoder :: Export :: Function ( umbrella_funcs - 1 ) } wasm_encoder :: ItemKind :: Table => { umbrella_tables += 1 ; wasm_encoder :: Export :: Table ( umbrella_tables - 1 ) } wasm_encoder :: ItemKind :: Memory => { umbrella_memories += 1 ; wasm_encoder :: Export :: Memory ( umbrella_memories - 1 ) } wasm_encoder :: ItemKind :: Global => { umbrella_globals += 1 ; wasm_encoder :: Export :: Global ( umbrella_globals - 1 ) } wasm_encoder :: ItemKind :: Instance => { umbrella_instances += 1 ; wasm_encoder :: Export :: Instance ( umbrella_instances - 1 ) } wasm_encoder :: ItemKind :: Module => unreachable ! ( ) , } , ) ; } // NB: We encode the types last, even though it is the first section we // place in the umbrella module, since adding state imports may need to // define new instance types. let types = umbrella_type_section ( cx ) ; // Now combine all our sections together in the umbrella module. umbrella . section ( & types ) ; umbrella . section ( & code_modules ) ; umbrella . section ( & modules ) ; for s in import_sections { umbrella . section ( s ) ; } umbrella . section ( & instances ) ; umbrella . section ( & aliases ) ; umbrella . section ( & exports ) ; umbrella . finish ( ) }
Rewrite a module linking bundle.
Rewrite a module linking bundle .
&self
cx
&mut ModuleContext<'_>
store
&crate::Store
snapshot
&Snapshot
renames
&FuncRenames
&self
cx
&mut ModuleContext<'_>
store
&crate::Store
snapshot
&Snapshot
renames
&FuncRenames
code shape
With module linking, we rewrite each module in the original bundle into
a *code module* that doesn't define any internal state  and instead imports a *state instance
that exports all of these things. For each instantiation, we have a
state module* that defines the already-initialized state for that
instantiation, we instantiate that state module to create one such state
instance, and then use this as an import argument in the instantiation
of the original code module. This way, we do not duplicate shared code
bodies across multiple instantiations of the same module.

Note that the root module is also split out into a code module and state
module, even though it is never explicitly instantiated inside the
bundle.

The new root is an "umbrella" module that defines all the types used
within the whole bundle. Each nested module then aliases its types from
the umbrella module. The umbrella module aliases all exports of the
original root and re-exports them.

For example, given this input Wasm module.



(instance $x (instantiate $B))
(instance $y (instantiate $B))

(memory $A_mem)
(global $A_glob (mut i32))



and some post-initialization state, this rewrite pass will produce the
following pre-initialized module.

```wat
(module $Umbrella
(module $A
;; Locally defined state is replaced by a state instance import.

(module $B
;; Locally defined state is replaced by a state instance import.
(import "__wizer_state"
(instance
(export "__wizer_memory_0" (memory $B_mem))
(export "__wizer_global_0" (global $B_glob (mut i32)))
)
)
(func (export "f") ...)
)

;; Instantiations are replaced with specialized state modules that get
;; instantiated exactly once to produce state instances, and finally
;; the original instantiations are rewritten into instantiations of
;; the corresponding code module with the state instance as an import
;; argument.

;; State module for `$A`.
(module $A_state_module
;; State module for `$x`.
(module $x_state_module
(memory (export "__wizer_memory_0") (memory))
;; Data segments to initialize the memory based on our snapshot
;; would go here

(global (export "__wizer_global_0")
(global (mut i32) (i32.const (; ...snapshot's initialized value goes here...

;; State instance for `$x`.
(instance $x_state (instantiate $x_state_module))

;; The instantiation of `$x` is now rewritten to use our state
;; instance.
(instance $x (instantiate $B (import "__wizer_state" $x_state)))

;; Same goes for the `$y` instantiation.
(module $y_state_module
(memory (export "__wizer_memory_0") (memory))
;; Data segments
(global (export "__wizer_global_0")
(global (mut i32) (i32.const (; ...snapshot's initialized value goes here... ;)))
)
)
(instance $y_state (instantiate $y_state_module))
(instance $y (instantiate $B (import "__wizer_state" $y_state)))

(memory $A_mem)
(global $A_glob (mut i32))
)

;; State instance for `$A`.
(instance $a_state (instantiate $A_state_module))

;; The state is now joined with the code.
(instance $a_instance (instantiate $A (import "__wizer_state" $a_state)))

;; And finally we re-export all of our old root's exports.
With module linking we rewrite each module in the original bundle into a * code module * that doesn ' t define any internal state and instead imports a * state instance that exports all of these things . For each instantiation we have a state module * that defines the already - initialized state for that instantiation we instantiate that state module to create one such state instance and then use this as an import argument in the instantiation of the original code module . This way we do not duplicate shared code bodies across multiple instantiations of the same module . Note that the root module is also split out into a code module and state module even though it is never explicitly instantiated inside the bundle . The new root is an " umbrella " module that defines all the types used within the whole bundle . Each nested module then aliases its types from the umbrella module . The umbrella module aliases all exports of the original root and re - exports them . For example given this input Wasm module . ( instance $x ( instantiate $B )) ( instance $y ( instantiate $B )) ( memory $A_mem ) ( global $A_glob ( mut i32 )) and some post - initialization state this rewrite pass will produce the following pre - initialized module . ` ` ` wat ( module $Umbrella ( module $A ;; Locally defined state is replaced by a state instance import . ( module $B ;; Locally defined state is replaced by a state instance import . ( import " __wizer_state " ( instance ( export " __wizer_memory_0 " ( memory $B_mem )) ( export " __wizer_global_0 " ( global $B_glob ( mut i32 ))) ) ) ( func ( export " f " ) ... ) ) ;; Instantiations are replaced with specialized state modules that get ;; instantiated exactly once to produce state instances and finally ;; the original instantiations are rewritten into instantiations of ;; the corresponding code module with the state instance as an import ;; argument . ;; State module for ` $A ` . ( module $A_state_module ;; State module for ` $x ` . ( module $x_state_module ( memory ( export " __wizer_memory_0 " ) ( memory )) ;; Data segments to initialize the memory based on our snapshot ;; would go here ( global ( export " __wizer_global_0 " ) ( global ( mut i32 ) ( i32 . const ( ; ... snapshot ' s initialized value goes here ... ;; State instance for ` $x ` . ( instance $x_state ( instantiate $x_state_module )) ;; The instantiation of ` $x ` is now rewritten to use our state ;; instance . ( instance $x ( instantiate $B ( import " __wizer_state " $x_state ))) ;; Same goes for the ` $y ` instantiation . ( module $y_state_module ( memory ( export " __wizer_memory_0 " ) ( memory )) ;; Data segments ( global ( export " __wizer_global_0 " ) ( global ( mut i32 ) ( i32 . const ( ; ... snapshot ' s initialized value goes here ... ; ))) ) ) ( instance $y_state ( instantiate $y_state_module )) ( instance $y ( instantiate $B ( import " __wizer_state " $y_state ))) ( memory $A_mem ) ( global $A_glob ( mut i32 )) ) ;; State instance for ` $A ` . ( instance $a_state ( instantiate $A_state_module )) ;; The state is now joined with the code . ( instance $a_instance ( instantiate $A ( import " __wizer_state " $a_state ))) ;; And finally we re - export all of our old root ' s exports .
implementation
To implement this transformation, we first do a pre-order walk of the
module tree and emit the code modules as a flat sequence. Why a flat
sequence. The code modules cannot contain nested instantiations, because
nested instantiations are state that is not necessarily shared across
all instantiations of the outer module. And if we are already lifting
out nested instantiations, we need to also make nested modules available
for those lifted instantiations, and the easiest way to do that is to
flatten the code module tree (as opposed to re-exporting the nested
modules under well-known symbols). The pre-order traversal ensures that
the `Module::id` we assigned during the instrumentation phase matches
the module's place in the index space.

The state modules, however, remain a nested tree, and we emit them in a
traversal of the `Snapshot` instance tree. We can do this because,
unlike code modules, each state module is only instantiated exactly
once. The instantiations' references to nested modules become outer
aliases pointing to the module's position in the parent's flat sequence
of nested modules.
To implement this transformation we first do a pre - order walk of the module tree and emit the code modules as a flat sequence . Why a flat sequence . The code modules cannot contain nested instantiations because nested instantiations are state that is not necessarily shared across all instantiations of the outer module . And if we are already lifting out nested instantiations we need to also make nested modules available for those lifted instantiations and the easiest way to do that is to flatten the code module tree ( as opposed to re - exporting the nested modules under well - known symbols ) . The pre - order traversal ensures that the ` Module :: id ` we assigned during the instrumentation phase matches the module ' s place in the index space . The state modules however remain a nested tree and we emit them in a traversal of the ` Snapshot ` instance tree . We can do this because unlike code modules each state module is only instantiated exactly once . The instantiations ' references to nested modules become outer aliases pointing to the module ' s position in the parent ' s flat sequence of nested modules .