Skip to content

Commit dafed76

Browse files
committed
Restore mapiterinit(), mapiterkey(), mapiterelem() and mapiternext().
golang/go@1b2d794 in the upstream changed signatures of those functions in the reflect package. The upstream `hiter` type is a close functional counterpart of the `mapIter` type we already had, so I renamed `mapIter` into `hiter` to match the upstream, and updated function implementations to match the upstream signatures.
1 parent 40a9a9c commit dafed76

File tree

1 file changed

+54
-8
lines changed

1 file changed

+54
-8
lines changed

compiler/natives/src/reflect/reflect.go

+54-8
Original file line numberDiff line numberDiff line change
@@ -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

690736
func maplen(m unsafe.Pointer) int {

0 commit comments

Comments
 (0)