You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
2.3 KiB
81 lines
2.3 KiB
// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
|
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
|
|
|
//go:build !safe && !codec.safe && !appengine && go1.9 && !gc
|
|
// +build !safe,!codec.safe,!appengine,go1.9,!gc
|
|
|
|
package codec
|
|
|
|
import (
|
|
"reflect"
|
|
_ "runtime" // needed for go linkname(s)
|
|
"unsafe"
|
|
)
|
|
|
|
var unsafeZeroArr [1024]byte
|
|
|
|
// runtime.growslice does not work with gccgo, failing with "growslice: cap out of range" error.
|
|
// consequently, we just call newarray followed by typedslicecopy directly.
|
|
|
|
func unsafeGrowslice(typ unsafe.Pointer, old unsafeSlice, cap, incr int) (v unsafeSlice) {
|
|
size := rtsize2(typ)
|
|
if size == 0 {
|
|
return unsafeSlice{unsafe.Pointer(&unsafeZeroArr[0]), old.Len, cap + incr}
|
|
}
|
|
newcap := int(growCap(uint(cap), uint(size), uint(incr)))
|
|
v = unsafeSlice{Data: newarray(typ, newcap), Len: old.Len, Cap: newcap}
|
|
if old.Len > 0 {
|
|
typedslicecopy(typ, v, old)
|
|
}
|
|
// memmove(v.Data, old.Data, size*uintptr(old.Len))
|
|
return
|
|
}
|
|
|
|
// func unsafeNew(t reflect.Type, typ unsafe.Pointer) unsafe.Pointer {
|
|
// rv := reflect.New(t)
|
|
// return ((*unsafeReflectValue)(unsafe.Pointer(&rv))).ptr
|
|
// }
|
|
|
|
// runtime.{mapassign_fastXXX, mapaccess2_fastXXX} are not supported in gollvm,
|
|
// failing with "error: undefined reference" error.
|
|
// so we just use runtime.{mapassign, mapaccess2} directly
|
|
|
|
func mapStoresElemIndirect(elemsize uintptr) bool { return false }
|
|
|
|
func mapSet(m, k, v reflect.Value, _ mapKeyFastKind, _, valIsRef bool) {
|
|
var urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
|
|
var kptr = unsafeMapKVPtr(urv)
|
|
urv = (*unsafeReflectValue)(unsafe.Pointer(&v))
|
|
var vtyp = urv.typ
|
|
var vptr = unsafeMapKVPtr(urv)
|
|
|
|
urv = (*unsafeReflectValue)(unsafe.Pointer(&m))
|
|
mptr := rvRefPtr(urv)
|
|
|
|
vvptr := mapassign(urv.typ, mptr, kptr)
|
|
typedmemmove(vtyp, vvptr, vptr)
|
|
}
|
|
|
|
func mapGet(m, k, v reflect.Value, _ mapKeyFastKind, _, valIsRef bool) (_ reflect.Value) {
|
|
var urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
|
|
var kptr = unsafeMapKVPtr(urv)
|
|
urv = (*unsafeReflectValue)(unsafe.Pointer(&m))
|
|
mptr := rvRefPtr(urv)
|
|
|
|
vvptr, ok := mapaccess2(urv.typ, mptr, kptr)
|
|
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
urv = (*unsafeReflectValue)(unsafe.Pointer(&v))
|
|
|
|
if helperUnsafeDirectAssignMapEntry || valIsRef {
|
|
urv.ptr = vvptr
|
|
} else {
|
|
typedmemmove(urv.typ, urv.ptr, vvptr)
|
|
}
|
|
|
|
return v
|
|
}
|