@@ -631,6 +631,8 @@ impl<'a> EncodingState<'a> {
631
631
self . instantiate_adapter_module ( & shims, name, adapter) ;
632
632
}
633
633
634
+ self . encode_initialize_with_start ( ) ?;
635
+
634
636
Ok ( ( ) )
635
637
}
636
638
@@ -1689,6 +1691,60 @@ impl<'a> EncodingState<'a> {
1689
1691
} ) ;
1690
1692
self . adapter_import_reallocs . insert ( name, realloc) ;
1691
1693
}
1694
+
1695
+ /// Generates component bits that are responsible for executing
1696
+ /// `_initialize`, if found, in the original component.
1697
+ ///
1698
+ /// The `_initialize` function was a part of WASIp1 where it generally is
1699
+ /// intended to run after imports and memory and such are all "hooked up"
1700
+ /// and performs other various initialization tasks. This is additionally
1701
+ /// specified in https://github.com/WebAssembly/component-model/pull/378
1702
+ /// to be part of the component model lowerings as well.
1703
+ ///
1704
+ /// This implements this functionality by encoding a core module that
1705
+ /// imports a function and then registers a `start` section with that
1706
+ /// imported function. This is all encoded after the
1707
+ /// imports/lowerings/tables/etc are all filled in above meaning that this
1708
+ /// is the last piece to run. That means that when this is running
1709
+ /// everything should be hooked up for all imported functions to work.
1710
+ ///
1711
+ /// Note that at this time `_initialize` is only detected in the "main
1712
+ /// module", not adapters/libraries.
1713
+ fn encode_initialize_with_start ( & mut self ) -> Result < ( ) > {
1714
+ let initialize = match self . info . info . initialize {
1715
+ Some ( name) => name,
1716
+ // If this core module didn't have `_initialize` or similar, then
1717
+ // there's nothing to do here.
1718
+ None => return Ok ( ( ) ) ,
1719
+ } ;
1720
+ let initialize_index = self . component . alias_core_export (
1721
+ self . instance_index . unwrap ( ) ,
1722
+ initialize,
1723
+ ExportKind :: Func ,
1724
+ ) ;
1725
+ let mut shim = Module :: default ( ) ;
1726
+ let mut section = TypeSection :: new ( ) ;
1727
+ section. function ( [ ] , [ ] ) ;
1728
+ shim. section ( & section) ;
1729
+ let mut section = ImportSection :: new ( ) ;
1730
+ section. import ( "" , "" , EntityType :: Function ( 0 ) ) ;
1731
+ shim. section ( & section) ;
1732
+ shim. section ( & StartSection { function_index : 0 } ) ;
1733
+
1734
+ // Declare the core module within the component, create a dummy core
1735
+ // instance with one export of our `_initialize` function, and then use
1736
+ // that to instantiate the module we emit to run the `start` function in
1737
+ // core wasm to run `_initialize`.
1738
+ let shim_module_index = self . component . core_module ( & shim) ;
1739
+ let shim_args_instance_index =
1740
+ self . component
1741
+ . core_instantiate_exports ( [ ( "" , ExportKind :: Func , initialize_index) ] ) ;
1742
+ self . component . core_instantiate (
1743
+ shim_module_index,
1744
+ [ ( "" , ModuleArg :: Instance ( shim_args_instance_index) ) ] ,
1745
+ ) ;
1746
+ Ok ( ( ) )
1747
+ }
1692
1748
}
1693
1749
1694
1750
/// A list of "shims" which start out during the component instantiation process
0 commit comments