Source File
linkname_swiss.go
Belonging Package
runtime
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build goexperiment.swissmap
package runtime
import (
)
// Legacy //go:linkname compatibility shims
//
// The functions below are unused by the toolchain, and exist only for
// compatibility with existing //go:linkname use in the ecosystem (and in
// map_noswiss.go for normal use via GOEXPERIMENT=noswissmap).
// linknameIter is the it argument to mapiterinit and mapiternext.
//
// Callers of mapiterinit allocate their own iter structure, which has the
// layout of the pre-Go 1.24 hiter structure, shown here for posterity:
//
// type hiter struct {
// key unsafe.Pointer
// elem unsafe.Pointer
// t *maptype
// h *hmap
// buckets unsafe.Pointer
// bptr *bmap
// overflow *[]*bmap
// oldoverflow *[]*bmap
// startBucket uintptr
// offset uint8
// wrapped bool
// B uint8
// i uint8
// bucket uintptr
// checkBucket uintptr
// }
//
// Our structure must maintain compatibility with the old structure. This
// means:
//
// - Our structure must be the same size or smaller than hiter. Otherwise we
// may write outside the caller's hiter allocation.
// - Our structure must have the same pointer layout as hiter, so that the GC
// tracks pointers properly.
//
// Based on analysis of the "hall of shame" users of these linknames:
//
// - The key and elem fields must be kept up to date with the current key/elem.
// Some users directly access the key and elem fields rather than calling
// reflect.mapiterkey/reflect.mapiterelem.
// - The t field must be non-nil after mapiterinit. gonum.org/v1/gonum uses
// this to verify the iterator is initialized.
// - github.com/segmentio/encoding and github.com/RomiChan/protobuf check if h
// is non-nil, but the code has no effect. Thus the value of h does not
// matter. See internal/runtime_reflect/map.go.
type linknameIter struct {
// Fields from hiter.
key unsafe.Pointer
elem unsafe.Pointer
typ *abi.SwissMapType
// The real iterator.
it *maps.Iter
}
// mapiterinit is a compatibility wrapper for map iterator for users of
// //go:linkname from before Go 1.24. It is not used by Go itself. New users
// should use reflect or the maps package.
//
// mapiterinit should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - github.com/bytedance/sonic
// - github.com/goccy/go-json
// - github.com/RomiChan/protobuf
// - github.com/segmentio/encoding
// - github.com/ugorji/go/codec
// - github.com/wI2L/jettison
//
// Do not remove or change the type signature.
// See go.dev/issue/67401.
//
//go:linkname mapiterinit
func mapiterinit( *abi.SwissMapType, *maps.Map, *linknameIter) {
if raceenabled && != nil {
:= sys.GetCallerPC()
racereadpc(unsafe.Pointer(), , abi.FuncPCABIInternal())
}
.typ =
.it = new(maps.Iter)
.it.Init(, )
.it.Next()
.key = .it.Key()
.elem = .it.Elem()
}
// reflect_mapiterinit is a compatibility wrapper for map iterator for users of
// //go:linkname from before Go 1.24. It is not used by Go itself. New users
// should use reflect or the maps package.
//
// reflect_mapiterinit should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - github.com/modern-go/reflect2
// - gitee.com/quant1x/gox
// - github.com/v2pro/plz
// - github.com/wI2L/jettison
//
// Do not remove or change the type signature.
// See go.dev/issue/67401.
//
//go:linkname reflect_mapiterinit reflect.mapiterinit
func reflect_mapiterinit( *abi.SwissMapType, *maps.Map, *linknameIter) {
mapiterinit(, , )
}
// mapiternext is a compatibility wrapper for map iterator for users of
// //go:linkname from before Go 1.24. It is not used by Go itself. New users
// should use reflect or the maps package.
//
// mapiternext should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - github.com/bytedance/sonic
// - github.com/RomiChan/protobuf
// - github.com/segmentio/encoding
// - github.com/ugorji/go/codec
// - gonum.org/v1/gonum
//
// Do not remove or change the type signature.
// See go.dev/issue/67401.
//
//go:linkname mapiternext
func mapiternext( *linknameIter) {
if raceenabled {
:= sys.GetCallerPC()
racereadpc(unsafe.Pointer(.it.Map()), , abi.FuncPCABIInternal())
}
.it.Next()
.key = .it.Key()
.elem = .it.Elem()
}
// reflect_mapiternext is a compatibility wrapper for map iterator for users of
// //go:linkname from before Go 1.24. It is not used by Go itself. New users
// should use reflect or the maps package.
//
// reflect_mapiternext is for package reflect,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - gitee.com/quant1x/gox
// - github.com/modern-go/reflect2
// - github.com/goccy/go-json
// - github.com/v2pro/plz
// - github.com/wI2L/jettison
//
// Do not remove or change the type signature.
// See go.dev/issue/67401.
//
//go:linkname reflect_mapiternext reflect.mapiternext
func reflect_mapiternext( *linknameIter) {
mapiternext()
}
// reflect_mapiterkey is a compatibility wrapper for map iterator for users of
// //go:linkname from before Go 1.24. It is not used by Go itself. New users
// should use reflect or the maps package.
//
// reflect_mapiterkey should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - github.com/goccy/go-json
// - gonum.org/v1/gonum
//
// Do not remove or change the type signature.
// See go.dev/issue/67401.
//
//go:linkname reflect_mapiterkey reflect.mapiterkey
func reflect_mapiterkey( *linknameIter) unsafe.Pointer {
return .it.Key()
}
// reflect_mapiterelem is a compatibility wrapper for map iterator for users of
// //go:linkname from before Go 1.24. It is not used by Go itself. New users
// should use reflect or the maps package.
//
// reflect_mapiterelem should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - github.com/goccy/go-json
// - gonum.org/v1/gonum
//
// Do not remove or change the type signature.
// See go.dev/issue/67401.
//
//go:linkname reflect_mapiterelem reflect.mapiterelem
func reflect_mapiterelem( *linknameIter) unsafe.Pointer {
return .it.Elem()
}
![]() |
The pages are generated with Golds v0.7.7-preview. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |