// 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 }