github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/internal/rt/fastmem.go (about)

     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  	"reflect"
    21  	"unsafe"
    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  }
   113  
   114  // NoEscape hides a pointer from escape analysis. NoEscape is
   115  // the identity function but escape analysis doesn't think the
   116  // output depends on the input. NoEscape is inlined and currently
   117  // compiles down to zero instructions.
   118  // USE CAREFULLY!
   119  //
   120  //go:nosplit
   121  //goland:noinspection GoVetUnsafePointer
   122  func NoEscape(p unsafe.Pointer) unsafe.Pointer {
   123  	x := uintptr(p)
   124  	return unsafe.Pointer(x ^ 0)
   125  }