From 9f8719752a25505b268c5e580f3c452128b6df23 Mon Sep 17 00:00:00 2001 From: Tao Wen Date: Sat, 11 Sep 2021 08:23:03 +0800 Subject: [PATCH 1/2] update signature of mapiterinit of go 1.18 --- go.mod | 3 +++ unsafe_link.go | 22 +++++++++++++++++----- unsafe_map.go | 4 +++- 3 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 go.mod diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..bad14b7 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/modern-go/reflect2 + +go 1.18 diff --git a/unsafe_link.go b/unsafe_link.go index 57229c8..de964d9 100644 --- a/unsafe_link.go +++ b/unsafe_link.go @@ -19,7 +19,7 @@ func typedslicecopy(elemType unsafe.Pointer, dst, src sliceHeader) int //go:linkname mapassign reflect.mapassign //go:noescape -func mapassign(rtype unsafe.Pointer, m unsafe.Pointer, key, val unsafe.Pointer) +func mapassign(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer, val unsafe.Pointer) //go:linkname mapaccess reflect.mapaccess //go:noescape @@ -29,7 +29,7 @@ func mapaccess(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) (val // doesn't let the return value escape. //go:noescape //go:linkname mapiterinit reflect.mapiterinit -func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer) *hiter +func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer, it *hiter) //go:noescape //go:linkname mapiternext reflect.mapiternext @@ -42,9 +42,21 @@ func ifaceE2I(rtype unsafe.Pointer, src interface{}, dst unsafe.Pointer) // If you modify hiter, also change cmd/internal/gc/reflect.go to indicate // the layout of this structure. type hiter struct { - key unsafe.Pointer // Must be in first position. Write nil to indicate iteration end (see cmd/internal/gc/range.go). - value unsafe.Pointer // Must be in second position (see cmd/internal/gc/range.go). - // rest fields are ignored + key unsafe.Pointer + value unsafe.Pointer + t unsafe.Pointer + h unsafe.Pointer + buckets unsafe.Pointer + bptr unsafe.Pointer + overflow *[]unsafe.Pointer + oldoverflow *[]unsafe.Pointer + startBucket uintptr + offset uint8 + wrapped bool + B uint8 + i uint8 + bucket uintptr + checkBucket uintptr } // add returns p+x. diff --git a/unsafe_map.go b/unsafe_map.go index f2e76e6..b8b747c 100644 --- a/unsafe_map.go +++ b/unsafe_map.go @@ -108,8 +108,10 @@ func (type2 *UnsafeMapType) Iterate(obj interface{}) MapIterator { } func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { + var it hiter + mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj), &it) return &UnsafeMapIterator{ - hiter: mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj)), + hiter: &it, pKeyRType: type2.pKeyRType, pElemRType: type2.pElemRType, } From 835802817d782825522f9d3fb740b00139f42e21 Mon Sep 17 00:00:00 2001 From: Tao Wen Date: Sat, 11 Sep 2021 10:08:56 +0800 Subject: [PATCH 2/2] fix go1.18 --- go.mod | 2 +- go_above_118.go | 23 +++++++++++++++++++++++ go_below_118.go | 21 +++++++++++++++++++++ test.sh | 12 ------------ unsafe_link.go | 6 ------ unsafe_map.go | 10 ---------- 6 files changed, 45 insertions(+), 29 deletions(-) create mode 100644 go_above_118.go create mode 100644 go_below_118.go delete mode 100755 test.sh diff --git a/go.mod b/go.mod index bad14b7..9057e9b 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/modern-go/reflect2 -go 1.18 +go 1.12 diff --git a/go_above_118.go b/go_above_118.go new file mode 100644 index 0000000..2b4116f --- /dev/null +++ b/go_above_118.go @@ -0,0 +1,23 @@ +//+build go1.18 + +package reflect2 + +import ( + "unsafe" +) + +// m escapes into the return value, but the caller of mapiterinit +// doesn't let the return value escape. +//go:noescape +//go:linkname mapiterinit reflect.mapiterinit +func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer, it *hiter) + +func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { + var it hiter + mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj), &it) + return &UnsafeMapIterator{ + hiter: &it, + pKeyRType: type2.pKeyRType, + pElemRType: type2.pElemRType, + } +} \ No newline at end of file diff --git a/go_below_118.go b/go_below_118.go new file mode 100644 index 0000000..00003db --- /dev/null +++ b/go_below_118.go @@ -0,0 +1,21 @@ +//+build !go1.18 + +package reflect2 + +import ( + "unsafe" +) + +// m escapes into the return value, but the caller of mapiterinit +// doesn't let the return value escape. +//go:noescape +//go:linkname mapiterinit reflect.mapiterinit +func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer) (val *hiter) + +func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { + return &UnsafeMapIterator{ + hiter: mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj)), + pKeyRType: type2.pKeyRType, + pElemRType: type2.pElemRType, + } +} \ No newline at end of file diff --git a/test.sh b/test.sh deleted file mode 100755 index 3d2b976..0000000 --- a/test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e -echo "" > coverage.txt - -for d in $(go list github.com/modern-go/reflect2-tests/... | grep -v vendor); do - go test -coverprofile=profile.out -coverpkg=github.com/modern-go/reflect2 $d - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - rm profile.out - fi -done diff --git a/unsafe_link.go b/unsafe_link.go index de964d9..b49f614 100644 --- a/unsafe_link.go +++ b/unsafe_link.go @@ -25,12 +25,6 @@ func mapassign(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer, val u //go:noescape func mapaccess(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer) -// m escapes into the return value, but the caller of mapiterinit -// doesn't let the return value escape. -//go:noescape -//go:linkname mapiterinit reflect.mapiterinit -func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer, it *hiter) - //go:noescape //go:linkname mapiternext reflect.mapiternext func mapiternext(it *hiter) diff --git a/unsafe_map.go b/unsafe_map.go index b8b747c..37872da 100644 --- a/unsafe_map.go +++ b/unsafe_map.go @@ -107,16 +107,6 @@ func (type2 *UnsafeMapType) Iterate(obj interface{}) MapIterator { return type2.UnsafeIterate(objEFace.data) } -func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { - var it hiter - mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj), &it) - return &UnsafeMapIterator{ - hiter: &it, - pKeyRType: type2.pKeyRType, - pElemRType: type2.pElemRType, - } -} - type UnsafeMapIterator struct { *hiter pKeyRType unsafe.Pointer