mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-16 10:43:29 +00:00
reflect, internal/reflectlite: add Value.SetIter{Key,Value} and MapIter.Reset
Fixes #4790. Depends on #4787 (merge that first).
This commit is contained in:
@@ -1102,20 +1102,9 @@ func hashmapNewIterator() unsafe.Pointer
|
|||||||
func hashmapNext(m unsafe.Pointer, it unsafe.Pointer, key, value unsafe.Pointer) bool
|
func hashmapNext(m unsafe.Pointer, it unsafe.Pointer, key, value unsafe.Pointer) bool
|
||||||
|
|
||||||
func (v Value) MapRange() *MapIter {
|
func (v Value) MapRange() *MapIter {
|
||||||
if v.Kind() != Map {
|
iter := &MapIter{}
|
||||||
panic(&ValueError{Method: "MapRange", Kind: v.Kind()})
|
iter.Reset(v)
|
||||||
}
|
return iter
|
||||||
|
|
||||||
keyType := v.typecode.key()
|
|
||||||
|
|
||||||
keyTypeIsEmptyInterface := keyType.Kind() == Interface && keyType.NumMethod() == 0
|
|
||||||
shouldUnpackInterface := !keyTypeIsEmptyInterface && keyType.Kind() != String && !keyType.isBinary()
|
|
||||||
|
|
||||||
return &MapIter{
|
|
||||||
m: v,
|
|
||||||
it: hashmapNewIterator(),
|
|
||||||
unpackKeyInterface: shouldUnpackInterface,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MapIter struct {
|
type MapIter struct {
|
||||||
@@ -1142,6 +1131,10 @@ func (it *MapIter) Key() Value {
|
|||||||
return it.key.Elem()
|
return it.key.Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v Value) SetIterKey(iter *MapIter) {
|
||||||
|
v.Set(iter.Key())
|
||||||
|
}
|
||||||
|
|
||||||
func (it *MapIter) Value() Value {
|
func (it *MapIter) Value() Value {
|
||||||
if !it.valid {
|
if !it.valid {
|
||||||
panic("reflect.MapIter.Value called on invalid iterator")
|
panic("reflect.MapIter.Value called on invalid iterator")
|
||||||
@@ -1150,6 +1143,10 @@ func (it *MapIter) Value() Value {
|
|||||||
return it.val.Elem()
|
return it.val.Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v Value) SetIterValue(iter *MapIter) {
|
||||||
|
v.Set(iter.Value())
|
||||||
|
}
|
||||||
|
|
||||||
func (it *MapIter) Next() bool {
|
func (it *MapIter) Next() bool {
|
||||||
it.key = New(it.m.typecode.Key())
|
it.key = New(it.m.typecode.Key())
|
||||||
it.val = New(it.m.typecode.Elem())
|
it.val = New(it.m.typecode.Elem())
|
||||||
@@ -1158,6 +1155,23 @@ func (it *MapIter) Next() bool {
|
|||||||
return it.valid
|
return it.valid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (iter *MapIter) Reset(v Value) {
|
||||||
|
if v.Kind() != Map {
|
||||||
|
panic(&ValueError{Method: "MapRange", Kind: v.Kind()})
|
||||||
|
}
|
||||||
|
|
||||||
|
keyType := v.typecode.key()
|
||||||
|
|
||||||
|
keyTypeIsEmptyInterface := keyType.Kind() == Interface && keyType.NumMethod() == 0
|
||||||
|
shouldUnpackInterface := !keyTypeIsEmptyInterface && keyType.Kind() != String && !keyType.isBinary()
|
||||||
|
|
||||||
|
*iter = MapIter{
|
||||||
|
m: v,
|
||||||
|
it: hashmapNewIterator(),
|
||||||
|
unpackKeyInterface: shouldUnpackInterface,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (v Value) Set(x Value) {
|
func (v Value) Set(x Value) {
|
||||||
v.checkAddressable()
|
v.checkAddressable()
|
||||||
v.checkRO()
|
v.checkRO()
|
||||||
|
|||||||
@@ -381,8 +381,6 @@ func TestSetValue(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
func TestMapIterSet(t *testing.T) {
|
func TestMapIterSet(t *testing.T) {
|
||||||
m := make(map[string]any, len(valueTests))
|
m := make(map[string]any, len(valueTests))
|
||||||
for _, tt := range valueTests {
|
for _, tt := range valueTests {
|
||||||
@@ -430,8 +428,6 @@ func TestMapIterSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
func TestCanIntUintFloatComplex(t *testing.T) {
|
func TestCanIntUintFloatComplex(t *testing.T) {
|
||||||
type integer int
|
type integer int
|
||||||
type uinteger uint
|
type uinteger uint
|
||||||
@@ -7955,6 +7951,8 @@ func TestConvertibleTo(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
func TestSetIter(t *testing.T) {
|
func TestSetIter(t *testing.T) {
|
||||||
data := map[string]int{
|
data := map[string]int{
|
||||||
"foo": 1,
|
"foo": 1,
|
||||||
@@ -8044,6 +8042,8 @@ func TestSetIter(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
func TestMethodCallValueCodePtr(t *testing.T) {
|
func TestMethodCallValueCodePtr(t *testing.T) {
|
||||||
m := ValueOf(Point{}).Method(1)
|
m := ValueOf(Point{}).Method(1)
|
||||||
want := MethodValueCallCodePtr()
|
want := MethodValueCallCodePtr()
|
||||||
|
|||||||
@@ -65,14 +65,26 @@ func (it *MapIter) Key() Value {
|
|||||||
return Value{((*reflectlite.MapIter)(it)).Key()}
|
return Value{((*reflectlite.MapIter)(it)).Key()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v Value) SetIterKey(iter *MapIter) {
|
||||||
|
v.Value.SetIterKey((*reflectlite.MapIter)(iter))
|
||||||
|
}
|
||||||
|
|
||||||
func (it *MapIter) Value() Value {
|
func (it *MapIter) Value() Value {
|
||||||
return Value{((*reflectlite.MapIter)(it)).Value()}
|
return Value{((*reflectlite.MapIter)(it)).Value()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v Value) SetIterValue(iter *MapIter) {
|
||||||
|
v.Value.SetIterValue((*reflectlite.MapIter)(iter))
|
||||||
|
}
|
||||||
|
|
||||||
func (it *MapIter) Next() bool {
|
func (it *MapIter) Next() bool {
|
||||||
return ((*reflectlite.MapIter)(it)).Next()
|
return ((*reflectlite.MapIter)(it)).Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (iter *MapIter) Reset(v Value) {
|
||||||
|
(*reflectlite.MapIter)(iter).Reset(v.Value)
|
||||||
|
}
|
||||||
|
|
||||||
func (v Value) Set(x Value) {
|
func (v Value) Set(x Value) {
|
||||||
v.Value.Set(x.Value)
|
v.Value.Set(x.Value)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user