@@ -6,7 +6,9 @@ use indexmap::IndexSet;
6
6
use std:: collections:: { HashMap , HashSet } ;
7
7
use std:: fmt:: Write ;
8
8
use 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
+ } ;
10
12
use wit_bindgen_core:: {
11
13
dealias, uwrite, uwriteln, wit_parser:: * , AnonymousTypeGenerator , AsyncFilterSet , Direction ,
12
14
Files , InterfaceGenerator as _, Ns , WorldGenerator ,
@@ -139,12 +141,13 @@ impl Opts {
139
141
}
140
142
}
141
143
142
- #[ derive( Debug , Default ) ]
144
+ #[ derive( Clone , Debug , Default ) ]
143
145
struct Return {
144
146
scalar : Option < Scalar > ,
145
147
retptrs : Vec < Type > ,
146
148
}
147
149
150
+ #[ derive( Clone ) ]
148
151
struct CSig {
149
152
name : String ,
150
153
sig : String ,
@@ -153,7 +156,7 @@ struct CSig {
153
156
retptrs : Vec < String > ,
154
157
}
155
158
156
- #[ derive( Debug ) ]
159
+ #[ derive( Clone , Debug ) ]
157
160
enum Scalar {
158
161
Void ,
159
162
OptionBool ( Type ) ,
@@ -1949,13 +1952,13 @@ impl InterfaceGenerator<'_> {
1949
1952
// Print the public facing signature into the header, and since that's
1950
1953
// what we are defining also print it into the C file.
1951
1954
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_) ;
1953
1956
self . src . c_adapters ( "\n " ) ;
1954
1957
self . src . c_adapters ( & c_sig. sig ) ;
1955
1958
self . src . c_adapters ( " {\n " ) ;
1956
1959
1957
1960
if async_ {
1958
- self . import_body_async ( func, c_sig, & import_name) ;
1961
+ self . import_body_async ( func, c_sig, & sig , & import_name) ;
1959
1962
} else {
1960
1963
self . import_body_sync ( func, c_sig, & import_name) ;
1961
1964
}
@@ -1993,7 +1996,6 @@ impl InterfaceGenerator<'_> {
1993
1996
1994
1997
let mut f = FunctionBindgen :: new ( self , c_sig, & import_name) ;
1995
1998
for ( pointer, param) in f. sig . params . iter ( ) {
1996
- f. locals . insert ( & param) . unwrap ( ) ;
1997
1999
if * pointer {
1998
2000
f. params . push ( format ! ( "*{}" , param) ) ;
1999
2001
} else {
@@ -2034,19 +2036,31 @@ impl InterfaceGenerator<'_> {
2034
2036
self . src . c_adapters ( & String :: from ( src) ) ;
2035
2037
}
2036
2038
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
+ }
2047
2060
uwriteln ! (
2048
2061
self . src. c_adapters,
2049
- "return {import_name}({params}, {results});"
2062
+ "return {import_name}({});" ,
2063
+ params. join( ", " ) ,
2050
2064
) ;
2051
2065
}
2052
2066
@@ -2064,11 +2078,7 @@ impl InterfaceGenerator<'_> {
2064
2078
( AbiVariant :: GuestExport , "" )
2065
2079
} ;
2066
2080
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) ;
2072
2082
2073
2083
self . src . c_fns ( "\n " ) ;
2074
2084
@@ -2077,7 +2087,7 @@ impl InterfaceGenerator<'_> {
2077
2087
2078
2088
// Print the actual header for this function into the header file, and
2079
2089
// 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_) ;
2081
2091
2082
2092
// Generate, in the C source file, the raw wasm signature that has the
2083
2093
// canonical ABI.
@@ -2220,6 +2230,7 @@ void {name}_return({return_ty}) {{
2220
2230
& mut self ,
2221
2231
interface_name : Option < & WorldKey > ,
2222
2232
func : & Function ,
2233
+ sig : & WasmSignature ,
2223
2234
async_ : bool ,
2224
2235
) -> CSig {
2225
2236
let name = self . c_func_name ( interface_name, func) ;
@@ -2259,50 +2270,10 @@ void {name}_return({return_ty}) {{
2259
2270
self . src . h_fns ( " " ) ;
2260
2271
self . src . h_fns ( & name) ;
2261
2272
self . src . h_fns ( "(" ) ;
2262
- let mut params = Vec :: new ( ) ;
2273
+ let params;
2263
2274
let mut retptrs = Vec :: new ( ) ;
2264
2275
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) ;
2306
2277
} else if async_ && !self . in_import {
2307
2278
params = self . print_sig_params ( func) ;
2308
2279
} else {
@@ -2388,6 +2359,72 @@ void {name}_return({return_ty}) {{
2388
2359
params
2389
2360
}
2390
2361
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
+
2391
2428
fn classify_ret ( & mut self , func : & Function ) -> Return {
2392
2429
let mut ret = Return :: default ( ) ;
2393
2430
match & func. result {
@@ -2768,10 +2805,14 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
2768
2805
sig : CSig ,
2769
2806
func_to_call : & ' a str ,
2770
2807
) -> FunctionBindgen < ' a , ' b > {
2808
+ let mut locals = Ns :: default ( ) ;
2809
+ for ( _, name) in sig. params . iter ( ) {
2810
+ locals. insert ( name) . unwrap ( ) ;
2811
+ }
2771
2812
FunctionBindgen {
2772
2813
gen,
2773
2814
sig,
2774
- locals : Default :: default ( ) ,
2815
+ locals,
2775
2816
src : Default :: default ( ) ,
2776
2817
func_to_call,
2777
2818
block_storage : Vec :: new ( ) ,
0 commit comments