diff options
author | 2023-02-25 13:12:40 +0100 | |
---|---|---|
committer | 2023-02-25 12:12:40 +0000 | |
commit | ecdc8379fa8f9d88faca626e7de748c2afbe4910 (patch) | |
tree | 8c20a5826db2136fc89bee45e15355c5899fa65b /vendor/github.com/bytedance/sonic/internal/loader | |
parent | [bugfix] Fix deleted status causing issues when getting bookmark (#1551) (diff) | |
download | gotosocial-ecdc8379fa8f9d88faca626e7de748c2afbe4910.tar.xz |
[chore] Update gin to v1.9.0 (#1553)
Diffstat (limited to 'vendor/github.com/bytedance/sonic/internal/loader')
8 files changed, 1055 insertions, 0 deletions
diff --git a/vendor/github.com/bytedance/sonic/internal/loader/asm.s b/vendor/github.com/bytedance/sonic/internal/loader/asm.s new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/vendor/github.com/bytedance/sonic/internal/loader/asm.s diff --git a/vendor/github.com/bytedance/sonic/internal/loader/funcdata.go b/vendor/github.com/bytedance/sonic/internal/loader/funcdata.go new file mode 100644 index 000000000..59a3cb349 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/internal/loader/funcdata.go @@ -0,0 +1,124 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package loader + +import ( + `reflect` + `sync` + `unsafe` + + `github.com/bytedance/sonic/internal/rt` +) + +//go:linkname lastmoduledatap runtime.lastmoduledatap +//goland:noinspection GoUnusedGlobalVariable +var lastmoduledatap *_ModuleData + +//go:linkname moduledataverify1 runtime.moduledataverify1 +func moduledataverify1(_ *_ModuleData) + +// PCDATA and FUNCDATA table indexes. +// +// See funcdata.h and $GROOT/src/cmd/internal/objabi/funcdata.go. +const ( + _FUNCDATA_ArgsPointerMaps = 0 + _FUNCDATA_LocalsPointerMaps = 1 +) + +type funcInfo struct { + *_Func + datap *_ModuleData +} + +//go:linkname findfunc runtime.findfunc +func findfunc(pc uintptr) funcInfo + +//go:linkname funcdata runtime.funcdata +func funcdata(f funcInfo, i uint8) unsafe.Pointer + +var ( + modLock sync.Mutex + modList []*_ModuleData +) + +var emptyByte byte + +func encodeVariant(v int) []byte { + var u int + var r []byte + + /* split every 7 bits */ + for v > 127 { + u = v & 0x7f + v = v >> 7 + r = append(r, byte(u) | 0x80) + } + + /* check for last one */ + if v == 0 { + return r + } + + /* add the last one */ + r = append(r, byte(v)) + return r +} + +func registerModule(mod *_ModuleData) { + modLock.Lock() + modList = append(modList, mod) + lastmoduledatap.next = mod + lastmoduledatap = mod + modLock.Unlock() +} + +func stackMap(f interface{}) (args uintptr, locals uintptr) { + fv := reflect.ValueOf(f) + if fv.Kind() != reflect.Func { + panic("f must be reflect.Func kind!") + } + fi := findfunc(fv.Pointer()) + return uintptr(funcdata(fi, uint8(_FUNCDATA_ArgsPointerMaps))), uintptr(funcdata(fi, uint8(_FUNCDATA_LocalsPointerMaps))) +} + +var moduleCache = struct{ + m map[*_ModuleData][]byte + l sync.Mutex +}{ + m : make(map[*_ModuleData][]byte), +} + +func cacheStackmap(argPtrs []bool, localPtrs []bool, mod *_ModuleData) (argptrs uintptr, localptrs uintptr) { + as := rt.StackMapBuilder{} + for _, b := range argPtrs { + as.AddField(b) + } + ab, _ := as.Build().MarshalBinary() + ls := rt.StackMapBuilder{} + for _, b := range localPtrs { + ls.AddField(b) + } + lb, _ := ls.Build().MarshalBinary() + cache := make([]byte, len(ab) + len(lb)) + copy(cache, ab) + copy(cache[len(ab):], lb) + moduleCache.l.Lock() + moduleCache.m[mod] = cache + moduleCache.l.Unlock() + return uintptr(rt.IndexByte(cache, 0)), uintptr(rt.IndexByte(cache, len(ab))) + +}
\ No newline at end of file diff --git a/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go115.go b/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go115.go new file mode 100644 index 000000000..b0d2d6c65 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go115.go @@ -0,0 +1,169 @@ +// +build go1.15,!go1.16 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package loader + +import ( + `unsafe` + + `github.com/bytedance/sonic/internal/rt` +) + +type _Func struct { + entry uintptr // start pc + nameoff int32 // function name + args int32 // in/out args size + deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any. + pcsp int32 + pcfile int32 + pcln int32 + npcdata int32 + funcID uint8 // set for certain special runtime functions + _ [2]int8 // unused + nfuncdata uint8 // must be last + argptrs uintptr + localptrs uintptr +} + +type _FuncTab struct { + entry uintptr + funcoff uintptr +} + +type _BitVector struct { + n int32 // # of bits + bytedata *uint8 +} + +type _PtabEntry struct { + name int32 + typ int32 +} + +type _TextSection struct { + vaddr uintptr // prelinked section vaddr + length uintptr // section length + baseaddr uintptr // relocated section address +} + +type _ModuleData struct { + pclntable []byte + ftab []_FuncTab + filetab []uint32 + findfunctab *_FindFuncBucket + minpc, maxpc uintptr + text, etext uintptr + noptrdata, enoptrdata uintptr + data, edata uintptr + bss, ebss uintptr + noptrbss, enoptrbss uintptr + end, gcdata, gcbss uintptr + types, etypes uintptr + textsectmap []_TextSection + typelinks []int32 // offsets from types + itablinks []*rt.GoItab + ptab []_PtabEntry + pluginpath string + pkghashes []byte + modulename string + modulehashes []byte + hasmain uint8 // 1 if module contains the main function, 0 otherwise + gcdatamask, gcbssmask _BitVector + typemap map[int32]*rt.GoType // offset to *_rtype in previous module + bad bool // module failed to load and should be ignored + next *_ModuleData +} + +type _FindFuncBucket struct { + idx uint32 + subbuckets [16]byte +} + +var findFuncTab = &_FindFuncBucket { + idx: 1, +} + +func registerFunction(name string, pc uintptr, textSize uintptr, fp int, args int, size uintptr, argPtrs []bool, localPtrs []bool) { + mod := new(_ModuleData) + minpc := pc + maxpc := pc + size + + /* build the PC & line table */ + pclnt := []byte { + 0xfb, 0xff, 0xff, 0xff, // magic : 0xfffffffb + 0, // pad1 : 0 + 0, // pad2 : 0 + 1, // minLC : 1 + 4 << (^uintptr(0) >> 63), // ptrSize : 4 << (^uintptr(0) >> 63) + } + + // cache arg and local stackmap + argptrs, localptrs := cacheStackmap(argPtrs, localPtrs, mod) + + /* add the function name */ + noff := len(pclnt) + pclnt = append(append(pclnt, name...), 0) + + /* add PCDATA */ + pcsp := len(pclnt) + pclnt = append(pclnt, encodeVariant((fp + 1) << 1)...) + pclnt = append(pclnt, encodeVariant(int(size))...) + + /* function entry */ + fnv := _Func { + entry : pc, + nameoff : int32(noff), + args : int32(args), + pcsp : int32(pcsp), + nfuncdata : 2, + argptrs : uintptr(argptrs), + localptrs : uintptr(localptrs), + } + + /* align the func to 8 bytes */ + if p := len(pclnt) % 8; p != 0 { + pclnt = append(pclnt, make([]byte, 8 - p)...) + } + + /* add the function descriptor */ + foff := len(pclnt) + pclnt = append(pclnt, (*(*[unsafe.Sizeof(_Func{})]byte)(unsafe.Pointer(&fnv)))[:]...) + + /* function table */ + tab := []_FuncTab { + {entry: pc, funcoff: uintptr(foff)}, + {entry: pc, funcoff: uintptr(foff)}, + {entry: maxpc}, + } + + /* module data */ + *mod = _ModuleData { + pclntable : pclnt, + ftab : tab, + findfunctab : findFuncTab, + minpc : minpc, + maxpc : maxpc, + modulename : name, + gcdata: uintptr(unsafe.Pointer(&emptyByte)), + gcbss: uintptr(unsafe.Pointer(&emptyByte)), + } + + /* verify and register the new module */ + moduledataverify1(mod) + registerModule(mod) +} diff --git a/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go116.go b/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go116.go new file mode 100644 index 000000000..f01747f93 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go116.go @@ -0,0 +1,175 @@ +//go:build go1.16 && !go1.18 +// +build go1.16,!go1.18 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package loader + +import ( + `unsafe` +) + +type _Func struct { + entry uintptr // start pc + nameoff int32 // function name + args int32 // in/out args size + deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any. + pcsp uint32 + pcfile uint32 + pcln uint32 + npcdata uint32 + cuOffset uint32 // runtime.cutab offset of this function's CU + funcID uint8 // set for certain special runtime functions + _ [2]byte // pad + nfuncdata uint8 // must be last + argptrs uintptr + localptrs uintptr +} + +type _FuncTab struct { + entry uintptr + funcoff uintptr +} + +type _PCHeader struct { + magic uint32 // 0xFFFFFFFA + pad1, pad2 uint8 // 0,0 + minLC uint8 // min instruction size + ptrSize uint8 // size of a ptr in bytes + nfunc int // number of functions in the module + nfiles uint // number of entries in the file tab. + funcnameOffset uintptr // offset to the funcnametab variable from _PCHeader + cuOffset uintptr // offset to the cutab variable from _PCHeader + filetabOffset uintptr // offset to the filetab variable from _PCHeader + pctabOffset uintptr // offset to the pctab varible from _PCHeader + pclnOffset uintptr // offset to the pclntab variable from _PCHeader +} + +type _BitVector struct { + n int32 // # of bits + bytedata *uint8 +} + +type _PtabEntry struct { + name int32 + typ int32 +} + +type _TextSection struct { + vaddr uintptr // prelinked section vaddr + length uintptr // section length + baseaddr uintptr // relocated section address +} + +type _ModuleData struct { + pcHeader *_PCHeader + funcnametab []byte + cutab []uint32 + filetab []byte + pctab []byte + pclntable []_Func + ftab []_FuncTab + findfunctab *_FindFuncBucket + minpc, maxpc uintptr + text, etext uintptr + noptrdata, enoptrdata uintptr + data, edata uintptr + bss, ebss uintptr + noptrbss, enoptrbss uintptr + end, gcdata, gcbss uintptr + types, etypes uintptr + textsectmap []_TextSection + typelinks []int32 + itablinks []unsafe.Pointer + ptab []_PtabEntry + pluginpath string + pkghashes []struct{} + modulename string + modulehashes []struct{} + hasmain uint8 + gcdatamask, gcbssmask _BitVector + typemap map[int32]unsafe.Pointer + bad bool + next *_ModuleData +} + +type _FindFuncBucket struct { + idx uint32 + subbuckets [16]byte +} + +var modHeader = &_PCHeader { + magic : 0xfffffffa, + minLC : 1, + nfunc : 1, + ptrSize : 4 << (^uintptr(0) >> 63), +} + +var findFuncTab = &_FindFuncBucket { + idx: 1, +} + +func makePCtab(fp int) []byte { + return append([]byte{0}, encodeVariant((fp + 1) << 1)...) +} + +func registerFunction(name string, pc uintptr, textSize uintptr, fp int, args int, size uintptr, argPtrs []bool, localPtrs []bool) { + mod := new(_ModuleData) + + minpc := pc + maxpc := pc + size + + // cache arg and local stackmap + argptrs, localptrs := cacheStackmap(argPtrs, localPtrs, mod) + + /* function entry */ + lnt := []_Func {{ + entry : pc, + nameoff : 1, + args : int32(args), + pcsp : 1, + nfuncdata : 2, + argptrs : uintptr(argptrs), + localptrs : uintptr(localptrs), + }} + + /* function table */ + tab := []_FuncTab { + {entry: pc}, + {entry: pc}, + {entry: maxpc}, + } + + /* module data */ + *mod = _ModuleData { + pcHeader : modHeader, + funcnametab : append(append([]byte{0}, name...), 0), + pctab : append(makePCtab(fp), encodeVariant(int(size))...), + pclntable : lnt, + ftab : tab, + findfunctab : findFuncTab, + minpc : minpc, + maxpc : maxpc, + modulename : name, + gcdata: uintptr(unsafe.Pointer(&emptyByte)), + gcbss: uintptr(unsafe.Pointer(&emptyByte)), + } + + /* verify and register the new module */ + moduledataverify1(mod) + registerModule(mod) +}
\ No newline at end of file diff --git a/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go118.go b/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go118.go new file mode 100644 index 000000000..f1d585d97 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go118.go @@ -0,0 +1,201 @@ +// +build go1.18,!go1.20 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package loader + +import ( + `unsafe` + + `github.com/bytedance/sonic/internal/rt` +) + +// A FuncFlag holds bits about a function. +// This list must match the list in cmd/internal/objabi/funcid.go. +type funcFlag uint8 + +type _Func struct { + entryOff uint32 // start pc + nameoff int32 // function name + args int32 // in/out args size + deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any. + pcsp uint32 + pcfile uint32 + pcln uint32 + npcdata uint32 + cuOffset uint32 // runtime.cutab offset of this function's CU + funcID uint8 // set for certain special runtime functions + flag funcFlag + _ [1]byte // pad + nfuncdata uint8 // must be last + argptrs uint32 + localptrs uint32 +} + +type _FuncTab struct { + entry uint32 + funcoff uint32 +} + +type _PCHeader struct { + magic uint32 // 0xFFFFFFF0 + pad1, pad2 uint8 // 0,0 + minLC uint8 // min instruction size + ptrSize uint8 // size of a ptr in bytes + nfunc int // number of functions in the module + nfiles uint // number of entries in the file tab + textStart uintptr // base for function entry PC offsets in this module, equal to moduledata.text + funcnameOffset uintptr // offset to the funcnametab variable from pcHeader + cuOffset uintptr // offset to the cutab variable from pcHeader + filetabOffset uintptr // offset to the filetab variable from pcHeader + pctabOffset uintptr // offset to the pctab variable from pcHeader + pclnOffset uintptr // offset to the pclntab variable from pcHeader +} + +type _BitVector struct { + n int32 // # of bits + bytedata *uint8 +} + +type _PtabEntry struct { + name int32 + typ int32 +} + +type _TextSection struct { + vaddr uintptr // prelinked section vaddr + length uintptr // section length + baseaddr uintptr // relocated section address +} + +type _ModuleData struct { + pcHeader *_PCHeader + funcnametab []byte + cutab []uint32 + filetab []byte + pctab []byte + pclntable []byte + ftab []_FuncTab + findfunctab *_FindFuncBucket + minpc, maxpc uintptr + text, etext uintptr + noptrdata, enoptrdata uintptr + data, edata uintptr + bss, ebss uintptr + noptrbss, enoptrbss uintptr + end, gcdata, gcbss uintptr + types, etypes uintptr + rodata uintptr + gofunc uintptr + textsectmap []_TextSection + typelinks []int32 + itablinks []unsafe.Pointer + ptab []_PtabEntry + pluginpath string + pkghashes []struct{} + modulename string + modulehashes []struct{} + hasmain uint8 + gcdatamask, gcbssmask _BitVector + typemap map[int32]unsafe.Pointer + bad bool + next *_ModuleData +} + + +type _FindFuncBucket struct { + idx uint32 + subbuckets [16]byte +} + + + +func makePCtab(fp int) []byte { + return append([]byte{0}, encodeVariant((fp + 1) << 1)...) +} + +func registerFunction(name string, pc uintptr, textSize uintptr, fp int, args int, size uintptr, argPtrs []bool, localPtrs []bool) { + mod := new(_ModuleData) + + minpc := pc + maxpc := pc + size + + findFuncTab := make([]_FindFuncBucket, textSize/4096 + 1) + + modHeader := &_PCHeader { + magic : 0xfffffff0, + minLC : 1, + nfunc : 1, + ptrSize : 4 << (^uintptr(0) >> 63), + textStart: minpc, + } + + // cache arg and local stackmap + argptrs, localptrs := cacheStackmap(argPtrs, localPtrs, mod) + + base := argptrs + if argptrs > localptrs { + base = localptrs + } + + /* function entry */ + lnt := []_Func {{ + entryOff : 0, + nameoff : 1, + args : int32(args), + pcsp : 1, + nfuncdata : 2, + argptrs: uint32(argptrs - base), + localptrs: uint32(localptrs - base), + }} + nlnt := len(lnt)*int(unsafe.Sizeof(_Func{})) + plnt := unsafe.Pointer(&lnt[0]) + + /* function table */ + ftab := []_FuncTab { + {entry : 0, funcoff : 16}, + {entry : uint32(size)}, + } + nftab := len(ftab)*int(unsafe.Sizeof(_FuncTab{})) + pftab := unsafe.Pointer(&ftab[0]) + + pclntab := make([]byte, 0, nftab + nlnt) + pclntab = append(pclntab, rt.BytesFrom(pftab, nftab, nftab)...) + pclntab = append(pclntab, rt.BytesFrom(plnt, nlnt, nlnt)...) + + /* module data */ + *mod = _ModuleData { + pcHeader : modHeader, + funcnametab : append(append([]byte{0}, name...), 0), + pctab : append(makePCtab(fp), encodeVariant(int(size))...), + pclntable : pclntab, + ftab : ftab, + text : minpc, + etext : pc + textSize, + findfunctab : &findFuncTab[0], + minpc : minpc, + maxpc : maxpc, + modulename : name, + gcdata: uintptr(unsafe.Pointer(&emptyByte)), + gcbss: uintptr(unsafe.Pointer(&emptyByte)), + gofunc: base, + } + + /* verify and register the new module */ + moduledataverify1(mod) + registerModule(mod) +}
\ No newline at end of file diff --git a/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go120.go b/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go120.go new file mode 100644 index 000000000..c12f8a73c --- /dev/null +++ b/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go120.go @@ -0,0 +1,201 @@ +// +build go1.20 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package loader + +import ( + `unsafe` + + `github.com/bytedance/sonic/internal/rt` +) + +// A FuncFlag holds bits about a function. +// This list must match the list in cmd/internal/objabi/funcid.go. +type funcFlag uint8 + +type _Func struct { + entryOff uint32 // start pc + nameoff int32 // function name + args int32 // in/out args size + deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any. + pcsp uint32 + pcfile uint32 + pcln uint32 + npcdata uint32 + cuOffset uint32 // runtime.cutab offset of this function's CU + funcID uint8 // set for certain special runtime functions + flag funcFlag + _ [1]byte // pad + nfuncdata uint8 // must be last + argptrs uint32 + localptrs uint32 +} + +type _FuncTab struct { + entry uint32 + funcoff uint32 +} + +type _PCHeader struct { + magic uint32 // 0xFFFFFFF0 + pad1, pad2 uint8 // 0,0 + minLC uint8 // min instruction size + ptrSize uint8 // size of a ptr in bytes + nfunc int // number of functions in the module + nfiles uint // number of entries in the file tab + textStart uintptr // base for function entry PC offsets in this module, equal to moduledata.text + funcnameOffset uintptr // offset to the funcnametab variable from pcHeader + cuOffset uintptr // offset to the cutab variable from pcHeader + filetabOffset uintptr // offset to the filetab variable from pcHeader + pctabOffset uintptr // offset to the pctab variable from pcHeader + pclnOffset uintptr // offset to the pclntab variable from pcHeader +} + +type _BitVector struct { + n int32 // # of bits + bytedata *uint8 +} + +type _PtabEntry struct { + name int32 + typ int32 +} + +type _TextSection struct { + vaddr uintptr // prelinked section vaddr + length uintptr // section length + baseaddr uintptr // relocated section address +} + +type _ModuleData struct { + pcHeader *_PCHeader + funcnametab []byte + cutab []uint32 + filetab []byte + pctab []byte + pclntable []byte + ftab []_FuncTab + findfunctab *_FindFuncBucket + minpc, maxpc uintptr + text, etext uintptr + noptrdata, enoptrdata uintptr + data, edata uintptr + bss, ebss uintptr + noptrbss, enoptrbss uintptr + end, gcdata, gcbss uintptr + types, etypes uintptr + rodata uintptr + gofunc uintptr + textsectmap []_TextSection + typelinks []int32 + itablinks []unsafe.Pointer + ptab []_PtabEntry + pluginpath string + pkghashes []struct{} + modulename string + modulehashes []struct{} + hasmain uint8 + gcdatamask, gcbssmask _BitVector + typemap map[int32]unsafe.Pointer + bad bool + next *_ModuleData +} + + +type _FindFuncBucket struct { + idx uint32 + subbuckets [16]byte +} + + + +func makePCtab(fp int) []byte { + return append([]byte{0}, encodeVariant((fp + 1) << 1)...) +} + +func registerFunction(name string, pc uintptr, textSize uintptr, fp int, args int, size uintptr, argPtrs []bool, localPtrs []bool) { + mod := new(_ModuleData) + + minpc := pc + maxpc := pc + size + + findFuncTab := make([]_FindFuncBucket, textSize/4096 + 1) + + modHeader := &_PCHeader { + magic : 0xfffffff0, + minLC : 1, + nfunc : 1, + ptrSize : 4 << (^uintptr(0) >> 63), + textStart: minpc, + } + + // cache arg and local stackmap + argptrs, localptrs := cacheStackmap(argPtrs, localPtrs, mod) + + base := argptrs + if argptrs > localptrs { + base = localptrs + } + + /* function entry */ + lnt := []_Func {{ + entryOff : 0, + nameoff : 1, + args : int32(args), + pcsp : 1, + nfuncdata : 2, + argptrs: uint32(argptrs - base), + localptrs: uint32(localptrs - base), + }} + nlnt := len(lnt)*int(unsafe.Sizeof(_Func{})) + plnt := unsafe.Pointer(&lnt[0]) + + /* function table */ + ftab := []_FuncTab { + {entry : 0, funcoff : 16}, + {entry : uint32(size)}, + } + nftab := len(ftab)*int(unsafe.Sizeof(_FuncTab{})) + pftab := unsafe.Pointer(&ftab[0]) + + pclntab := make([]byte, 0, nftab + nlnt) + pclntab = append(pclntab, rt.BytesFrom(pftab, nftab, nftab)...) + pclntab = append(pclntab, rt.BytesFrom(plnt, nlnt, nlnt)...) + + /* module data */ + *mod = _ModuleData { + pcHeader : modHeader, + funcnametab : append(append([]byte{0}, name...), 0), + pctab : append(makePCtab(fp), encodeVariant(int(size))...), + pclntable : pclntab, + ftab : ftab, + text : minpc, + etext : pc + textSize, + findfunctab : &findFuncTab[0], + minpc : minpc, + maxpc : maxpc, + modulename : name, + gcdata: uintptr(unsafe.Pointer(&emptyByte)), + gcbss: uintptr(unsafe.Pointer(&emptyByte)), + gofunc: base, + } + + /* verify and register the new module */ + moduledataverify1(mod) + registerModule(mod) +}
\ No newline at end of file diff --git a/vendor/github.com/bytedance/sonic/internal/loader/loader.go b/vendor/github.com/bytedance/sonic/internal/loader/loader.go new file mode 100644 index 000000000..6446a5f07 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/internal/loader/loader.go @@ -0,0 +1,74 @@ +//go:build darwin || linux +// +build darwin linux + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package loader + +import ( + `fmt` + `os` + `reflect` + `syscall` + `unsafe` +) + +const ( + _AP = syscall.MAP_ANON | syscall.MAP_PRIVATE + _RX = syscall.PROT_READ | syscall.PROT_EXEC + _RW = syscall.PROT_READ | syscall.PROT_WRITE +) + +type Loader []byte +type Function unsafe.Pointer + +func (self Loader) Load(fn string, fp int, args int, argPtrs []bool, localPtrs []bool) (f Function) { + p := os.Getpagesize() + n := (((len(self) - 1) / p) + 1) * p + + /* register the function */ + m := mmap(n) + v := fmt.Sprintf("runtime.__%s_%x", fn, m) + + registerFunction(v, m, uintptr(n), fp, args, uintptr(len(self)), argPtrs, localPtrs) + + /* reference as a slice */ + s := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader { + Data : m, + Cap : n, + Len : len(self), + })) + + /* copy the machine code, and make it executable */ + copy(s, self) + mprotect(m, n) + return Function(&m) +} + +func mmap(nb int) uintptr { + if m, _, e := syscall.RawSyscall6(syscall.SYS_MMAP, 0, uintptr(nb), _RW, _AP, 0, 0); e != 0 { + panic(e) + } else { + return m + } +} + +func mprotect(p uintptr, nb int) { + if _, _, err := syscall.RawSyscall(syscall.SYS_MPROTECT, p, uintptr(nb), _RX); err != 0 { + panic(err) + } +} diff --git a/vendor/github.com/bytedance/sonic/internal/loader/loader_windows.go b/vendor/github.com/bytedance/sonic/internal/loader/loader_windows.go new file mode 100644 index 000000000..4053ee9bb --- /dev/null +++ b/vendor/github.com/bytedance/sonic/internal/loader/loader_windows.go @@ -0,0 +1,111 @@ +//go:build windows +// +build windows + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package loader + +import ( + `fmt` + `os` + `reflect` + `syscall` + `unsafe` +) + +const ( + MEM_COMMIT = 0x00001000 + MEM_RESERVE = 0x00002000 +) + +var ( + libKernel32 = syscall.NewLazyDLL("KERNEL32.DLL") + libKernel32_VirtualAlloc = libKernel32.NewProc("VirtualAlloc") + libKernel32_VirtualProtect = libKernel32.NewProc("VirtualProtect") +) + +type Loader []byte +type Function unsafe.Pointer + +func (self Loader) Load(fn string, fp int, args int, argPtrs []bool, localPtrs []bool) (f Function) { + p := os.Getpagesize() + n := (((len(self) - 1) / p) + 1) * p + + /* register the function */ + m := mmap(n) + v := fmt.Sprintf("runtime.__%s_%x", fn, m) + + registerFunction(v, m, uintptr(n), fp, args, uintptr(len(self)), argPtrs, localPtrs) + + /* reference as a slice */ + s := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader { + Data : m, + Cap : n, + Len : len(self), + })) + + /* copy the machine code, and make it executable */ + copy(s, self) + mprotect(m, n) + return Function(&m) +} + +func mmap(nb int) uintptr { + addr, err := winapi_VirtualAlloc(0, nb, MEM_COMMIT|MEM_RESERVE, syscall.PAGE_READWRITE) + if err != nil { + panic(err) + } + return addr +} + +func mprotect(p uintptr, nb int) (oldProtect int) { + err := winapi_VirtualProtect(p, nb, syscall.PAGE_EXECUTE_READ, &oldProtect) + if err != nil { + panic(err) + } + return +} + +// winapi_VirtualAlloc allocate memory +// Doc: https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc +func winapi_VirtualAlloc(lpAddr uintptr, dwSize int, flAllocationType int, flProtect int) (uintptr, error) { + r1, _, err := libKernel32_VirtualAlloc.Call( + lpAddr, + uintptr(dwSize), + uintptr(flAllocationType), + uintptr(flProtect), + ) + if r1 == 0 { + return 0, err + } + return r1, nil +} + +// winapi_VirtualProtect change memory protection +// Doc: https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualprotect +func winapi_VirtualProtect(lpAddr uintptr, dwSize int, flNewProtect int, lpflOldProtect *int) error { + r1, _, err := libKernel32_VirtualProtect.Call( + lpAddr, + uintptr(dwSize), + uintptr(flNewProtect), + uintptr(unsafe.Pointer(lpflOldProtect)), + ) + if r1 == 0 { + return err + } + return nil +} |