@@ -1057,6 +1057,9 @@ impl<'a> DInterfaceGenerator<'a> {
10571057 _ => false ,
10581058 } ;
10591059
1060+ res. post_return = self . direction == Some ( Direction :: Export )
1061+ && abi:: guest_export_needs_post_return ( self . resolve , func) ;
1062+
10601063 res. result
10611064 . push_str ( & ( self . optional_type_name ( func. result . as_ref ( ) , self . fqn ) ) ) ;
10621065
@@ -1296,23 +1299,21 @@ impl<'a> DInterfaceGenerator<'a> {
12961299 }
12971300 }
12981301
1302+ let core_module_name = self . name . map ( |s| self . resolve . name_world_key ( s) ) ;
1303+ let export_name = func. legacy_core_export_name ( core_module_name. as_deref ( ) ) ;
1304+
12991305 self . src . push_str ( "/// ditto\n " ) ;
1300- self . src . push_str ( & format ! (
1301- "@wasmExport!(\" {}#{}\" )\n " ,
1302- self . wasm_import_module. unwrap( ) ,
1303- func. name
1304- ) ) ;
1306+ self . src
1307+ . push_str ( & format ! ( "@wasmExport!(\" {export_name}\" )\n " ) ) ;
13051308
13061309 self . src . push_str ( & format ! (
1307- "pragma(mangle, \" __wit_export_{}__{}\" )\n " ,
1308- self . wasm_import_module
1309- . unwrap( )
1310+ "pragma(mangle, \" __wit_export_{}\" )\n " ,
1311+ export_name
13101312 . replace( "/" , "__" )
1311- . replace( "-" , "_" ) ,
1312- func. name
13131313 . replace( "-" , "_" )
13141314 . replace( "[" , ":" )
13151315 . replace( "]" , ":" )
1316+ . replace( "#" , "::" )
13161317 ) ) ;
13171318
13181319 if d_sig. implicit_self || d_sig. static_member {
@@ -1362,6 +1363,68 @@ impl<'a> DInterfaceGenerator<'a> {
13621363 self . src . push_str ( & src. to_string ( ) ) ;
13631364
13641365 self . src . push_str ( "}\n " ) ;
1366+
1367+ if abi:: guest_export_needs_post_return ( self . resolve , func) {
1368+ let mut param_data = Vec :: new ( ) ;
1369+ let mut params = Vec :: < & str > :: new ( ) ;
1370+
1371+ for ( arg, _ty) in wasm_sig. results . iter ( ) . enumerate ( ) {
1372+ param_data. push ( format ! ( "arg{arg}" ) ) ;
1373+ }
1374+ for param in & param_data {
1375+ params. push ( & param) ;
1376+ }
1377+
1378+ self . src
1379+ . push_str ( & format ! ( "@wasmExport!(\" cabi_post_{export_name}\" )\n " ) ) ;
1380+
1381+ self . src . push_str ( & format ! (
1382+ "pragma(mangle, \" __wit_cabi_post_{}\" )\n " ,
1383+ export_name
1384+ . replace( "/" , "__" )
1385+ . replace( "-" , "_" )
1386+ . replace( "[" , ":" )
1387+ . replace( "]" , ":" )
1388+ . replace( "#" , "::" )
1389+ ) ) ;
1390+
1391+ if d_sig. implicit_self || d_sig. static_member {
1392+ self . src . push_str ( "static " ) ;
1393+ }
1394+ self . src . push_str ( & format ! (
1395+ "private extern(C) void __cabi_post_{}({}) {{\n " ,
1396+ d_sig. name,
1397+ wasm_sig
1398+ . results
1399+ . iter( )
1400+ . zip( & params)
1401+ . map( |( ty, name) | format!( "{} {name}" , wasm_type( * ty) ) )
1402+ . collect:: <Vec <String >>( )
1403+ . join( ", " )
1404+ ) ) ;
1405+
1406+ let mut f = FunctionBindgen :: new ( self , & params) ;
1407+ abi:: post_return ( f. r#gen . resolve , func, & mut f) ;
1408+
1409+ let ret_area_decl = f. emit_ret_area_if_needed ( ) ;
1410+
1411+ let FunctionBindgen {
1412+ src,
1413+ return_pointer_area_size,
1414+ return_pointer_area_align,
1415+ ..
1416+ } = f;
1417+ self . return_pointer_area_size =
1418+ self . return_pointer_area_size . max ( return_pointer_area_size) ;
1419+ self . return_pointer_area_align = self
1420+ . return_pointer_area_align
1421+ . max ( return_pointer_area_align) ;
1422+
1423+ self . src . push_str ( & ret_area_decl) ;
1424+ self . src . push_str ( & src. to_string ( ) ) ;
1425+
1426+ self . src . push_str ( "}\n " ) ;
1427+ }
13651428 }
13661429
13671430 fn emit_ret_area_if_needed ( & self ) -> String {
@@ -1615,10 +1678,10 @@ impl<'a> InterfaceGenerator<'a> for DInterfaceGenerator<'a> {
16151678
16161679 self . src . push_str ( & format ! (
16171680 "struct Borrow {{
1618- package(wit) void* __ptr = null ;
1681+ package(wit) uint __handle = 0 ;
16191682
1620- package(wit) this(void* ptr ) {{
1621- __ptr = ptr ;
1683+ package(wit) this(uint handle ) {{
1684+ __handle = handle ;
16221685 }}
16231686
16241687 @disable this();
@@ -2861,16 +2924,57 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
28612924 self . push_str ( & format ! ( "free({});" , operands[ 0 ] ) ) ;
28622925 }
28632926 abi:: Instruction :: GuestDeallocateString { .. } => {
2864- todo ! ( "instr: GuestDeallocateString" ) ;
2865- //self.push_str(&format!("if (({}) > 0) {{\n", operands[1]));
2866- //self.push_str(&format!("free({});", operands[0]));
2867- //self.push_str("}\n");
2927+ self . push_str ( & format ! ( "if ({} > 0) {{\n " , operands[ 1 ] ) ) ;
2928+ self . push_str ( & format ! ( "free({});\n " , operands[ 0 ] ) ) ;
2929+ self . push_str ( "}\n " ) ;
28682930 }
2869- abi:: Instruction :: GuestDeallocateList { .. } => {
2870- todo ! ( "instr: GuestDeallocateList" )
2931+ abi:: Instruction :: GuestDeallocateList { element } => {
2932+ let Block {
2933+ body,
2934+ results : block_results,
2935+ element : block_element,
2936+ base,
2937+ } = self . blocks . pop ( ) . unwrap ( ) ;
2938+ let tmp = self . tmp ( ) ;
2939+ let size = self . r#gen . sizes . size ( element) ;
2940+ let size_str = size. format ( "size_t.sizeof" ) ;
2941+
2942+ let list = tempname ( "_list" , tmp) ;
2943+ let list_len = tempname ( "_listLen" , tmp) ;
2944+ let list_src = tempname ( "_listSrcPtr" , tmp) ;
2945+ self . push_str ( & format ! ( "auto {list_src} = {};\n " , operands[ 0 ] ) ) ;
2946+ self . push_str ( & format ! ( "auto {list_len} = {};\n " , operands[ 1 ] ) ) ;
2947+
2948+ self . push_str ( & format ! (
2949+ "foreach ({block_element}_idx; 0..{list_len}) {{\n " ,
2950+ ) ) ;
2951+ self . push_str ( & format ! (
2952+ "const auto {base} = {list_src} + {block_element}_idx * {size_str};\n "
2953+ ) ) ;
2954+ self . push_str ( & body) ;
2955+ self . push_str ( "\n }\n " ) ;
2956+
2957+ self . push_str ( & format ! ( "if ({} > 0) {{\n " , operands[ 1 ] ) ) ;
2958+ self . push_str ( & format ! ( "free({});\n " , operands[ 0 ] ) ) ;
2959+ self . push_str ( "}\n " ) ;
28712960 }
2872- abi:: Instruction :: GuestDeallocateVariant { .. } => {
2873- todo ! ( "instr: GuestDeallocateVariant" )
2961+ abi:: Instruction :: GuestDeallocateVariant {
2962+ blocks : block_count,
2963+ } => {
2964+ let blocks = self
2965+ . blocks
2966+ . drain ( self . blocks . len ( ) - block_count..)
2967+ . collect :: < Vec < _ > > ( ) ;
2968+
2969+ self . push_str ( & format ! ( "switch ({}) {{\n " , operands[ 0 ] ) ) ;
2970+ for ( i, block) in blocks. into_iter ( ) . enumerate ( ) {
2971+ assert ! ( results. is_empty( ) ) ;
2972+
2973+ self . push_str ( & format ! ( "case {}: {{\n " , i) ) ;
2974+ self . src . push_str ( & block. body ) ;
2975+ self . src . push_str ( "break;\n }\n " ) ;
2976+ }
2977+ self . src . push_str ( "default: break;\n }\n " ) ;
28742978 }
28752979 abi:: Instruction :: DropHandle { .. } => {
28762980 todo ! ( "instr: DropHandle" )
0 commit comments