@@ -225,6 +225,148 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
225
225
226
226
results. push ( lifted) ;
227
227
}
228
+
229
+ fn handle_result_import ( & mut self , operands : & mut Vec < String > ) {
230
+ if self . interface_gen . csharp_gen . opts . with_wit_results {
231
+ uwriteln ! ( self . src, "return {};" , operands[ 0 ] ) ;
232
+ return ;
233
+ }
234
+
235
+ let mut payload_is_void = false ;
236
+ let mut previous = operands[ 0 ] . clone ( ) ;
237
+ let mut vars: Vec < ( String , Option < String > ) > = Vec :: with_capacity ( self . results . len ( ) ) ;
238
+ if let Direction :: Import = self . interface_gen . direction {
239
+ for ty in & self . results {
240
+ let tmp = self . locals . tmp ( "tmp" ) ;
241
+ uwrite ! (
242
+ self . src,
243
+ "\
244
+ if ({previous}.IsOk)
245
+ {{
246
+ var {tmp} = {previous}.AsOk;
247
+ "
248
+ ) ;
249
+ let TypeDefKind :: Result ( result) = & self . interface_gen . resolve . types [ * ty] . kind
250
+ else {
251
+ unreachable ! ( ) ;
252
+ } ;
253
+ let exception_name = result
254
+ . err
255
+ . map ( |ty| self . interface_gen . type_name_with_qualifier ( & ty, true ) ) ;
256
+ vars. push ( ( previous. clone ( ) , exception_name) ) ;
257
+ payload_is_void = result. ok . is_none ( ) ;
258
+ previous = tmp;
259
+ }
260
+ }
261
+ uwriteln ! (
262
+ self . src,
263
+ "return {};" ,
264
+ if payload_is_void { "" } else { & previous }
265
+ ) ;
266
+ for ( level, var) in vars. iter ( ) . enumerate ( ) . rev ( ) {
267
+ self . interface_gen . csharp_gen . needs_wit_exception = true ;
268
+ let ( var_name, exception_name) = var;
269
+ let exception_name = match exception_name {
270
+ Some ( type_name) => & format ! ( "WitException<{}>" , type_name) ,
271
+ None => "WitException" ,
272
+ } ;
273
+ uwrite ! (
274
+ self . src,
275
+ "\
276
+ }}
277
+ else
278
+ {{
279
+ throw new {exception_name}({var_name}.AsErr!, {level});
280
+ }}
281
+ "
282
+ ) ;
283
+ }
284
+ }
285
+
286
+ fn handle_result_call (
287
+ & mut self ,
288
+ func : & & wit_parser:: Function ,
289
+ target : String ,
290
+ func_name : String ,
291
+ oper : String ,
292
+ ) -> String {
293
+ let ret = self . locals . tmp ( "ret" ) ;
294
+ if self . interface_gen . csharp_gen . opts . with_wit_results {
295
+ uwriteln ! ( self . src, "var {ret} = {target}.{func_name}({oper});" ) ;
296
+ return ret;
297
+ }
298
+
299
+ // otherwise generate exception code
300
+ let ty = self
301
+ . interface_gen
302
+ . type_name_with_qualifier ( func. results . iter_types ( ) . next ( ) . unwrap ( ) , true ) ;
303
+ uwriteln ! ( self . src, "{ty} {ret};" ) ;
304
+ let mut cases = Vec :: with_capacity ( self . results . len ( ) ) ;
305
+ let mut oks = Vec :: with_capacity ( self . results . len ( ) ) ;
306
+ let mut payload_is_void = false ;
307
+ for ( index, ty) in self . results . iter ( ) . enumerate ( ) {
308
+ let TypeDefKind :: Result ( result) = & self . interface_gen . resolve . types [ * ty] . kind else {
309
+ unreachable ! ( ) ;
310
+ } ;
311
+ let err_ty = if let Some ( ty) = result. err {
312
+ self . interface_gen . type_name_with_qualifier ( & ty, true )
313
+ } else {
314
+ "None" . to_owned ( )
315
+ } ;
316
+ let ty = self
317
+ . interface_gen
318
+ . type_name_with_qualifier ( & Type :: Id ( * ty) , true ) ;
319
+ let head = oks. concat ( ) ;
320
+ let tail = oks. iter ( ) . map ( |_| ")" ) . collect :: < Vec < _ > > ( ) . concat ( ) ;
321
+ cases. push ( format ! (
322
+ "\
323
+ case {index}:
324
+ {{
325
+ ret = {head}{ty}.Err(({err_ty}) e.Value){tail};
326
+ break;
327
+ }}
328
+ "
329
+ ) ) ;
330
+ oks. push ( format ! ( "{ty}.Ok(" ) ) ;
331
+ payload_is_void = result. ok . is_none ( ) ;
332
+ }
333
+ if !self . results . is_empty ( ) {
334
+ self . src . push_str (
335
+ "
336
+ try
337
+ {\n
338
+ " ,
339
+ ) ;
340
+ }
341
+ let head = oks. concat ( ) ;
342
+ let tail = oks. iter ( ) . map ( |_| ")" ) . collect :: < Vec < _ > > ( ) . concat ( ) ;
343
+ let val = if payload_is_void {
344
+ uwriteln ! ( self . src, "{target}.{func_name}({oper});" ) ;
345
+ "new None()" . to_owned ( )
346
+ } else {
347
+ format ! ( "{target}.{func_name}({oper})" )
348
+ } ;
349
+ uwriteln ! ( self . src, "{ret} = {head}{val}{tail};" ) ;
350
+ if !self . results . is_empty ( ) {
351
+ self . interface_gen . csharp_gen . needs_wit_exception = true ;
352
+ let cases = cases. join ( "\n " ) ;
353
+ uwriteln ! (
354
+ self . src,
355
+ r#"}}
356
+ catch (WitException e)
357
+ {{
358
+ switch (e.NestingLevel)
359
+ {{
360
+ {cases}
361
+
362
+ default: throw new ArgumentException($"invalid nesting level: {{e.NestingLevel}}");
363
+ }}
364
+ }}
365
+ "#
366
+ ) ;
367
+ }
368
+ ret
369
+ }
228
370
}
229
371
230
372
impl Bindgen for FunctionBindgen < ' _ , ' _ > {
@@ -814,70 +956,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
814
956
match func. results . len ( ) {
815
957
0 => uwriteln ! ( self . src, "{target}.{func_name}({oper});" ) ,
816
958
1 => {
817
- let ret = self . locals . tmp ( "ret" ) ;
818
- let ty = self . interface_gen . type_name_with_qualifier (
819
- func. results . iter_types ( ) . next ( ) . unwrap ( ) ,
820
- true
821
- ) ;
822
- uwriteln ! ( self . src, "{ty} {ret};" ) ;
823
- let mut cases = Vec :: with_capacity ( self . results . len ( ) ) ;
824
- let mut oks = Vec :: with_capacity ( self . results . len ( ) ) ;
825
- let mut payload_is_void = false ;
826
- for ( index, ty) in self . results . iter ( ) . enumerate ( ) {
827
- let TypeDefKind :: Result ( result) = & self . interface_gen . resolve . types [ * ty] . kind else {
828
- unreachable ! ( ) ;
829
- } ;
830
- let err_ty = if let Some ( ty) = result. err {
831
- self . interface_gen . type_name_with_qualifier ( & ty, true )
832
- } else {
833
- "None" . to_owned ( )
834
- } ;
835
- let ty = self . interface_gen . type_name_with_qualifier ( & Type :: Id ( * ty) , true ) ;
836
- let head = oks. concat ( ) ;
837
- let tail = oks. iter ( ) . map ( |_| ")" ) . collect :: < Vec < _ > > ( ) . concat ( ) ;
838
- cases. push (
839
- format ! (
840
- "\
841
- case {index}: {{
842
- ret = {head}{ty}.Err(({err_ty}) e.Value){tail};
843
- break;
844
- }}
845
- "
846
- )
847
- ) ;
848
- oks. push ( format ! ( "{ty}.Ok(" ) ) ;
849
- payload_is_void = result. ok . is_none ( ) ;
850
- }
851
- if !self . results . is_empty ( ) {
852
- self . src . push_str ( "try {\n " ) ;
853
- }
854
- let head = oks. concat ( ) ;
855
- let tail = oks. iter ( ) . map ( |_| ")" ) . collect :: < Vec < _ > > ( ) . concat ( ) ;
856
- let val = if payload_is_void {
857
- uwriteln ! ( self . src, "{target}.{func_name}({oper});" ) ;
858
- "new None()" . to_owned ( )
859
- } else {
860
- format ! ( "{target}.{func_name}({oper})" )
861
- } ;
862
- uwriteln ! (
863
- self . src,
864
- "{ret} = {head}{val}{tail};"
865
- ) ;
866
- if !self . results . is_empty ( ) {
867
- self . interface_gen . csharp_gen . needs_wit_exception = true ;
868
- let cases = cases. join ( "\n " ) ;
869
- uwriteln ! (
870
- self . src,
871
- r#"}} catch (WitException e) {{
872
- switch (e.NestingLevel) {{
873
- {cases}
874
-
875
- default: throw new ArgumentException($"invalid nesting level: {{e.NestingLevel}}");
876
- }}
877
- }}
878
- "#
879
- ) ;
880
- }
959
+ let ret = self . handle_result_call ( func, target, func_name, oper) ;
881
960
results. push ( ret) ;
882
961
}
883
962
_ => {
@@ -927,46 +1006,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
927
1006
match func. results . len ( ) {
928
1007
0 => ( ) ,
929
1008
1 => {
930
- let mut payload_is_void = false ;
931
- let mut previous = operands[ 0 ] . clone ( ) ;
932
- let mut vars: Vec < ( String , Option < String > ) > = Vec :: with_capacity ( self . results . len ( ) ) ;
933
- if let Direction :: Import = self . interface_gen . direction {
934
- for ty in & self . results {
935
- let tmp = self . locals . tmp ( "tmp" ) ;
936
- uwrite ! (
937
- self . src,
938
- "\
939
- if ({previous}.IsOk) {{
940
- var {tmp} = {previous}.AsOk;
941
- "
942
- ) ;
943
- let TypeDefKind :: Result ( result) = & self . interface_gen . resolve . types [ * ty] . kind else {
944
- unreachable ! ( ) ;
945
- } ;
946
- let exception_name = result. err
947
- . map ( |ty| self . interface_gen . type_name_with_qualifier ( & ty, true ) ) ;
948
- vars. push ( ( previous. clone ( ) , exception_name) ) ;
949
- payload_is_void = result. ok . is_none ( ) ;
950
- previous = tmp;
951
- }
952
- }
953
- uwriteln ! ( self . src, "return {};" , if payload_is_void { "" } else { & previous } ) ;
954
- for ( level, var) in vars. iter ( ) . enumerate ( ) . rev ( ) {
955
- self . interface_gen . csharp_gen . needs_wit_exception = true ;
956
- let ( var_name, exception_name) = var;
957
- let exception_name = match exception_name {
958
- Some ( type_name) => & format ! ( "WitException<{}>" , type_name) ,
959
- None => "WitException" ,
960
- } ;
961
- uwrite ! (
962
- self . src,
963
- "\
964
- }} else {{
965
- throw new {exception_name}({var_name}.AsErr!, {level});
966
- }}
967
- "
968
- ) ;
969
- }
1009
+ self . handle_result_import ( operands) ;
970
1010
}
971
1011
_ => {
972
1012
let results = operands. join ( ", " ) ;
0 commit comments