33use {
44 anyhow:: { anyhow, Context , Result } ,
55 convert:: { IntoEntityType , IntoExportKind } ,
6+ module_info:: ModuleInfo ,
67 std:: { borrow:: Cow , collections:: HashSet } ,
78 wasm_encoder:: { CustomSection , ExportSection , ImportSection , Module , RawSection } ,
89 wasmparser:: { Encoding , Parser , Payload } ,
@@ -14,6 +15,7 @@ pub mod bugs;
1415#[ cfg( test) ]
1516mod abi_conformance;
1617mod convert;
18+ mod module_info;
1719
1820const SPIN_ADAPTER : & [ u8 ] = include_bytes ! ( concat!(
1921 env!( "OUT_DIR" ) ,
@@ -51,8 +53,9 @@ pub fn componentize_if_necessary(module_or_component: &[u8]) -> Result<Cow<[u8]>
5153}
5254
5355pub fn componentize ( module : & [ u8 ] ) -> Result < Vec < u8 > > {
54- match WitBindgenVersion :: from_module ( module) ? {
55- WitBindgenVersion :: V0_2 => componentize_old_bindgen ( module) ,
56+ let module_info = ModuleInfo :: from_module ( module) ?;
57+ match WitBindgenVersion :: detect ( & module_info) ? {
58+ WitBindgenVersion :: V0_2OrNone => componentize_old_module ( module, & module_info) ,
5659 WitBindgenVersion :: GreaterThanV0_4 => componentize_new_bindgen ( module) ,
5760 WitBindgenVersion :: Other ( other) => Err ( anyhow:: anyhow!(
5861 "cannot adapt modules created with wit-bindgen version {other}"
@@ -65,40 +68,36 @@ pub fn componentize(module: &[u8]) -> Result<Vec<u8>> {
6568#[ derive( Debug ) ]
6669enum WitBindgenVersion {
6770 GreaterThanV0_4 ,
68- V0_2 ,
71+ V0_2OrNone ,
6972 Other ( String ) ,
7073}
7174
7275impl WitBindgenVersion {
73- fn from_module ( module : & [ u8 ] ) -> Result < Self > {
74- let ( _, bindgen) = metadata:: decode ( module) ?;
75- if let Some ( producers) = bindgen. producers {
76- if let Some ( processors) = producers. get ( "processed-by" ) {
77- let bindgen_version = processors. iter ( ) . find_map ( |( key, value) | {
78- key. starts_with ( "wit-bindgen" ) . then_some ( value. as_str ( ) )
79- } ) ;
80- if let Some ( v) = bindgen_version {
81- let mut parts = v. split ( '.' ) ;
82- let Some ( major) = parts. next ( ) . and_then ( |p| p. parse :: < u8 > ( ) . ok ( ) ) else {
83- return Ok ( Self :: Other ( v. to_owned ( ) ) ) ;
84- } ;
85- let Some ( minor) = parts. next ( ) . and_then ( |p| p. parse :: < u8 > ( ) . ok ( ) ) else {
86- return Ok ( Self :: Other ( v. to_owned ( ) ) ) ;
87- } ;
88- if ( major == 0 && minor < 5 ) || major >= 1 {
89- return Ok ( Self :: Other ( v. to_owned ( ) ) ) ;
90- }
91- // Either there should be no patch version or nothing after patch
92- if parts. next ( ) . is_none ( ) || parts. next ( ) . is_none ( ) {
93- return Ok ( Self :: GreaterThanV0_4 ) ;
94- } else {
95- return Ok ( Self :: Other ( v. to_owned ( ) ) ) ;
96- }
76+ fn detect ( module_info : & ModuleInfo ) -> Result < Self > {
77+ if let Some ( processors) = module_info. bindgen_processors ( ) {
78+ let bindgen_version = processors
79+ . iter ( )
80+ . find_map ( |( key, value) | key. starts_with ( "wit-bindgen" ) . then_some ( value. as_str ( ) ) ) ;
81+ if let Some ( v) = bindgen_version {
82+ let mut parts = v. split ( '.' ) ;
83+ let Some ( major) = parts. next ( ) . and_then ( |p| p. parse :: < u8 > ( ) . ok ( ) ) else {
84+ return Ok ( Self :: Other ( v. to_owned ( ) ) ) ;
85+ } ;
86+ let Some ( minor) = parts. next ( ) . and_then ( |p| p. parse :: < u8 > ( ) . ok ( ) ) else {
87+ return Ok ( Self :: Other ( v. to_owned ( ) ) ) ;
88+ } ;
89+ if ( major == 0 && minor < 5 ) || major >= 1 {
90+ return Ok ( Self :: Other ( v. to_owned ( ) ) ) ;
91+ }
92+ // Either there should be no patch version or nothing after patch
93+ if parts. next ( ) . is_none ( ) || parts. next ( ) . is_none ( ) {
94+ return Ok ( Self :: GreaterThanV0_4 ) ;
95+ } else {
96+ return Ok ( Self :: Other ( v. to_owned ( ) ) ) ;
9797 }
9898 }
9999 }
100-
101- Ok ( Self :: V0_2 )
100+ Ok ( Self :: V0_2OrNone )
102101 }
103102}
104103
@@ -111,6 +110,17 @@ pub fn componentize_new_bindgen(module: &[u8]) -> Result<Vec<u8>> {
111110 . encode ( )
112111}
113112
113+ /// Modules *not* produced with wit-bindgen >= 0.5 could be old wit-bindgen or no wit-bindgen
114+ pub fn componentize_old_module ( module : & [ u8 ] , module_info : & ModuleInfo ) -> Result < Vec < u8 > > {
115+ // If the module has a _start export and doesn't obviously use wit-bindgen
116+ // it is likely an old p1 command module.
117+ if module_info. has_start_export && !module_info. probably_uses_wit_bindgen ( ) {
118+ componentize_command ( module)
119+ } else {
120+ componentize_old_bindgen ( module)
121+ }
122+ }
123+
114124/// Modules produced with wit-bindgen 0.2 need more extensive adaption
115125pub fn componentize_old_bindgen ( module : & [ u8 ] ) -> Result < Vec < u8 > > {
116126 let ( module, exports) = retarget_imports_and_get_exports ( ADAPTER_NAME , module) ?;
0 commit comments