fastmem.go (2847B)
1 /* 2 * Copyright 2021 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package rt 18 19 import ( 20 `unsafe` 21 `reflect` 22 ) 23 24 //go:nosplit 25 func Get16(v []byte) int16 { 26 return *(*int16)((*GoSlice)(unsafe.Pointer(&v)).Ptr) 27 } 28 29 //go:nosplit 30 func Get32(v []byte) int32 { 31 return *(*int32)((*GoSlice)(unsafe.Pointer(&v)).Ptr) 32 } 33 34 //go:nosplit 35 func Get64(v []byte) int64 { 36 return *(*int64)((*GoSlice)(unsafe.Pointer(&v)).Ptr) 37 } 38 39 //go:nosplit 40 func Mem2Str(v []byte) (s string) { 41 (*GoString)(unsafe.Pointer(&s)).Len = (*GoSlice)(unsafe.Pointer(&v)).Len 42 (*GoString)(unsafe.Pointer(&s)).Ptr = (*GoSlice)(unsafe.Pointer(&v)).Ptr 43 return 44 } 45 46 //go:nosplit 47 func Str2Mem(s string) (v []byte) { 48 (*GoSlice)(unsafe.Pointer(&v)).Cap = (*GoString)(unsafe.Pointer(&s)).Len 49 (*GoSlice)(unsafe.Pointer(&v)).Len = (*GoString)(unsafe.Pointer(&s)).Len 50 (*GoSlice)(unsafe.Pointer(&v)).Ptr = (*GoString)(unsafe.Pointer(&s)).Ptr 51 return 52 } 53 54 func BytesFrom(p unsafe.Pointer, n int, c int) (r []byte) { 55 (*GoSlice)(unsafe.Pointer(&r)).Ptr = p 56 (*GoSlice)(unsafe.Pointer(&r)).Len = n 57 (*GoSlice)(unsafe.Pointer(&r)).Cap = c 58 return 59 } 60 61 func FuncAddr(f interface{}) unsafe.Pointer { 62 if vv := UnpackEface(f); vv.Type.Kind() != reflect.Func { 63 panic("f is not a function") 64 } else { 65 return *(*unsafe.Pointer)(vv.Value) 66 } 67 } 68 69 func IndexChar(src string, index int) unsafe.Pointer { 70 return unsafe.Pointer(uintptr((*GoString)(unsafe.Pointer(&src)).Ptr) + uintptr(index)) 71 } 72 73 func IndexByte(ptr []byte, index int) unsafe.Pointer { 74 return unsafe.Pointer(uintptr((*GoSlice)(unsafe.Pointer(&ptr)).Ptr) + uintptr(index)) 75 } 76 77 //go:nosplit 78 func GuardSlice(buf *[]byte, n int) { 79 c := cap(*buf) 80 l := len(*buf) 81 if c-l < n { 82 c = c>>1 + n + l 83 if c < 32 { 84 c = 32 85 } 86 tmp := make([]byte, l, c) 87 copy(tmp, *buf) 88 *buf = tmp 89 } 90 } 91 92 //go:nosplit 93 func Ptr2SlicePtr(s unsafe.Pointer, l int, c int) unsafe.Pointer { 94 slice := &GoSlice{ 95 Ptr: s, 96 Len: l, 97 Cap: c, 98 } 99 return unsafe.Pointer(slice) 100 } 101 102 //go:nosplit 103 func StrPtr(s string) unsafe.Pointer { 104 return (*GoString)(unsafe.Pointer(&s)).Ptr 105 } 106 107 //go:nosplit 108 func StrFrom(p unsafe.Pointer, n int64) (s string) { 109 (*GoString)(unsafe.Pointer(&s)).Ptr = p 110 (*GoString)(unsafe.Pointer(&s)).Len = int(n) 111 return 112 }