@@ -2241,15 +2241,18 @@ where
22412241 }
22422242}
22432243
2244- fn lift_map < K , V > (
2244+ /// Shared helper that validates a map's memory region and lifts each
2245+ /// (key, value) pair, forwarding them to `insert`.
2246+ fn lift_map_pairs < K , V > (
22452247 cx : & mut LiftContext < ' _ > ,
22462248 key_ty : InterfaceType ,
22472249 value_ty : InterfaceType ,
22482250 ptr : usize ,
22492251 len : usize ,
2250- ) -> Result < HashMap < K , V > >
2252+ mut insert : impl FnMut ( K , V ) -> Result < ( ) > ,
2253+ ) -> Result < ( ) >
22512254where
2252- K : Lift + Eq + Hash ,
2255+ K : Lift ,
22532256 V : Lift ,
22542257{
22552258 let tuple_abi = CanonicalAbiInfo :: record_static ( & [ K :: ABI , V :: ABI ] ) ;
@@ -2267,7 +2270,6 @@ where
22672270 bail ! ( "map pointer is not aligned" ) ;
22682271 }
22692272
2270- let mut result = HashMap :: with_capacity ( len) ?;
22712273 for i in 0 ..len {
22722274 let entry_base = ptr + ( i * tuple_size) ;
22732275
@@ -2280,18 +2282,33 @@ where
22802282 let value_bytes = & cx. memory ( ) [ entry_base + value_field..] [ ..V :: SIZE32 ] ;
22812283 let value = V :: linear_lift_from_memory ( cx, value_ty, value_bytes) ?;
22822284
2283- result . insert ( key, value) ?;
2285+ insert ( key, value) ?;
22842286 }
22852287
2288+ Ok ( ( ) )
2289+ }
2290+
2291+ fn lift_map < K , V > (
2292+ cx : & mut LiftContext < ' _ > ,
2293+ key_ty : InterfaceType ,
2294+ value_ty : InterfaceType ,
2295+ ptr : usize ,
2296+ len : usize ,
2297+ ) -> Result < HashMap < K , V > >
2298+ where
2299+ K : Lift + Eq + Hash ,
2300+ V : Lift ,
2301+ {
2302+ let mut result = HashMap :: with_capacity ( len) ?;
2303+ lift_map_pairs ( cx, key_ty, value_ty, ptr, len, |k, v| {
2304+ result. insert ( k, v) ?;
2305+ Ok ( ( ) )
2306+ } ) ?;
22862307 Ok ( result)
22872308}
22882309
22892310// =============================================================================
22902311// std::collections::HashMap<K, V> support for component model `map<K, V>`
2291- //
2292- // This mirrors the wasmtime_environ::collections::HashMap implementation above
2293- // but works with the standard library HashMap type, which is what users will
2294- // naturally reach for.
22952312
22962313#[ cfg( feature = "std" ) ]
22972314unsafe impl < K , V > ComponentType for std:: collections:: HashMap < K , V >
@@ -2422,37 +2439,11 @@ where
24222439 K : Lift + Eq + Hash ,
24232440 V : Lift ,
24242441{
2425- let tuple_abi = CanonicalAbiInfo :: record_static ( & [ K :: ABI , V :: ABI ] ) ;
2426- let tuple_size = tuple_abi. size32 as usize ;
2427- let tuple_align = tuple_abi. align32 as usize ;
2428-
2429- match len
2430- . checked_mul ( tuple_size)
2431- . and_then ( |total| ptr. checked_add ( total) )
2432- {
2433- Some ( n) if n <= cx. memory ( ) . len ( ) => { }
2434- _ => bail ! ( "map pointer/length out of bounds of memory" ) ,
2435- }
2436- if ptr % tuple_align != 0 {
2437- bail ! ( "map pointer is not aligned" ) ;
2438- }
2439-
24402442 let mut result = std:: collections:: HashMap :: with_capacity ( len) ;
2441- for i in 0 ..len {
2442- let entry_base = ptr + ( i * tuple_size) ;
2443-
2444- let mut field_offset = 0usize ;
2445- let key_field = K :: ABI . next_field32_size ( & mut field_offset) ;
2446- let key_bytes = & cx. memory ( ) [ entry_base + key_field..] [ ..K :: SIZE32 ] ;
2447- let key = K :: linear_lift_from_memory ( cx, key_ty, key_bytes) ?;
2448-
2449- let value_field = V :: ABI . next_field32_size ( & mut field_offset) ;
2450- let value_bytes = & cx. memory ( ) [ entry_base + value_field..] [ ..V :: SIZE32 ] ;
2451- let value = V :: linear_lift_from_memory ( cx, value_ty, value_bytes) ?;
2452-
2453- result. insert ( key, value) ;
2454- }
2455-
2443+ lift_map_pairs ( cx, key_ty, value_ty, ptr, len, |k, v| {
2444+ result. insert ( k, v) ;
2445+ Ok ( ( ) )
2446+ } ) ?;
24562447 Ok ( result)
24572448}
24582449
0 commit comments