diff --git a/ast/b64_amd64.go b/ast/b64_amd64.go deleted file mode 100644 index b62ec52b3..000000000 --- a/ast/b64_amd64.go +++ /dev/null @@ -1,31 +0,0 @@ -// +build amd64,go1.17 - -/** - * Copyright 2023 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 ast - -import ( - `github.com/cloudwego/base64x` -) - -func decodeBase64(src string) ([]byte, error) { - return base64x.StdEncoding.DecodeString(src) -} - -func encodeBase64(src []byte) string { - return base64x.StdEncoding.EncodeToString(src) -} diff --git a/ast/b64_compat.go b/ast/b64_compat.go deleted file mode 100644 index a7f84cfa3..000000000 --- a/ast/b64_compat.go +++ /dev/null @@ -1,31 +0,0 @@ -// +build !amd64 !go1.17 - -/* - * Copyright 2022 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 ast - -import ( - `encoding/base64` -) - -func decodeBase64(src string) ([]byte, error) { - return base64.StdEncoding.DecodeString(src) -} - -func encodeBase64(src []byte) string { - return base64.StdEncoding.EncodeToString(src) -} diff --git a/ast/encode.go b/ast/encode.go index 956809c2c..b5bcd4c2d 100644 --- a/ast/encode.go +++ b/ast/encode.go @@ -17,8 +17,10 @@ package ast import ( - `sync` - `unicode/utf8` + "sync" + "unicode/utf8" + + "github.com/bytedance/sonic/internal/rt" ) const ( @@ -30,7 +32,7 @@ func quoteString(e *[]byte, s string) { start := 0 for i := 0; i < len(s); { if b := s[i]; b < utf8.RuneSelf { - if safeSet[b] { + if rt.SafeSet[b] { i++ continue } @@ -54,8 +56,8 @@ func quoteString(e *[]byte, s string) { // user-controlled strings are rendered into JSON // and served to some browsers. *e = append(*e, `u00`...) - *e = append(*e, hex[b>>4]) - *e = append(*e, hex[b&0xF]) + *e = append(*e, rt.Hex[b>>4]) + *e = append(*e, rt.Hex[b&0xF]) } i++ start = i @@ -76,7 +78,7 @@ func quoteString(e *[]byte, s string) { *e = append(*e, s[start:i]...) } *e = append(*e, `\u202`...) - *e = append(*e, hex[c&0xF]) + *e = append(*e, rt.Hex[c&0xF]) i += size start = i continue diff --git a/ast/node.go b/ast/node.go index ac6d22808..1a77a1fa1 100644 --- a/ast/node.go +++ b/ast/node.go @@ -1653,7 +1653,7 @@ func NewBytes(src []byte) Node { if len(src) == 0 { panic("empty src bytes") } - out := encodeBase64(src) + out := rt.EncodeBase64(src) return NewString(out) } diff --git a/ast/stubs.go b/ast/stubs.go index ae08f33d6..89bdb6750 100644 --- a/ast/stubs.go +++ b/ast/stubs.go @@ -18,7 +18,6 @@ package ast import ( `unsafe` - `unicode/utf8` `github.com/bytedance/sonic/internal/rt` ) @@ -37,13 +36,5 @@ func mem2ptr(s []byte) unsafe.Pointer { return (*rt.GoSlice)(unsafe.Pointer(&s)).Ptr } -var ( - //go:linkname safeSet encoding/json.safeSet - safeSet [utf8.RuneSelf]bool - - //go:linkname hex encoding/json.hex - hex string -) - //go:linkname unquoteBytes encoding/json.unquoteBytes func unquoteBytes(s []byte) (t []byte, ok bool) diff --git a/internal/decoder/optdec/node.go b/internal/decoder/optdec/node.go index 8b29e03cc..d55c2eaa7 100644 --- a/internal/decoder/optdec/node.go +++ b/internal/decoder/optdec/node.go @@ -967,11 +967,7 @@ func AsEfaceFast(iter *NodeIter, ctx *Context) interface{} { val = sp goto _arr_val; } else { - ctx.efacePool.ConvTSlice(rt.GoSlice{ - Ptr: rt.ZSTPtr, - Len: 0, - Cap: 0, - }, rt.SliceEfaceType, unsafe.Pointer(&root)) + ctx.efacePool.ConvTSlice(rt.EmptySlice, rt.SliceEfaceType, unsafe.Pointer(&root)) } case KStringCommon: ctx.efacePool.ConvTstring(node.StringRef(ctx), unsafe.Pointer(&root)) case KStringEscaped: ctx.efacePool.ConvTstring(node.StringCopyEsc(ctx), unsafe.Pointer(&root)) @@ -993,9 +989,8 @@ _object_key: } else { key = node.StringCopyEsc(ctx) } - // interface{} slot in map bucket - //println("key is **", key, "** mp is ", mp) + // interface{} slot in map bucket val = rt.Mapassign_faststr(rt.MapEfaceMapType, mp, key) vt = &(*rt.GoEface)(val).Type vp = &(*rt.GoEface)(val).Value @@ -1021,11 +1016,7 @@ _object_key: case KArray: newSize := node.Array().Len() if newSize == 0 { - ctx.efacePool.ConvTSlice(rt.GoSlice{ - Ptr: rt.ZSTPtr, - Len: 0, - Cap: 0, - }, rt.SliceEfaceType, val) + ctx.efacePool.ConvTSlice(rt.EmptySlice, rt.SliceEfaceType, val) break; } @@ -1124,11 +1115,7 @@ _arr_val: case KArray: newSize := node.Array().Len() if newSize == 0 { - ctx.efacePool.ConvTSlice(rt.GoSlice{ - Ptr: rt.ZSTPtr, - Len: newSize, - Cap: newSize, - }, rt.SliceEfaceType, val) + ctx.efacePool.ConvTSlice(rt.EmptySlice, rt.SliceEfaceType, val) break; } diff --git a/internal/decoder/optdec/options.go b/internal/decoder/optdec/options.go deleted file mode 100644 index 416af1d29..000000000 --- a/internal/decoder/optdec/options.go +++ /dev/null @@ -1,58 +0,0 @@ -package optdec - -// type Options uint64 - -// const ( -// OptionUseInt64 Options = 1 << _F_use_int64 // 1 -// OptionUseNumber Options = 1 << _F_use_number // 2 -// OptionUseUnicodeErrors Options = 1 << _F_disable_urc // 4 -// OptionDisableUnknown Options = 1 << _F_disable_unknown // 8 -// OptionCopyString Options = 1 << _F_copy_string // 16 -// OptionValidateString Options = 1 << _F_validate_string // 32 -// ) - -// func (self *Decoder) SetOptions(opts Options) { -// if (opts&OptionUseNumber != 0) && (opts&OptionUseInt64 != 0) { -// panic("can't set OptionUseInt64 and OptionUseNumber both!") -// } -// self.opts = opts -// } - -// // UseInt64 indicates the Decoder to unmarshal an integer into an interface{} as an -// // int64 instead of as a float64. -// func (self *Decoder) UseInt64() { -// self.opts |= 1 << _F_use_int64 -// self.opts &^= 1 << _F_use_number -// } - -// // UseNumber indicates the Decoder to unmarshal a number into an interface{} as a -// // json.Number instead of as a float64. -// func (self *Decoder) UseNumber() { -// self.opts &^= 1 << _F_use_int64 -// self.opts |= 1 << _F_use_number -// } - -// // UseUnicodeErrors indicates the Decoder to return an error when encounter invalid -// // UTF-8 escape sequences. -// func (self *Decoder) UseUnicodeErrors() { -// self.opts |= 1 << _F_disable_urc -// } - -// // DisallowUnknownFields indicates the Decoder to return an error when the destination -// // is a struct and the input contains object keys which do not match any -// // non-ignored, exported fields in the destination. -// func (self *Decoder) DisallowUnknownFields() { -// self.opts |= 1 << _F_disable_unknown -// } - -// // CopyString indicates the Decoder to decode string values by copying instead of referring. -// func (self *Decoder) CopyString() { -// self.opts |= 1 << _F_copy_string -// } - -// // ValidateString causes the Decoder to validate string values when decoding string value -// // in JSON. Validation is that, returning error when unescaped control chars(0x00-0x1f) or -// // invalid UTF-8 chars in the string value of JSON. -// func (self *Decoder) ValidateString() { -// self.opts |= 1 << _F_validate_string -// } diff --git a/internal/encoder/alg/spec_compat.go b/internal/encoder/alg/spec_compat.go index aba6331f4..5bb7b042e 100644 --- a/internal/encoder/alg/spec_compat.go +++ b/internal/encoder/alg/spec_compat.go @@ -55,7 +55,7 @@ func Quote(e []byte, s string, double bool) []byte { for i := 0; i < len(s); { if b := s[i]; b < utf8.RuneSelf { - if safeSet[b] { + if rt.SafeSet[b] { i++ continue } @@ -79,8 +79,8 @@ func Quote(e []byte, s string, double bool) []byte { // user-controlled strings are rendered into JSON // and served to some browsers. e = append(e, `u00`...) - e = append(e, hex[b>>4]) - e = append(e, hex[b&0xF]) + e = append(e, rt.Hex[b>>4]) + e = append(e, rt.Hex[b&0xF]) } i++ start = i @@ -101,7 +101,7 @@ func Quote(e []byte, s string, double bool) []byte { e = append(e, s[start:i]...) } e = append(e, `\u202`...) - e = append(e, hex[c&0xF]) + e = append(e, rt.Hex[c&0xF]) i += size start = i continue @@ -121,14 +121,6 @@ func Quote(e []byte, s string, double bool) []byte { } } -var ( - //go:linkname safeSet encoding/json.safeSet - safeSet [utf8.RuneSelf]bool - - //go:linkname hex encoding/json.hex - hex string -) - func HtmlEscape(dst []byte, src []byte) []byte { buf := bytes.NewBuffer(dst) json.HTMLEscape(buf, src) diff --git a/internal/rt/asm_amd64.s b/internal/rt/asm_amd64.s index 8250e38d3..86d264230 100644 --- a/internal/rt/asm_amd64.s +++ b/internal/rt/asm_amd64.s @@ -18,43 +18,3 @@ _entry: _stack_grow: CALL runtime·morestack_noctxt<>(SB) JMP _entry - - -TEXT ·StopProf(SB), NOSPLIT, $0-0 - NO_LOCAL_POINTERS - CMPB github·com∕bytedance∕sonic∕internal∕rt·StopProfiling(SB), $0 - JEQ _ret_1 - MOVL $1, AX - LEAQ github·com∕bytedance∕sonic∕internal∕rt·yieldCount(SB), CX - LOCK - XADDL AX, (CX) - MOVL runtime·prof+4(SB), AX - TESTL AX, AX - JEQ _ret_1 - MOVL AX, github·com∕bytedance∕sonic∕internal∕rt·oldHz(SB) - MOVL $0, runtime·prof+4(SB) -_ret_1: - RET - - -TEXT ·StartProf(SB), NOSPLIT, $0-0 - NO_LOCAL_POINTERS - CMPB github·com∕bytedance∕sonic∕internal∕rt·StopProfiling(SB), $0 - JEQ _ret_2 - MOVL $-1, AX - LEAQ github·com∕bytedance∕sonic∕internal∕rt·yieldCount(SB), CX - LOCK - XADDL AX, (CX) - CMPL github·com∕bytedance∕sonic∕internal∕rt·yieldCount(SB), $0 - JNE _ret_2 - CMPL runtime·prof+4(SB), $0 - JNE _ret_2 - CMPL github·com∕bytedance∕sonic∕internal∕rt·oldHz(SB), $0 - JNE _branch_1 - MOVL $100, github·com∕bytedance∕sonic∕internal∕rt·oldHz(SB) -_branch_1: - MOVL github·com∕bytedance∕sonic∕internal∕rt·oldHz(SB), AX - MOVL AX, runtime·prof+4(SB) -_ret_2: - RET - \ No newline at end of file diff --git a/internal/rt/base64_amd64.go b/internal/rt/base64_amd64.go index 69b31bada..cbbe346f5 100644 --- a/internal/rt/base64_amd64.go +++ b/internal/rt/base64_amd64.go @@ -14,3 +14,7 @@ func DecodeBase64(raw []byte) ([]byte, error) { } return ret[:n], nil } + +func EncodeBase64(src []byte) string { + return base64x.StdEncoding.EncodeToString(src) +} diff --git a/internal/rt/base64_compat.go b/internal/rt/base64_compat.go index f3518861f..5d5c10cdb 100644 --- a/internal/rt/base64_compat.go +++ b/internal/rt/base64_compat.go @@ -14,3 +14,7 @@ func DecodeBase64(raw []byte) ([]byte, error) { } return ret[:n], nil } + +func EncodeBase64(src []byte) string { + return base64.StdEncoding.EncodeToString(src) +} diff --git a/internal/rt/rt_stubs_go116.go b/internal/rt/rt_stubs_go116.go index a2961f067..2c60e164c 100644 --- a/internal/rt/rt_stubs_go116.go +++ b/internal/rt/rt_stubs_go116.go @@ -7,8 +7,6 @@ import ( "unsafe" ) -//go:linkname roundupsize runtime.roundupsize -func roundupsize(size uintptr) uintptr //go:linkname makeslice runtime.makeslice //goland:noinspection GoUnusedParameter @@ -16,11 +14,7 @@ func makeslice(et *GoType, len int, cap int) unsafe.Pointer func MakeSlice(oldPtr unsafe.Pointer, et *GoType, newLen int) *GoSlice { if newLen == 0 { - return &GoSlice{ - Ptr: ZSTPtr, - Len: 0, - Cap: 0, - } + return &EmptySlice } if *(*unsafe.Pointer)(oldPtr) == nil { diff --git a/internal/rt/rt_stubs_go120.go b/internal/rt/rt_stubs_go120.go index ddde46bf6..735be152d 100644 --- a/internal/rt/rt_stubs_go120.go +++ b/internal/rt/rt_stubs_go120.go @@ -1,5 +1,5 @@ -//go:build go1.20 && !go1.22 -// +build go1.20,!go1.22 +//go:build go1.20 && !go1.23 +// +build go1.20,!go1.23 package rt @@ -7,20 +7,13 @@ import ( "unsafe" ) -//go:linkname roundupsize runtime.roundupsize -func roundupsize(size uintptr) uintptr - //go:linkname makeslice runtime.makeslice //goland:noinspection GoUnusedParameter func makeslice(et *GoType, len int, cap int) unsafe.Pointer func MakeSlice(oldPtr unsafe.Pointer, et *GoType, newLen int) *GoSlice { if newLen == 0 { - return &GoSlice{ - Ptr: ZSTPtr, - Len: 0, - Cap: 0, - } + return &EmptySlice } if *(*unsafe.Pointer)(oldPtr) == nil { diff --git a/internal/rt/rt_stubs_go123.go b/internal/rt/rt_stubs_go123.go deleted file mode 100644 index 91eb2844d..000000000 --- a/internal/rt/rt_stubs_go123.go +++ /dev/null @@ -1,48 +0,0 @@ -//go:build go1.22 && !go1.23 -// +build go1.22,!go1.23 - -package rt - -import ( - "unsafe" -) - -//go:linkname rt_roundupsize runtime.roundupsize -func rt_roundupsize(size uintptr, noscan bool) uintptr - -// a wrapper for fastmap -func roundupsize(size uintptr) uintptr { - return rt_roundupsize(size, MapType(MapEfaceType).Bucket.PtrData == 0) -} - -//go:linkname makeslice runtime.makeslice -//goland:noinspection GoUnusedParameter -func makeslice(et *GoType, len int, cap int) unsafe.Pointer - -func MakeSlice(oldPtr unsafe.Pointer, et *GoType, newLen int) *GoSlice { - if newLen == 0 { - return &GoSlice{ - Ptr: ZSTPtr, - Len: 0, - Cap: 0, - } - } - - if *(*unsafe.Pointer)(oldPtr) == nil { - return &GoSlice{ - Ptr: makeslice(et, newLen, newLen), - Len: newLen, - Cap: newLen, - } - } - - old := (*GoSlice)(oldPtr) - if old.Cap >= newLen { - old.Len = newLen - return old - } - - new := GrowSlice(et, *old, newLen-old.Len) - new.Len = newLen - return &new -} diff --git a/internal/rt/stubs.go b/internal/rt/stubs.go index 5cb3b18f9..36e9a808e 100644 --- a/internal/rt/stubs.go +++ b/internal/rt/stubs.go @@ -124,3 +124,6 @@ func GetMap64Assign(vt reflect.Type) Map64Assign { } } + +var emptyBytes = make([]byte, 0, 0) +var EmptySlice = *(*GoSlice)(unsafe.Pointer(&emptyBytes)) diff --git a/internal/rt/table.go b/internal/rt/table.go new file mode 100644 index 000000000..7d49f90e4 --- /dev/null +++ b/internal/rt/table.go @@ -0,0 +1,118 @@ +// Copyright 2024 CloudWeGo Authors +// +// 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 +// +// https://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 rt + +import "unicode/utf8" + +var SafeSet = [utf8.RuneSelf]bool{ + ' ': true, + '!': true, + '"': false, + '#': true, + '$': true, + '%': true, + '&': true, + '\'': true, + '(': true, + ')': true, + '*': true, + '+': true, + ',': true, + '-': true, + '.': true, + '/': true, + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + ':': true, + ';': true, + '<': true, + '=': true, + '>': true, + '?': true, + '@': true, + 'A': true, + 'B': true, + 'C': true, + 'D': true, + 'E': true, + 'F': true, + 'G': true, + 'H': true, + 'I': true, + 'J': true, + 'K': true, + 'L': true, + 'M': true, + 'N': true, + 'O': true, + 'P': true, + 'Q': true, + 'R': true, + 'S': true, + 'T': true, + 'U': true, + 'V': true, + 'W': true, + 'X': true, + 'Y': true, + 'Z': true, + '[': true, + '\\': false, + ']': true, + '^': true, + '_': true, + '`': true, + 'a': true, + 'b': true, + 'c': true, + 'd': true, + 'e': true, + 'f': true, + 'g': true, + 'h': true, + 'i': true, + 'j': true, + 'k': true, + 'l': true, + 'm': true, + 'n': true, + 'o': true, + 'p': true, + 'q': true, + 'r': true, + 's': true, + 't': true, + 'u': true, + 'v': true, + 'w': true, + 'x': true, + 'y': true, + 'z': true, + '{': true, + '|': true, + '}': true, + '~': true, + '\u007f': true, +} + +var Hex = "0123456789abcdef" diff --git a/internal/rt/types.go b/internal/rt/types.go index 7574f7d89..2c9aaa583 100644 --- a/internal/rt/types.go +++ b/internal/rt/types.go @@ -10,9 +10,6 @@ func AsGoType(t uintptr) *GoType { return (*GoType)(unsafe.Pointer(t)) } -//go:linkname zerobase runtime.zerobase -var zerobase uintptr - var ( BoolType = UnpackType(reflect.TypeOf(false)) ByteType = UnpackType(reflect.TypeOf(byte(0))) @@ -45,6 +42,4 @@ var ( MapStringType = UnpackType(reflect.TypeOf(map[string]string(nil))) MapEfaceMapType = MapType(UnpackType(reflect.TypeOf(map[string]interface{}(nil)))) - - ZSTPtr = unsafe.Pointer(&zerobase) ) diff --git a/tools/asm2asm b/tools/asm2asm index 8510d6cb2..7551cd410 160000 --- a/tools/asm2asm +++ b/tools/asm2asm @@ -1 +1 @@ -Subproject commit 8510d6cb224813b7b72c5ac5e971a41163775e5f +Subproject commit 7551cd4109d65d83475ccf98ac3a6844c774e44f