gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

funcdata.go (3045B)


      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 loader
     18 
     19 import (
     20     `reflect`
     21     `sync`
     22     `unsafe`
     23 
     24     `github.com/bytedance/sonic/internal/rt`
     25 )
     26 
     27 //go:linkname lastmoduledatap runtime.lastmoduledatap
     28 //goland:noinspection GoUnusedGlobalVariable
     29 var lastmoduledatap *_ModuleData
     30 
     31 //go:linkname moduledataverify1 runtime.moduledataverify1
     32 func moduledataverify1(_ *_ModuleData)
     33 
     34 // PCDATA and FUNCDATA table indexes.
     35 //
     36 // See funcdata.h and $GROOT/src/cmd/internal/objabi/funcdata.go.
     37 const (
     38     _FUNCDATA_ArgsPointerMaps = 0
     39     _FUNCDATA_LocalsPointerMaps = 1
     40 )
     41 
     42 type funcInfo struct {
     43     *_Func
     44     datap *_ModuleData
     45 }
     46 
     47 //go:linkname findfunc runtime.findfunc
     48 func findfunc(pc uintptr) funcInfo
     49 
     50 //go:linkname funcdata runtime.funcdata
     51 func funcdata(f funcInfo, i uint8) unsafe.Pointer
     52 
     53 var (
     54     modLock sync.Mutex
     55     modList []*_ModuleData
     56 )
     57 
     58 var emptyByte byte
     59 
     60 func encodeVariant(v int) []byte {
     61     var u int
     62     var r []byte
     63 
     64     /* split every 7 bits */
     65     for v > 127 {
     66         u = v & 0x7f
     67         v = v >> 7
     68         r = append(r, byte(u) | 0x80)
     69     }
     70 
     71     /* check for last one */
     72     if v == 0 {
     73         return r
     74     }
     75 
     76     /* add the last one */
     77     r = append(r, byte(v))
     78     return r
     79 }
     80 
     81 func registerModule(mod *_ModuleData) {
     82     modLock.Lock()
     83     modList = append(modList, mod)
     84     lastmoduledatap.next = mod
     85     lastmoduledatap = mod
     86     modLock.Unlock()
     87 }
     88 
     89 func stackMap(f interface{}) (args uintptr, locals uintptr) {
     90     fv := reflect.ValueOf(f)
     91     if fv.Kind() != reflect.Func {
     92         panic("f must be reflect.Func kind!")
     93     }
     94     fi := findfunc(fv.Pointer())
     95     return uintptr(funcdata(fi, uint8(_FUNCDATA_ArgsPointerMaps))), uintptr(funcdata(fi, uint8(_FUNCDATA_LocalsPointerMaps)))
     96 }
     97 
     98 var moduleCache = struct{
     99     m map[*_ModuleData][]byte
    100     l sync.Mutex
    101 }{
    102     m : make(map[*_ModuleData][]byte),
    103 }
    104 
    105 func cacheStackmap(argPtrs []bool, localPtrs []bool, mod *_ModuleData) (argptrs uintptr, localptrs uintptr) {
    106     as := rt.StackMapBuilder{}
    107     for _, b := range argPtrs {
    108         as.AddField(b)
    109     }
    110     ab, _ := as.Build().MarshalBinary()
    111     ls := rt.StackMapBuilder{}
    112     for _, b := range localPtrs {
    113         ls.AddField(b)
    114     }
    115     lb, _ := ls.Build().MarshalBinary()
    116     cache := make([]byte, len(ab) + len(lb))
    117     copy(cache, ab)
    118     copy(cache[len(ab):], lb)
    119     moduleCache.l.Lock()
    120     moduleCache.m[mod] = cache
    121     moduleCache.l.Unlock()
    122     return uintptr(rt.IndexByte(cache, 0)), uintptr(rt.IndexByte(cache, len(ab)))
    123 
    124 }