@@ -6,7 +6,9 @@ use indexmap::IndexSet;
66use std:: collections:: { HashMap , HashSet } ;
77use std:: fmt:: Write ;
88use std:: mem;
9- use wit_bindgen_core:: abi:: { self , AbiVariant , Bindgen , Bitcast , Instruction , LiftLower , WasmType } ;
9+ use wit_bindgen_core:: abi:: {
10+ self , AbiVariant , Bindgen , Bitcast , Instruction , LiftLower , WasmSignature , WasmType ,
11+ } ;
1012use wit_bindgen_core:: {
1113 dealias, uwrite, uwriteln, wit_parser:: * , AnonymousTypeGenerator , AsyncFilterSet , Direction ,
1214 Files , InterfaceGenerator as _, Ns , WorldGenerator ,
@@ -139,12 +141,13 @@ impl Opts {
139141 }
140142}
141143
142- #[ derive( Debug , Default ) ]
144+ #[ derive( Clone , Debug , Default ) ]
143145struct Return {
144146 scalar : Option < Scalar > ,
145147 retptrs : Vec < Type > ,
146148}
147149
150+ #[ derive( Clone ) ]
148151struct CSig {
149152 name : String ,
150153 sig : String ,
@@ -153,7 +156,7 @@ struct CSig {
153156 retptrs : Vec < String > ,
154157}
155158
156- #[ derive( Debug ) ]
159+ #[ derive( Clone , Debug ) ]
157160enum Scalar {
158161 Void ,
159162 OptionBool ( Type ) ,
@@ -1949,13 +1952,13 @@ impl InterfaceGenerator<'_> {
19491952 // Print the public facing signature into the header, and since that's
19501953 // what we are defining also print it into the C file.
19511954 self . src . h_fns ( "extern " ) ;
1952- let c_sig = self . print_sig ( interface_name, func, async_) ;
1955+ let c_sig = self . print_sig ( interface_name, func, & sig , async_) ;
19531956 self . src . c_adapters ( "\n " ) ;
19541957 self . src . c_adapters ( & c_sig. sig ) ;
19551958 self . src . c_adapters ( " {\n " ) ;
19561959
19571960 if async_ {
1958- self . import_body_async ( func, c_sig, & import_name) ;
1961+ self . import_body_async ( func, c_sig, & sig , & import_name) ;
19591962 } else {
19601963 self . import_body_sync ( func, c_sig, & import_name) ;
19611964 }
@@ -1993,7 +1996,6 @@ impl InterfaceGenerator<'_> {
19931996
19941997 let mut f = FunctionBindgen :: new ( self , c_sig, & import_name) ;
19951998 for ( pointer, param) in f. sig . params . iter ( ) {
1996- f. locals . insert ( & param) . unwrap ( ) ;
19971999 if * pointer {
19982000 f. params . push ( format ! ( "*{}" , param) ) ;
19992001 } else {
@@ -2034,19 +2036,31 @@ impl InterfaceGenerator<'_> {
20342036 self . src . c_adapters ( & String :: from ( src) ) ;
20352037 }
20362038
2037- fn import_body_async ( & mut self , func : & Function , sig : CSig , import_name : & str ) {
2038- let params = match & func. params [ ..] {
2039- [ ] => "NULL" . to_string ( ) ,
2040- _ => format ! ( "(uint8_t*) {}" , sig. params[ 0 ] . 1 ) ,
2041- } ;
2042- let results = match & func. result {
2043- None => "NULL" . to_string ( ) ,
2044- Some ( _) => format ! ( "(uint8_t*) {}" , sig. params. last( ) . unwrap( ) . 1 ) ,
2045- } ;
2046-
2039+ fn import_body_async (
2040+ & mut self ,
2041+ func : & Function ,
2042+ c_sig : CSig ,
2043+ wasm_sig : & WasmSignature ,
2044+ import_name : & str ,
2045+ ) {
2046+ let mut params = Vec :: new ( ) ;
2047+ if wasm_sig. indirect_params {
2048+ params. push ( format ! ( "(uint8_t*) {}" , c_sig. params[ 0 ] . 1 ) ) ;
2049+ } else {
2050+ let mut f = FunctionBindgen :: new ( self , c_sig. clone ( ) , "INVALID" ) ;
2051+ for ( i, ( _, ty) ) in func. params . iter ( ) . enumerate ( ) {
2052+ let param = & c_sig. params [ i] . 1 ;
2053+ params. extend ( abi:: lower_flat ( f. gen . resolve , & mut f, param. clone ( ) , ty) ) ;
2054+ }
2055+ f. gen . src . c_adapters . push_str ( & f. src ) ;
2056+ }
2057+ if func. result . is_some ( ) {
2058+ params. push ( format ! ( "(uint8_t*) {}" , c_sig. params. last( ) . unwrap( ) . 1 ) ) ;
2059+ }
20472060 uwriteln ! (
20482061 self . src. c_adapters,
2049- "return {import_name}({params}, {results});"
2062+ "return {import_name}({});" ,
2063+ params. join( ", " ) ,
20502064 ) ;
20512065 }
20522066
@@ -2064,11 +2078,7 @@ impl InterfaceGenerator<'_> {
20642078 ( AbiVariant :: GuestExport , "" )
20652079 } ;
20662080
2067- let mut sig = self . resolve . wasm_signature ( variant, func) ;
2068- if async_ {
2069- assert_eq ! ( sig. results, [ WasmType :: Pointer ] ) ;
2070- sig. results [ 0 ] = WasmType :: I32 ;
2071- }
2081+ let sig = self . resolve . wasm_signature ( variant, func) ;
20722082
20732083 self . src . c_fns ( "\n " ) ;
20742084
@@ -2077,7 +2087,7 @@ impl InterfaceGenerator<'_> {
20772087
20782088 // Print the actual header for this function into the header file, and
20792089 // it's what we'll be calling.
2080- let h_sig = self . print_sig ( interface_name, func, async_) ;
2090+ let h_sig = self . print_sig ( interface_name, func, & sig , async_) ;
20812091
20822092 // Generate, in the C source file, the raw wasm signature that has the
20832093 // canonical ABI.
@@ -2220,6 +2230,7 @@ void {name}_return({return_ty}) {{
22202230 & mut self ,
22212231 interface_name : Option < & WorldKey > ,
22222232 func : & Function ,
2233+ sig : & WasmSignature ,
22232234 async_ : bool ,
22242235 ) -> CSig {
22252236 let name = self . c_func_name ( interface_name, func) ;
@@ -2259,50 +2270,10 @@ void {name}_return({return_ty}) {{
22592270 self . src . h_fns ( " " ) ;
22602271 self . src . h_fns ( & name) ;
22612272 self . src . h_fns ( "(" ) ;
2262- let mut params = Vec :: new ( ) ;
2273+ let params;
22632274 let mut retptrs = Vec :: new ( ) ;
22642275 if async_ && self . in_import {
2265- let mut printed = false ;
2266- match & func. params [ ..] {
2267- [ ] => { }
2268- [ ( _name, ty) ] => {
2269- printed = true ;
2270- let name = "arg" . to_string ( ) ;
2271- self . print_ty ( SourceType :: HFns , ty) ;
2272- self . src . h_fns ( " *" ) ;
2273- self . src . h_fns ( & name) ;
2274- params. push ( ( true , name) ) ;
2275- }
2276- multiple => {
2277- printed = true ;
2278- let names = multiple
2279- . iter ( )
2280- . map ( |( name, ty) | ( to_c_ident ( name) , self . gen . type_name ( ty) ) )
2281- . collect :: < Vec < _ > > ( ) ;
2282- uwriteln ! ( self . src. h_defs, "typedef struct {name}_args {{" ) ;
2283- for ( name, ty) in names {
2284- uwriteln ! ( self . src. h_defs, "{ty} {name};" ) ;
2285- }
2286- uwriteln ! ( self . src. h_defs, "}} {name}_args_t;" ) ;
2287- uwrite ! ( self . src. h_fns, "{name}_args_t *args" ) ;
2288- params. push ( ( true , "args" . to_string ( ) ) ) ;
2289- }
2290- }
2291- if let Some ( ty) = & func. result {
2292- if printed {
2293- self . src . h_fns ( ", " ) ;
2294- } else {
2295- printed = true ;
2296- }
2297- let name = "result" . to_string ( ) ;
2298- self . print_ty ( SourceType :: HFns , ty) ;
2299- self . src . h_fns ( " *" ) ;
2300- self . src . h_fns ( & name) ;
2301- params. push ( ( true , name) ) ;
2302- }
2303- if !printed {
2304- self . src . h_fns ( "void" ) ;
2305- }
2276+ params = self . print_sig_async_import_params ( & name, func, sig) ;
23062277 } else if async_ && !self . in_import {
23072278 params = self . print_sig_params ( func) ;
23082279 } else {
@@ -2388,6 +2359,72 @@ void {name}_return({return_ty}) {{
23882359 params
23892360 }
23902361
2362+ fn print_sig_async_import_params (
2363+ & mut self ,
2364+ c_func_name : & str ,
2365+ func : & Function ,
2366+ sig : & WasmSignature ,
2367+ ) -> Vec < ( bool , String ) > {
2368+ let mut params = Vec :: new ( ) ;
2369+ let mut printed = false ;
2370+ if sig. indirect_params {
2371+ match & func. params [ ..] {
2372+ [ ] => { }
2373+ [ ( _name, ty) ] => {
2374+ printed = true ;
2375+ let name = "arg" . to_string ( ) ;
2376+ self . print_ty ( SourceType :: HFns , ty) ;
2377+ self . src . h_fns ( " *" ) ;
2378+ self . src . h_fns ( & name) ;
2379+ params. push ( ( true , name) ) ;
2380+ }
2381+ multiple => {
2382+ printed = true ;
2383+ let names = multiple
2384+ . iter ( )
2385+ . map ( |( name, ty) | ( to_c_ident ( name) , self . gen . type_name ( ty) ) )
2386+ . collect :: < Vec < _ > > ( ) ;
2387+ uwriteln ! ( self . src. h_defs, "typedef struct {c_func_name}_args {{" ) ;
2388+ for ( name, ty) in names {
2389+ uwriteln ! ( self . src. h_defs, "{ty} {name};" ) ;
2390+ }
2391+ uwriteln ! ( self . src. h_defs, "}} {c_func_name}_args_t;" ) ;
2392+ uwrite ! ( self . src. h_fns, "{c_func_name}_args_t *args" ) ;
2393+ params. push ( ( true , "args" . to_string ( ) ) ) ;
2394+ }
2395+ }
2396+ } else {
2397+ for ( name, ty) in func. params . iter ( ) {
2398+ let name = to_c_ident ( name) ;
2399+ if printed {
2400+ self . src . h_fns ( ", " ) ;
2401+ } else {
2402+ printed = true ;
2403+ }
2404+ self . print_ty ( SourceType :: HFns , ty) ;
2405+ self . src . h_fns ( " " ) ;
2406+ self . src . h_fns ( & name) ;
2407+ params. push ( ( false , name) ) ;
2408+ }
2409+ }
2410+ if let Some ( ty) = & func. result {
2411+ if printed {
2412+ self . src . h_fns ( ", " ) ;
2413+ } else {
2414+ printed = true ;
2415+ }
2416+ let name = "result" . to_string ( ) ;
2417+ self . print_ty ( SourceType :: HFns , ty) ;
2418+ self . src . h_fns ( " *" ) ;
2419+ self . src . h_fns ( & name) ;
2420+ params. push ( ( true , name) ) ;
2421+ }
2422+ if !printed {
2423+ self . src . h_fns ( "void" ) ;
2424+ }
2425+ params
2426+ }
2427+
23912428 fn classify_ret ( & mut self , func : & Function ) -> Return {
23922429 let mut ret = Return :: default ( ) ;
23932430 match & func. result {
@@ -2768,10 +2805,14 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
27682805 sig : CSig ,
27692806 func_to_call : & ' a str ,
27702807 ) -> FunctionBindgen < ' a , ' b > {
2808+ let mut locals = Ns :: default ( ) ;
2809+ for ( _, name) in sig. params . iter ( ) {
2810+ locals. insert ( name) . unwrap ( ) ;
2811+ }
27712812 FunctionBindgen {
27722813 gen,
27732814 sig,
2774- locals : Default :: default ( ) ,
2815+ locals,
27752816 src : Default :: default ( ) ,
27762817 func_to_call,
27772818 block_storage : Vec :: new ( ) ,
0 commit comments