github.com/kamalshkeir/kencoding@v0.0.2-0.20230409043843-44b609a0475a/internal/runtime_reflect/map.go (about)

     1  // Package runtime_reflect exposes internal APIs of the Go runtime.
     2  //
     3  // This package is internal so it doesn't become part of the exported APIs that
     4  // users of this package can take dependencies on. There is a risk that these
     5  // APIs will be implicitly changed by Go, in which case packages that depend on
     6  // it will break. We use these APIs to have access to optimziations that aren't
     7  // possible today via the reflect package. Ideally, the reflect package evolves
     8  // to expose APIs that are efficient enough that we can drop the need for this
     9  // package, but until then we will be maintaining bridges to these Go runtime
    10  // functions and types.
    11  package runtime_reflect
    12  
    13  import "unsafe"
    14  
    15  func Assign(typ, dst, src unsafe.Pointer) {
    16  	typedmemmove(typ, dst, src)
    17  }
    18  
    19  func MapAssign(t, m, k unsafe.Pointer) unsafe.Pointer {
    20  	return mapassign(t, m, k)
    21  }
    22  
    23  func MakeMap(t unsafe.Pointer, cap int) unsafe.Pointer {
    24  	return makemap(t, cap)
    25  }
    26  
    27  type MapIter struct{ hiter }
    28  
    29  func (it *MapIter) Init(t unsafe.Pointer, m unsafe.Pointer) {
    30  	mapiterinit(t, m, &it.hiter)
    31  }
    32  
    33  func (it *MapIter) Done() {
    34  	if it.h != nil {
    35  		it.key = nil
    36  		mapiternext(&it.hiter)
    37  	}
    38  }
    39  
    40  func (it *MapIter) Next() {
    41  	mapiternext(&it.hiter)
    42  }
    43  
    44  func (it *MapIter) HasNext() bool {
    45  	return it.key != nil
    46  }
    47  
    48  func (it *MapIter) Key() unsafe.Pointer { return it.key }
    49  
    50  func (it *MapIter) Value() unsafe.Pointer { return it.value }
    51  
    52  // copied from src/runtime/map.go, all pointer types replaced with
    53  // unsafe.Pointer.
    54  //
    55  // Alternatively we could get away with a heap allocation and only
    56  // defining key and val if we were using reflect.mapiterinit instead,
    57  // which returns a heap-allocated *hiter.
    58  type hiter struct {
    59  	key         unsafe.Pointer // nil when iteration is done
    60  	value       unsafe.Pointer
    61  	t           unsafe.Pointer
    62  	h           unsafe.Pointer
    63  	buckets     unsafe.Pointer // bucket ptr at hash_iter initialization time
    64  	bptr        unsafe.Pointer // current bucket
    65  	overflow    unsafe.Pointer // keeps overflow buckets of hmap.buckets alive
    66  	oldoverflow unsafe.Pointer // keeps overflow buckets of hmap.oldbuckets alive
    67  	startBucket uintptr        // bucket iteration started at
    68  	offset      uint8          // intra-bucket offset to start from during iteration (should be big enough to hold bucketCnt-1)
    69  	wrapped     bool           // already wrapped around from end of bucket array to beginning
    70  	B           uint8
    71  	i           uint8
    72  	bucket      uintptr
    73  	checkBucket uintptr
    74  }
    75  
    76  //go:noescape
    77  //go:linkname makemap reflect.makemap
    78  func makemap(t unsafe.Pointer, cap int) unsafe.Pointer
    79  
    80  // m escapes into the return value, but the caller of mapiterinit
    81  // doesn't let the return value escape.
    82  //go:noescape
    83  //go:linkname mapiterinit runtime.mapiterinit
    84  func mapiterinit(t unsafe.Pointer, m unsafe.Pointer, it *hiter)
    85  
    86  //go:noescape
    87  //go:linkname mapiternext runtime.mapiternext
    88  func mapiternext(it *hiter)
    89  
    90  //go:noescape
    91  //go:linkname mapassign runtime.mapassign
    92  func mapassign(t, m, k unsafe.Pointer) unsafe.Pointer
    93  
    94  //go:nosplit
    95  //go:noescape
    96  //go:linkname typedmemmove runtime.typedmemmove
    97  func typedmemmove(typ, dst, src unsafe.Pointer)