@@ -660,19 +660,20 @@ func mapdelete(t *rtype, m unsafe.Pointer, key unsafe.Pointer) {
660660 js .InternalObject (m ).Delete (k )
661661}
662662
663- type mapIter struct {
663+ type hiter struct {
664664 t Type
665- m * js.Object
665+ m * js.Object // Underlying map object.
666666 keys * js.Object
667667 i int
668668
669- // last is the last object the iterator indicates. If this object exists, the functions that return the
670- // current key or value returns this object, regardless of the current iterator. It is because the current
671- // iterator might be stale due to key deletion in a loop.
669+ // last is the last object the iterator indicates. If this object exists, the
670+ // functions that return the current key or value returns this object,
671+ // regardless of the current iterator. It is because the current iterator
672+ // might be stale due to key deletion in a loop.
672673 last * js.Object
673674}
674675
675- func (iter * mapIter ) skipUntilValidKey () {
676+ func (iter * hiter ) skipUntilValidKey () {
676677 for iter .i < iter .keys .Length () {
677678 k := iter .keys .Index (iter .i )
678679 if iter .m .Get (k .String ()) != js .Undefined {
@@ -683,8 +684,53 @@ func (iter *mapIter) skipUntilValidKey() {
683684 }
684685}
685686
686- func mapiterinit (t * rtype , m unsafe.Pointer , _ * hiter ) unsafe.Pointer {
687- return unsafe .Pointer (& mapIter {t , js .InternalObject (m ), js .Global .Call ("$keys" , js .InternalObject (m )), 0 , nil })
687+ func mapiterinit (t * rtype , m unsafe.Pointer , it * hiter ) {
688+ * it = hiter {
689+ t : t ,
690+ m : js .InternalObject (m ),
691+ keys : js .Global .Call ("$keys" , js .InternalObject (m )),
692+ i : 0 ,
693+ last : nil ,
694+ }
695+ }
696+
697+ func mapiterkey (it * hiter ) unsafe.Pointer {
698+ var kv * js.Object
699+ if it .last != nil {
700+ kv = it .last
701+ } else {
702+ it .skipUntilValidKey ()
703+ if it .i == it .keys .Length () {
704+ return nil
705+ }
706+ k := it .keys .Index (it .i )
707+ kv = it .m .Get (k .String ())
708+
709+ // Record the key-value pair for later accesses.
710+ it .last = kv
711+ }
712+ return unsafe .Pointer (js .Global .Call ("$newDataPointer" , kv .Get ("k" ), jsType (PtrTo (it .t .Key ()))).Unsafe ())
713+ }
714+
715+ func mapiterelem (it * hiter ) unsafe.Pointer {
716+ var kv * js.Object
717+ if it .last != nil {
718+ kv = it .last
719+ } else {
720+ it .skipUntilValidKey ()
721+ if it .i == it .keys .Length () {
722+ return nil
723+ }
724+ k := it .keys .Index (it .i )
725+ kv = it .m .Get (k .String ())
726+ it .last = kv
727+ }
728+ return unsafe .Pointer (js .Global .Call ("$newDataPointer" , kv .Get ("v" ), jsType (PtrTo (it .t .Elem ()))).Unsafe ())
729+ }
730+
731+ func mapiternext (it * hiter ) {
732+ it .last = nil
733+ it .i ++
688734}
689735
690736func maplen (m unsafe.Pointer ) int {
0 commit comments