@@ -591,13 +591,14 @@ impl WorldGenerator for Cpp {
591591
592592 fn import_types (
593593 & mut self ,
594- _resolve : & Resolve ,
594+ resolve : & Resolve ,
595595 _world : WorldId ,
596596 types : & [ ( & str , TypeId ) ] ,
597597 _files : & mut Files ,
598598 ) {
599- for i in types. iter ( ) {
600- uwriteln ! ( self . h_src. src, "// import_type {}" , i. 0 ) ;
599+ let mut gen = self . interface ( resolve, None , true , Some ( "$root" . to_string ( ) ) ) ;
600+ for ( name, id) in types. iter ( ) {
601+ gen. define_type ( name, * id) ;
601602 }
602603 }
603604
@@ -973,6 +974,8 @@ impl CppInterfaceGenerator<'_> {
973974 Some ( ref module_name) => make_external_symbol ( module_name, & func_name, symbol_variant) ,
974975 None => make_external_component ( & func_name) ,
975976 } ;
977+ // Add prefix to C ABI export functions to avoid conflicts with C++ namespaces
978+ self . gen . c_src . src . push_str ( "__wasm_export_" ) ;
976979 if let Some ( prefix) = self . gen . opts . export_prefix . as_ref ( ) {
977980 self . gen . c_src . src . push_str ( prefix) ;
978981 }
@@ -1335,7 +1338,8 @@ impl CppInterfaceGenerator<'_> {
13351338 f. needs_dealloc = needs_dealloc;
13361339 f. cabi_post = None ;
13371340 abi:: call ( f. gen . resolve , variant, lift_lower, func, & mut f, false ) ;
1338- let code = String :: from ( f. src ) ;
1341+ let ret_area_decl = f. emit_ret_area_if_needed ( ) ;
1342+ let code = format ! ( "{}{}" , ret_area_decl, String :: from( f. src) ) ;
13391343 self . gen . c_src . src . push_str ( & code) ;
13401344 }
13411345 }
@@ -1379,8 +1383,9 @@ impl CppInterfaceGenerator<'_> {
13791383 let mut f = FunctionBindgen :: new ( self , params. clone ( ) ) ;
13801384 f. params = params;
13811385 abi:: post_return ( f. gen . resolve , func, & mut f) ;
1382- let FunctionBindgen { src, .. } = f;
1383- self . gen . c_src . src . push_str ( & src) ;
1386+ let ret_area_decl = f. emit_ret_area_if_needed ( ) ;
1387+ let code = format ! ( "{}{}" , ret_area_decl, String :: from( f. src) ) ;
1388+ self . gen . c_src . src . push_str ( & code) ;
13841389 self . gen . c_src . src . push_str ( "}\n " ) ;
13851390 }
13861391 }
@@ -1636,7 +1641,8 @@ impl CppInterfaceGenerator<'_> {
16361641 result : & str ,
16371642 variant : AbiVariant ,
16381643 ) -> ( String , String ) {
1639- let extern_name = make_external_symbol ( module_name, name, variant) ;
1644+ let mut extern_name = String :: from ( "__wasm_import_" ) ;
1645+ extern_name. push_str ( & make_external_symbol ( module_name, name, variant) ) ;
16401646 let import = format ! ( "extern \" C\" __attribute__((import_module(\" {module_name}\" )))\n __attribute__((import_name(\" {name}\" )))\n {result} {extern_name}({args});\n " )
16411647 ;
16421648 ( extern_name, import)
@@ -2103,6 +2109,8 @@ struct FunctionBindgen<'a, 'b> {
21032109 cabi_post : Option < CabiPostInformation > ,
21042110 needs_dealloc : bool ,
21052111 leak_on_insertion : Option < String > ,
2112+ return_pointer_area_size : ArchitectureSize ,
2113+ return_pointer_area_align : Alignment ,
21062114}
21072115
21082116impl < ' a , ' b > FunctionBindgen < ' a , ' b > {
@@ -2120,6 +2128,8 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
21202128 cabi_post : None ,
21212129 needs_dealloc : false ,
21222130 leak_on_insertion : None ,
2131+ return_pointer_area_size : Default :: default ( ) ,
2132+ return_pointer_area_align : Default :: default ( ) ,
21232133 }
21242134 }
21252135
@@ -2191,6 +2201,47 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
21912201 operands[ 0 ]
21922202 ) ;
21932203 }
2204+
2205+ /// Emits a shared return area declaration if needed by this function.
2206+ ///
2207+ /// During code generation, `return_pointer()` may be called multiple times for:
2208+ /// - Indirect parameter storage (when too many/large params)
2209+ /// - Return value storage (when return type is too large)
2210+ ///
2211+ /// **Safety:** This is safe because return pointers are used sequentially:
2212+ /// 1. Parameter marshaling (before call)
2213+ /// 2. Function execution
2214+ /// 3. Return value unmarshaling (after call)
2215+ ///
2216+ /// The scratch space is reused but never accessed simultaneously.
2217+ fn emit_ret_area_if_needed ( & self ) -> String {
2218+ if !self . return_pointer_area_size . is_empty ( ) {
2219+ let size_string = self
2220+ . return_pointer_area_size
2221+ . format ( POINTER_SIZE_EXPRESSION ) ;
2222+ let tp = match self . return_pointer_area_align {
2223+ Alignment :: Bytes ( bytes) => match bytes. get ( ) {
2224+ 1 => "uint8_t" ,
2225+ 2 => "uint16_t" ,
2226+ 4 => "uint32_t" ,
2227+ 8 => "uint64_t" ,
2228+ // Fallback to uint8_t for unusual alignments (e.g., 16-byte SIMD).
2229+ // This is safe: the size calculation ensures correct buffer size,
2230+ // and uint8_t arrays can store any data regardless of alignment.
2231+ _ => "uint8_t" ,
2232+ } ,
2233+ Alignment :: Pointer => "uintptr_t" ,
2234+ } ;
2235+ let static_var = if self . gen . in_guest_import {
2236+ ""
2237+ } else {
2238+ "static "
2239+ } ;
2240+ format ! ( "{static_var}{tp} ret_area[({size_string}+sizeof({tp})-1)/sizeof({tp})];\n " )
2241+ } else {
2242+ String :: new ( )
2243+ }
2244+ }
21942245}
21952246
21962247fn move_if_necessary ( arg : & str ) -> String {
@@ -2502,14 +2553,25 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
25022553 results. push ( result) ;
25032554 }
25042555 abi:: Instruction :: HandleLower {
2505- handle : Handle :: Own ( _ty ) ,
2556+ handle : Handle :: Own ( ty ) ,
25062557 ..
25072558 } => {
25082559 let op = & operands[ 0 ] ;
2509- if matches ! ( self . variant, AbiVariant :: GuestImport ) {
2510- results. push ( format ! ( "{op}.into_handle()" ) ) ;
2511- } else {
2560+
2561+ // Check if this is an imported or exported resource
2562+ let resource_ty = & self . gen . resolve . types [ * ty] ;
2563+ let resource_ty = match & resource_ty. kind {
2564+ TypeDefKind :: Type ( Type :: Id ( id) ) => & self . gen . resolve . types [ * id] ,
2565+ _ => resource_ty,
2566+ } ;
2567+ let is_exported = self . gen . is_exported_type ( resource_ty) ;
2568+
2569+ if is_exported {
2570+ // Exported resources use .release()->handle
25122571 results. push ( format ! ( "{op}.release()->handle" ) ) ;
2572+ } else {
2573+ // Imported resources use .into_handle()
2574+ results. push ( format ! ( "{op}.into_handle()" ) ) ;
25132575 }
25142576 }
25152577 abi:: Instruction :: HandleLower {
@@ -2633,7 +2695,13 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
26332695 . join ( ", " ) ,
26342696 ) ;
26352697 self . src . push_str ( ">(" ) ;
2636- self . src . push_str ( & operands. join ( ", " ) ) ;
2698+ self . src . push_str (
2699+ & operands
2700+ . iter ( )
2701+ . map ( |op| move_if_necessary ( op) )
2702+ . collect :: < Vec < _ > > ( )
2703+ . join ( ", " ) ,
2704+ ) ;
26372705 self . src . push_str ( ");\n " ) ;
26382706 results. push ( format ! ( "std::move({name})" ) ) ;
26392707 }
@@ -2715,14 +2783,12 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
27152783 variant. cases . iter ( ) . zip ( blocks) . zip ( payloads) . enumerate ( )
27162784 {
27172785 uwriteln ! ( self . src, "case {}: {{" , i) ;
2718- if let Some ( ty) = case. ty . as_ref ( ) {
2719- let ty = self . gen . type_name ( ty, & self . namespace , Flavor :: InStruct ) ;
2786+ if case. ty . is_some ( ) {
27202787 let case =
27212788 format ! ( "{elem_ns}::{}" , to_c_ident( & case. name) . to_pascal_case( ) ) ;
27222789 uwriteln ! (
27232790 self . src,
2724- "{} &{} = std::get<{case}>({}.variants).value;" ,
2725- ty,
2791+ "auto& {} = std::get<{case}>({}.variants).value;" ,
27262792 payload,
27272793 operands[ 0 ] ,
27282794 ) ;
@@ -2998,7 +3064,13 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
29983064 }
29993065 self . src . push_str ( & func) ;
30003066 self . src . push_str ( "(" ) ;
3001- self . src . push_str ( & operands. join ( ", " ) ) ;
3067+ self . src . push_str (
3068+ & operands
3069+ . iter ( )
3070+ . map ( |op| move_if_necessary ( op) )
3071+ . collect :: < Vec < _ > > ( )
3072+ . join ( ", " ) ,
3073+ ) ;
30023074 self . src . push_str ( ");\n " ) ;
30033075 }
30043076 abi:: Instruction :: CallInterface { func, .. } => {
@@ -3015,7 +3087,13 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
30153087 }
30163088 self . src . push_str ( & func_name_h) ;
30173089 self . push_str ( "(" ) ;
3018- self . push_str ( & operands. join ( ", " ) ) ;
3090+ self . push_str (
3091+ & operands
3092+ . iter ( )
3093+ . map ( |op| move_if_necessary ( op) )
3094+ . collect :: < Vec < _ > > ( )
3095+ . join ( ", " ) ,
3096+ ) ;
30193097 self . push_str ( ");\n " ) ;
30203098 if self . needs_dealloc {
30213099 uwriteln ! (
@@ -3171,27 +3249,12 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
31713249 }
31723250
31733251 fn return_pointer ( & mut self , size : ArchitectureSize , align : Alignment ) -> Self :: Operand {
3252+ // Track maximum return area requirements
3253+ self . return_pointer_area_size = self . return_pointer_area_size . max ( size) ;
3254+ self . return_pointer_area_align = self . return_pointer_area_align . max ( align) ;
3255+
3256+ // Generate pointer to shared ret_area
31743257 let tmp = self . tmp ( ) ;
3175- let size_string = size. format ( POINTER_SIZE_EXPRESSION ) ;
3176- let tp = match align {
3177- Alignment :: Bytes ( bytes) => match bytes. get ( ) {
3178- 1 => "uint8_t" ,
3179- 2 => "uint16_t" ,
3180- 4 => "uint32_t" ,
3181- 8 => "uint64_t" ,
3182- _ => todo ! ( ) ,
3183- } ,
3184- Alignment :: Pointer => "uintptr_t" ,
3185- } ;
3186- let static_var = if self . gen . in_guest_import {
3187- ""
3188- } else {
3189- "static "
3190- } ;
3191- uwriteln ! (
3192- self . src,
3193- "{static_var}{tp} ret_area[({size_string}+sizeof({tp})-1)/sizeof({tp})];"
3194- ) ;
31953258 uwriteln ! (
31963259 self . src,
31973260 "{} ptr{tmp} = ({0})(&ret_area);" ,
0 commit comments