@@ -9,11 +9,12 @@ use crate::trivia::fn_lookup;
99use crate :: { BorrowedResource , QjsCallContext , with_ctx} ;
1010
1111use rquickjs:: class:: Class ;
12- use rquickjs:: { Coerced , IntoJs , Persistent , Symbol , Value } ;
12+ use rquickjs:: function:: This ;
13+ use rquickjs:: { Coerced , Constructor , Function , IntoJs , Persistent , Symbol , Value } ;
1314use smallvec:: SmallVec ;
1415use wit_dylib_ffi:: {
15- Call , Enum , Flags , Future , List , Record , Resource , Stream , Tuple , Type , Variant , WitOption ,
16- WitResult ,
16+ Call , Enum , Flags , Future , List , Map , Record , Resource , Stream , Tuple , Type , Variant ,
17+ WitOption , WitResult ,
1718} ;
1819
1920use std:: alloc:: Layout ;
@@ -202,7 +203,7 @@ impl Call for QjsCallContext {
202203 } )
203204 }
204205
205- fn pop_iter_next ( & mut self , _ty : List ) {
206+ fn pop_list_iter_next ( & mut self , _ty : List ) {
206207 let index = * self . iter_stack . last ( ) . expect ( "iter_stack underflow" ) ;
207208 let arr_persistent = self . stack . last ( ) . expect ( "stack underflow" ) . clone ( ) ;
208209
@@ -216,11 +217,53 @@ impl Call for QjsCallContext {
216217 * self . iter_stack . last_mut ( ) . unwrap ( ) = index + 1 ;
217218 }
218219
219- fn pop_iter ( & mut self , _ty : List ) {
220+ fn pop_list_iter ( & mut self , _ty : List ) {
220221 self . iter_stack . pop ( ) . expect ( "iter_stack underflow" ) ;
221222 self . stack . pop ( ) . expect ( "stack underflow" ) ;
222223 }
223224
225+ fn pop_map ( & mut self , _ty : Map ) -> usize {
226+ let persistent = self . stack . pop ( ) . expect ( "stack underflow" ) ;
227+
228+ with_ctx ( |ctx| {
229+ let value = persistent. restore ( ctx) . unwrap ( ) ;
230+ let map = value. as_object ( ) . expect ( "expected Map" ) ;
231+ let constructor: Constructor = ctx. globals ( ) . get ( "Map" ) . expect ( "Map not found" ) ;
232+ assert ! ( map. is_instance_of( & constructor) , "expected Map" ) ;
233+
234+ let len = map. get ( "size" ) . expect ( "expected Map size" ) ;
235+ let entries: Function = map. get ( "entries" ) . expect ( "Map.entries not found" ) ;
236+ let iterator: Value = entries
237+ . call ( ( This ( map. clone ( ) ) , ) )
238+ . expect ( "failed to create Map iterator" ) ;
239+ self . stack . push ( Persistent :: save ( ctx, iterator) ) ;
240+ len
241+ } )
242+ }
243+
244+ fn pop_map_iter_next ( & mut self , _ty : Map ) {
245+ let persistent = self . stack . last ( ) . expect ( "stack underflow" ) . clone ( ) ;
246+
247+ with_ctx ( |ctx| {
248+ let value = persistent. restore ( ctx) . unwrap ( ) ;
249+ let iterator = value. as_object ( ) . expect ( "expected Map iterator" ) ;
250+ let next: Function = iterator. get ( "next" ) . expect ( "Map iterator.next not found" ) ;
251+ let result: rquickjs:: Object = next
252+ . call ( ( This ( iterator. clone ( ) ) , ) )
253+ . expect ( "failed to advance Map iterator" ) ;
254+ let entry: rquickjs:: Array = result. get ( "value" ) . expect ( "expected Map entry" ) ;
255+ let key: Value = entry. get ( 0 ) . expect ( "expected Map key" ) ;
256+ let value: Value = entry. get ( 1 ) . expect ( "expected Map value" ) ;
257+
258+ self . stack . push ( Persistent :: save ( ctx, value) ) ;
259+ self . stack . push ( Persistent :: save ( ctx, key) ) ;
260+ } ) ;
261+ }
262+
263+ fn pop_map_iter ( & mut self , _ty : Map ) {
264+ self . stack . pop ( ) . expect ( "stack underflow" ) ;
265+ }
266+
224267 fn pop_option ( & mut self , ty : WitOption ) -> u32 {
225268 let persistent = self . stack . pop ( ) . expect ( "stack underflow" ) ;
226269
@@ -509,6 +552,31 @@ impl Call for QjsCallContext {
509552 } ) ;
510553 }
511554
555+ fn push_map ( & mut self , _ty : Map , _capacity : usize ) {
556+ with_ctx ( |ctx| {
557+ let constructor: Constructor = ctx. globals ( ) . get ( "Map" ) . expect ( "Map not found" ) ;
558+ let map: Value = constructor. construct ( ( ) ) . expect ( "failed to create Map" ) ;
559+ self . stack . push ( Persistent :: save ( ctx, map) ) ;
560+ } ) ;
561+ }
562+
563+ fn map_append ( & mut self , _ty : Map ) {
564+ let value = self . stack . pop ( ) . expect ( "stack underflow" ) ;
565+ let key = self . stack . pop ( ) . expect ( "stack underflow" ) ;
566+ let map_persistent = self . stack . last ( ) . expect ( "stack underflow" ) . clone ( ) ;
567+
568+ with_ctx ( |ctx| {
569+ let map_value = map_persistent. restore ( ctx) . unwrap ( ) ;
570+ let map = map_value. as_object ( ) . expect ( "expected Map" ) ;
571+ let set: Function = map. get ( "set" ) . expect ( "Map.set not found" ) ;
572+ let key = key. restore ( ctx) . unwrap ( ) ;
573+ let value = value. restore ( ctx) . unwrap ( ) ;
574+ let _: Value = set
575+ . call ( ( This ( map. clone ( ) ) , key, value) )
576+ . expect ( "failed to append Map entry" ) ;
577+ } ) ;
578+ }
579+
512580 fn push_option ( & mut self , ty : WitOption , is_some : bool ) {
513581 if option_is_nested ( ty) {
514582 // Nested option: wrap so `none` and `some(none)` stay distinct.
0 commit comments