summaryrefslogtreecommitdiff
path: root/vendor/github.com/bytedance/sonic/internal/loader
diff options
context:
space:
mode:
authorLibravatar Daenney <daenney@users.noreply.github.com>2023-02-25 13:12:40 +0100
committerLibravatar GitHub <noreply@github.com>2023-02-25 12:12:40 +0000
commitecdc8379fa8f9d88faca626e7de748c2afbe4910 (patch)
tree8c20a5826db2136fc89bee45e15355c5899fa65b /vendor/github.com/bytedance/sonic/internal/loader
parent[bugfix] Fix deleted status causing issues when getting bookmark (#1551) (diff)
downloadgotosocial-ecdc8379fa8f9d88faca626e7de748c2afbe4910.tar.xz
[chore] Update gin to v1.9.0 (#1553)
Diffstat (limited to 'vendor/github.com/bytedance/sonic/internal/loader')
-rw-r--r--vendor/github.com/bytedance/sonic/internal/loader/asm.s0
-rw-r--r--vendor/github.com/bytedance/sonic/internal/loader/funcdata.go124
-rw-r--r--vendor/github.com/bytedance/sonic/internal/loader/funcdata_go115.go169
-rw-r--r--vendor/github.com/bytedance/sonic/internal/loader/funcdata_go116.go175
-rw-r--r--vendor/github.com/bytedance/sonic/internal/loader/funcdata_go118.go201
-rw-r--r--vendor/github.com/bytedance/sonic/internal/loader/funcdata_go120.go201
-rw-r--r--vendor/github.com/bytedance/sonic/internal/loader/loader.go74
-rw-r--r--vendor/github.com/bytedance/sonic/internal/loader/loader_windows.go111
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
+}