@@ -310,6 +310,28 @@ def_instruction! {
310310 ty: TypeId ,
311311 } : [ 2 ] => [ 1 ] ,
312312
313+ /// Lowers a map into a canonical pointer/length pair.
314+ ///
315+ /// This operation pops a map value from the stack and pushes pointer
316+ /// and length. A block is popped from the block stack to lower one
317+ /// key/value entry into linear memory.
318+ MapLower {
319+ key: & ' a Type ,
320+ value: & ' a Type ,
321+ realloc: Option <& ' a str >,
322+ } : [ 1 ] => [ 2 ] ,
323+
324+ /// Lifts a canonical pointer/length pair into a map.
325+ ///
326+ /// This operation consumes pointer and length from the stack. A block
327+ /// is popped from the block stack and must produce key/value for one
328+ /// map entry.
329+ MapLift {
330+ key: & ' a Type ,
331+ value: & ' a Type ,
332+ ty: TypeId ,
333+ } : [ 2 ] => [ 1 ] ,
334+
313335 /// Pops all fields for a fixed list off the stack and then composes them
314336 /// into an array.
315337 FixedLengthListLift {
@@ -349,6 +371,14 @@ def_instruction! {
349371 /// This is only used inside of blocks related to lowering lists.
350372 IterElem { element: & ' a Type } : [ 0 ] => [ 1 ] ,
351373
374+ /// Pushes an operand onto the stack representing the current map key
375+ /// for each map iteration.
376+ IterMapKey { key: & ' a Type } : [ 0 ] => [ 1 ] ,
377+
378+ /// Pushes an operand onto the stack representing the current map value
379+ /// for each map iteration.
380+ IterMapValue { value: & ' a Type } : [ 0 ] => [ 1 ] ,
381+
352382 /// Pushes an operand onto the stack representing the base pointer of
353383 /// the next element in a list.
354384 ///
@@ -581,6 +611,17 @@ def_instruction! {
581611 element: & ' a Type ,
582612 } : [ 2 ] => [ 0 ] ,
583613
614+ /// Used exclusively for guest-code generation this indicates that a
615+ /// map is being deallocated. The ptr/length are on the stack and are
616+ /// popped off and used to deallocate the map entry buffer.
617+ ///
618+ /// This variant also pops a block off the block stack to be used as
619+ /// the body of the deallocation loop over map entries.
620+ GuestDeallocateMap {
621+ key: & ' a Type ,
622+ value: & ' a Type ,
623+ } : [ 2 ] => [ 0 ] ,
624+
584625 /// Used exclusively for guest-code generation this indicates that
585626 /// a variant is being deallocated. The integer discriminant is popped
586627 /// off the stack as well as `blocks` number of blocks popped from the
@@ -875,7 +916,7 @@ fn needs_deallocate(resolve: &Resolve, ty: &Type, what: Deallocate) -> bool {
875916 TypeDefKind :: Future ( _) | TypeDefKind :: Stream ( _) => what. handles ( ) ,
876917 TypeDefKind :: Unknown => unreachable ! ( ) ,
877918 TypeDefKind :: FixedLengthList ( t, _) => needs_deallocate ( resolve, t, what) ,
878- TypeDefKind :: Map ( .. ) => todo ! ( ) ,
919+ TypeDefKind :: Map ( _ , _ ) => true ,
879920 } ,
880921
881922 Type :: Bool
@@ -1618,7 +1659,25 @@ impl<'a, B: Bindgen> Generator<'a, B> {
16181659 self . lower ( ty) ;
16191660 }
16201661 }
1621- TypeDefKind :: Map ( ..) => todo ! ( ) ,
1662+ TypeDefKind :: Map ( key, value) => {
1663+ let realloc = self . list_realloc ( ) ;
1664+ let value_offset = self . bindgen . sizes ( ) . field_offsets ( [ key, value] ) [ 1 ] . 0 ;
1665+ self . push_block ( ) ;
1666+ self . emit ( & IterMapKey { key } ) ;
1667+ self . emit ( & IterBasePointer ) ;
1668+ let key_addr = self . stack . pop ( ) . unwrap ( ) ;
1669+ self . write_to_memory ( key, key_addr, Default :: default ( ) ) ;
1670+ self . emit ( & IterMapValue { value } ) ;
1671+ self . emit ( & IterBasePointer ) ;
1672+ let value_addr = self . stack . pop ( ) . unwrap ( ) ;
1673+ self . write_to_memory ( value, value_addr, value_offset) ;
1674+ self . finish_block ( 0 ) ;
1675+ self . emit ( & MapLower {
1676+ key,
1677+ value,
1678+ realloc,
1679+ } ) ;
1680+ }
16221681 } ,
16231682 }
16241683 }
@@ -1819,7 +1878,16 @@ impl<'a, B: Bindgen> Generator<'a, B> {
18191878 id,
18201879 } ) ;
18211880 }
1822- TypeDefKind :: Map ( ..) => todo ! ( ) ,
1881+ TypeDefKind :: Map ( key, value) => {
1882+ let value_offset = self . bindgen . sizes ( ) . field_offsets ( [ key, value] ) [ 1 ] . 0 ;
1883+ self . push_block ( ) ;
1884+ self . emit ( & IterBasePointer ) ;
1885+ let entry_addr = self . stack . pop ( ) . unwrap ( ) ;
1886+ self . read_from_memory ( key, entry_addr. clone ( ) , Default :: default ( ) ) ;
1887+ self . read_from_memory ( value, entry_addr, value_offset) ;
1888+ self . finish_block ( 2 ) ;
1889+ self . emit ( & MapLift { key, value, ty : id } ) ;
1890+ }
18231891 } ,
18241892 }
18251893 }
@@ -1907,6 +1975,8 @@ impl<'a, B: Bindgen> Generator<'a, B> {
19071975 Type :: Id ( id) => match & self . resolve . types [ id] . kind {
19081976 TypeDefKind :: Type ( t) => self . write_to_memory ( t, addr, offset) ,
19091977 TypeDefKind :: List ( _) => self . write_list_to_memory ( ty, addr, offset) ,
1978+ // Maps have the same linear memory layout as list<tuple<K, V>>.
1979+ TypeDefKind :: Map ( _, _) => self . write_list_to_memory ( ty, addr, offset) ,
19101980
19111981 TypeDefKind :: Future ( _) | TypeDefKind :: Stream ( _) | TypeDefKind :: Handle ( _) => {
19121982 self . lower_and_emit ( ty, addr, & I32Store { offset } )
@@ -2016,7 +2086,6 @@ impl<'a, B: Bindgen> Generator<'a, B> {
20162086 id,
20172087 } ) ;
20182088 }
2019- TypeDefKind :: Map ( ..) => todo ! ( ) ,
20202089 } ,
20212090 }
20222091 }
@@ -2115,6 +2184,8 @@ impl<'a, B: Bindgen> Generator<'a, B> {
21152184 TypeDefKind :: Type ( t) => self . read_from_memory ( t, addr, offset) ,
21162185
21172186 TypeDefKind :: List ( _) => self . read_list_from_memory ( ty, addr, offset) ,
2187+ // Maps have the same linear memory layout as list<tuple<K, V>>.
2188+ TypeDefKind :: Map ( _, _) => self . read_list_from_memory ( ty, addr, offset) ,
21182189
21192190 TypeDefKind :: Future ( _) | TypeDefKind :: Stream ( _) | TypeDefKind :: Handle ( _) => {
21202191 self . emit_and_lift ( ty, addr, & I32Load { offset } )
@@ -2216,7 +2287,6 @@ impl<'a, B: Bindgen> Generator<'a, B> {
22162287 id,
22172288 } ) ;
22182289 }
2219- TypeDefKind :: Map ( ..) => todo ! ( ) ,
22202290 } ,
22212291 }
22222292 }
@@ -2339,6 +2409,18 @@ impl<'a, B: Bindgen> Generator<'a, B> {
23392409 self . emit ( & Instruction :: GuestDeallocateList { element } ) ;
23402410 }
23412411
2412+ TypeDefKind :: Map ( key, value) => {
2413+ let value_offset = self . bindgen . sizes ( ) . field_offsets ( [ key, value] ) [ 1 ] . 0 ;
2414+ self . push_block ( ) ;
2415+ self . emit ( & IterBasePointer ) ;
2416+ let entry_addr = self . stack . pop ( ) . unwrap ( ) ;
2417+ self . deallocate_indirect ( key, entry_addr. clone ( ) , Default :: default ( ) , what) ;
2418+ self . deallocate_indirect ( value, entry_addr, value_offset, what) ;
2419+ self . finish_block ( 0 ) ;
2420+
2421+ self . emit ( & Instruction :: GuestDeallocateMap { key, value } ) ;
2422+ }
2423+
23422424 TypeDefKind :: Handle ( Handle :: Own ( _) )
23432425 | TypeDefKind :: Future ( _)
23442426 | TypeDefKind :: Stream ( _)
@@ -2405,7 +2487,6 @@ impl<'a, B: Bindgen> Generator<'a, B> {
24052487 TypeDefKind :: Unknown => unreachable ! ( ) ,
24062488
24072489 TypeDefKind :: FixedLengthList ( ..) => todo ! ( ) ,
2408- TypeDefKind :: Map ( ..) => todo ! ( ) ,
24092490 } ,
24102491 }
24112492 }
@@ -2464,6 +2545,17 @@ impl<'a, B: Bindgen> Generator<'a, B> {
24642545 self . deallocate ( ty, what) ;
24652546 }
24662547
2548+ TypeDefKind :: Map ( _, _) => {
2549+ self . stack . push ( addr. clone ( ) ) ;
2550+ self . emit ( & Instruction :: PointerLoad { offset } ) ;
2551+ self . stack . push ( addr) ;
2552+ self . emit ( & Instruction :: LengthLoad {
2553+ offset : offset + self . bindgen . sizes ( ) . align ( ty) . into ( ) ,
2554+ } ) ;
2555+
2556+ self . deallocate ( ty, what) ;
2557+ }
2558+
24672559 TypeDefKind :: Handle ( Handle :: Own ( _) )
24682560 | TypeDefKind :: Future ( _)
24692561 | TypeDefKind :: Stream ( _)
@@ -2527,7 +2619,6 @@ impl<'a, B: Bindgen> Generator<'a, B> {
25272619 TypeDefKind :: Stream ( _) => unreachable ! ( ) ,
25282620 TypeDefKind :: Unknown => unreachable ! ( ) ,
25292621 TypeDefKind :: FixedLengthList ( _, _) => { }
2530- TypeDefKind :: Map ( ..) => todo ! ( ) ,
25312622 } ,
25322623 }
25332624 }
0 commit comments