diff options
Diffstat (limited to 'vendor/github.com/bytedance/sonic/internal/encoder')
13 files changed, 171 insertions, 55 deletions
diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/alg/mapiter.go b/vendor/github.com/bytedance/sonic/internal/encoder/alg/mapiter.go index 090afac13..4664d90ca 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/alg/mapiter.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/alg/mapiter.go @@ -84,15 +84,24 @@ func (self *MapIterator) data() (p []_MapPair) { func (self *MapIterator) append(t *rt.GoType, k unsafe.Pointer, v unsafe.Pointer) (err error) { p := self.add() p.v = v + tk := t.Kind() - /* check for strings */ - if tk := t.Kind(); tk != reflect.String { - return self.appendGeneric(p, t, tk, k) + // followed as `encoding/json/emcode.go:resolveKeyName + if tk == reflect.String { + p.k = *(*string)(k) + return nil } - /* fast path for strings */ - p.k = *(*string)(k) - return nil + // check if the key implements the encoding.TextMarshaler interface + if t.Pack().Implements(vars.EncodingTextMarshalerType) { + if tk != reflect.Interface { + return self.appendConcrete(p, t, k) + } else { + return self.appendInterface(p, t, k) + } + } + + return self.appendGeneric(p, t, tk, k) } func (self *MapIterator) appendGeneric(p *_MapPair, t *rt.GoType, v reflect.Kind, k unsafe.Pointer) error { @@ -109,34 +118,43 @@ func (self *MapIterator) appendGeneric(p *_MapPair, t *rt.GoType, v reflect.Kind case reflect.Uint64 : p.k = rt.Mem2Str(strconv.AppendUint(p.m[:0], uint64(*(*uint64)(k)), 10)) ; return nil case reflect.Uintptr : p.k = rt.Mem2Str(strconv.AppendUint(p.m[:0], uint64(*(*uintptr)(k)), 10)) ; return nil case reflect.Bool : if *(*bool)(k) { p.k = "true" } else { p.k = "false" }; return nil - case reflect.Interface : return self.appendInterface(p, t, k) - case reflect.Struct, reflect.Ptr : return self.appendConcrete(p, t, k) - default : panic("unexpected map key type") + default : return vars.Error_type(t.Pack()) } } -func (self *MapIterator) appendConcrete(p *_MapPair, t *rt.GoType, k unsafe.Pointer) (err error) { +func (self *MapIterator) appendConcrete(p *_MapPair, t *rt.GoType, k unsafe.Pointer) error { // compiler has already checked that the type implements the encoding.MarshalText interface if !t.Indirect() { k = *(*unsafe.Pointer)(k) } + + // check the TextMarshaler interface eface := rt.GoEface{Value: k, Type: t}.Pack() - out, err := eface.(encoding.TextMarshaler).MarshalText() + e, ok := eface.(encoding.TextMarshaler) + if !ok { + return vars.Error_type(t.Pack()) + } + + // check for nil pointer + if t.Kind() == reflect.Ptr && k == nil { + p.k = "" + return nil + } + + out, err := e.MarshalText() if err != nil { return err } p.k = rt.Mem2Str(out) - return + return nil } func (self *MapIterator) appendInterface(p *_MapPair, t *rt.GoType, k unsafe.Pointer) (err error) { if len(rt.IfaceType(t).Methods) == 0 { panic("unexpected map key type") - } else if p.k, err = asText(k); err == nil { - return nil - } else { - return } + p.k, err = asText(k) + return } func IteratorStop(p *MapIterator) { @@ -206,3 +224,62 @@ func asText(v unsafe.Pointer) (string, error) { r, e := (*(*encoding.TextMarshaler)(unsafe.Pointer(&text))).MarshalText() return rt.Mem2Str(r), e } + +func IsValidNumber(s string) bool { + // This function implements the JSON numbers grammar. + // See https://tools.ietf.org/html/rfc7159#section-6 + // and https://www.json.org/img/number.png + + if s == "" { + return false + } + + // Optional - + if s[0] == '-' { + s = s[1:] + if s == "" { + return false + } + } + + // Digits + switch { + default: + return false + + case s[0] == '0': + s = s[1:] + + case '1' <= s[0] && s[0] <= '9': + s = s[1:] + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // . followed by 1 or more digits. + if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' { + s = s[2:] + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // e or E followed by an optional - or + and + // 1 or more digits. + if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') { + s = s[1:] + if s[0] == '+' || s[0] == '-' { + s = s[1:] + if s == "" { + return false + } + } + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // Make sure we are at the end. + return s == "" +} diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/alg/spec.go b/vendor/github.com/bytedance/sonic/internal/encoder/alg/spec.go index ecdbfb7bd..f98914961 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/alg/spec.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/alg/spec.go @@ -1,5 +1,5 @@ -//go:build (amd64 && go1.16 && !go1.25) || (arm64 && go1.20 && !go1.25) -// +build amd64,go1.16,!go1.25 arm64,go1.20,!go1.25 +//go:build (amd64 && go1.16 && !go1.26) || (arm64 && go1.20 && !go1.26) +// +build amd64,go1.16,!go1.26 arm64,go1.20,!go1.26 /** * Copyright 2024 ByteDance Inc. @@ -61,7 +61,6 @@ func Valid(data []byte) (ok bool, start int) { var typeByte = rt.UnpackEface(byte(0)).Type -//go:nocheckptr func Quote(buf []byte, val string, double bool) []byte { if len(val) == 0 { if double { @@ -77,6 +76,8 @@ func Quote(buf []byte, val string, double bool) []byte { } sp := rt.IndexChar(val, 0) nb := len(val) + + buf = rt.GuardSlice2(buf, nb+1) b := (*rt.GoSlice)(unsafe.Pointer(&buf)) // input buffer @@ -104,7 +105,9 @@ func Quote(buf []byte, val string, double bool) []byte { ret = ^ret // update input buffer nb -= ret - sp = unsafe.Pointer(uintptr(sp) + uintptr(ret)) + if nb > 0 { + sp = unsafe.Pointer(uintptr(sp) + uintptr(ret)) + } } runtime.KeepAlive(buf) diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/alg/spec_compat.go b/vendor/github.com/bytedance/sonic/internal/encoder/alg/spec_compat.go index cd8369834..cd9beab04 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/alg/spec_compat.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/alg/spec_compat.go @@ -1,4 +1,4 @@ -// +build !amd64,!arm64 go1.25 !go1.16 arm64,!go1.20 +// +build !amd64,!arm64 go1.26 !go1.16 arm64,!go1.20 /** * Copyright 2024 ByteDance Inc. diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/compiler.go b/vendor/github.com/bytedance/sonic/internal/encoder/compiler.go index 737dd3e07..eeeb119cc 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/compiler.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/compiler.go @@ -287,6 +287,12 @@ func (self *Compiler) compileMapBody(p *ir.Program, sp int, vt reflect.Type) { } func (self *Compiler) compileMapBodyKey(p *ir.Program, vk reflect.Type) { + // followed as `encoding/json/emcode.go:resolveKeyName + if vk.Kind() == reflect.String { + self.compileString(p, vk) + return + } + if !vk.Implements(vars.EncodingTextMarshalerType) { self.compileMapBodyTextKey(p, vk) } else { diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/encoder.go b/vendor/github.com/bytedance/sonic/internal/encoder/encoder.go index 4cba1a168..9e675a536 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/encoder.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/encoder.go @@ -28,6 +28,7 @@ import ( "github.com/bytedance/sonic/internal/encoder/vars" "github.com/bytedance/sonic/internal/rt" "github.com/bytedance/sonic/option" + "github.com/bytedance/gopkg/lang/dirtmake" ) // Options is a set of encoding options. @@ -193,7 +194,7 @@ func Encode(val interface{}, opts Options) ([]byte, error) { /* make a copy of the result */ if rt.CanSizeResue(cap(*buf)) { - ret = make([]byte, len(*buf)) + ret = dirtmake.Bytes(len(*buf), len(*buf)) copy(ret, *buf) vars.FreeBytes(buf) } else { diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/alg/primitives.go b/vendor/github.com/bytedance/sonic/internal/encoder/prim/primitives.go index e2610fbc8..ec4d2f5ca 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/alg/primitives.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/prim/primitives.go @@ -14,7 +14,7 @@ * limitations under the License. */ -package alg +package prim import ( "encoding" @@ -22,6 +22,7 @@ import ( "reflect" "unsafe" + "github.com/bytedance/sonic/internal/encoder/alg" "github.com/bytedance/sonic/internal/encoder/vars" "github.com/bytedance/sonic/internal/resolver" "github.com/bytedance/sonic/internal/rt" @@ -70,11 +71,11 @@ func EncodeJsonMarshaler(buf *[]byte, val json.Marshaler, opt uint64) error { if ret, err := val.MarshalJSON(); err != nil { return err } else { - if opt&(1<<BitCompactMarshaler) != 0 { + if opt&(1<<alg.BitCompactMarshaler) != 0 { return Compact(buf, ret) } - if opt&(1<<BitNoValidateJSONMarshaler) == 0 { - if ok, s := Valid(ret); !ok { + if opt&(1<<alg.BitNoValidateJSONMarshaler) == 0 { + if ok, s := alg.Valid(ret); !ok { return vars.Error_marshaler(ret, s) } } @@ -87,11 +88,11 @@ func EncodeTextMarshaler(buf *[]byte, val encoding.TextMarshaler, opt uint64) er if ret, err := val.MarshalText(); err != nil { return err } else { - if opt&(1<<BitNoQuoteTextMarshaler) != 0 { + if opt&(1<<alg.BitNoQuoteTextMarshaler) != 0 { *buf = append(*buf, ret...) return nil } - *buf = Quote(*buf, rt.Mem2Str(ret), false) + *buf = alg.Quote(*buf, rt.Mem2Str(ret), false) return nil } } diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/vars/errors.go b/vendor/github.com/bytedance/sonic/internal/encoder/vars/errors.go index ca3bbca1f..04e6d934d 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/vars/errors.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/vars/errors.go @@ -17,13 +17,15 @@ package vars import ( - `encoding/json` - `fmt` - `reflect` - `strconv` - `unsafe` + "encoding/json" + "fmt" + "os" + "reflect" + "strconv" + "strings" + "unsafe" - `github.com/bytedance/sonic/internal/rt` + "github.com/bytedance/sonic/internal/rt" ) var ERR_too_deep = &json.UnsupportedValueError { @@ -59,11 +61,31 @@ const ( PanicNilPointerOfNonEmptyString int = 1 + iota ) -func GoPanic(code int, val unsafe.Pointer) { +func GoPanic(code int, val unsafe.Pointer, buf string) { + sb := strings.Builder{} switch(code){ case PanicNilPointerOfNonEmptyString: - panic(fmt.Sprintf("val: %#v has nil pointer while its length is not zero!\nThis is a nil pointer exception (NPE) problem. There might be a data race issue. It is recommended to execute the tests related to the code with the `-race` compile flag to detect the problem.", (*rt.GoString)(val))) + sb.WriteString(fmt.Sprintf("val: %#v has nil pointer while its length is not zero!\nThis is a nil pointer exception (NPE) problem. There might be a data race issue. It is recommended to execute the tests related to the code with the `-race` compile flag to detect the problem.\n", (*rt.GoString)(val))) default: - panic("encoder error!") + sb.WriteString("encoder error: ") + sb.WriteString(strconv.Itoa(code)) + sb.WriteString("\n") + } + sb.WriteString("JSON: ") + if len(buf) > maxJSONLength { + sb.WriteString(buf[len(buf)-maxJSONLength:]) + } else { + sb.WriteString(buf) + } + panic(sb.String()) +} + +var maxJSONLength = 1024 + +func init() { + if v := os.Getenv("SONIC_PANIC_MAX_JSON_LENGTH"); v != "" { + if i, err := strconv.Atoi(v); err == nil { + maxJSONLength = i + } } } diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/vm/stbus.go b/vendor/github.com/bytedance/sonic/internal/encoder/vm/stbus.go index 21b476c3c..152c72ca1 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/vm/stbus.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/vm/stbus.go @@ -22,13 +22,14 @@ import ( "github.com/bytedance/sonic/internal/encoder/alg" "github.com/bytedance/sonic/internal/encoder/ir" + "github.com/bytedance/sonic/internal/encoder/prim" "github.com/bytedance/sonic/internal/encoder/vars" "github.com/bytedance/sonic/internal/rt" ) func EncodeTypedPointer(buf *[]byte, vt *rt.GoType, vp *unsafe.Pointer, sb *vars.Stack, fv uint64) error { if vt == nil { - return alg.EncodeNil(buf) + return prim.EncodeNil(buf) } else if pp, err := vars.FindOrCompile(vt, (fv&(1<<alg.BitPointerValue)) != 0, compiler); err != nil { return err } else if vt.Indirect() { diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/vm/vm.go b/vendor/github.com/bytedance/sonic/internal/encoder/vm/vm.go index aa3f515ce..93426b9c6 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/vm/vm.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/vm/vm.go @@ -24,6 +24,7 @@ import ( "github.com/bytedance/sonic/internal/encoder/alg" "github.com/bytedance/sonic/internal/encoder/ir" + "github.com/bytedance/sonic/internal/encoder/prim" "github.com/bytedance/sonic/internal/encoder/vars" "github.com/bytedance/sonic/internal/rt" ) @@ -183,7 +184,7 @@ func Execute(b *[]byte, p unsafe.Pointer, s *vars.Stack, flags uint64, prog *ir. v := *(*json.Number)(p) if v == "" { buf = append(buf, '0') - } else if !rt.IsValidNumber(string(v)) { + } else if !alg.IsValidNumber(string(v)) { return vars.Error_number(v) } else { buf = append(buf, v...) @@ -242,13 +243,13 @@ func Execute(b *[]byte, p unsafe.Pointer, s *vars.Stack, flags uint64, prog *ir. case reflect.Ptr, reflect.Map : it = convT2I(p, true, itab) default : it = convT2I(p, !vt.Indirect(), itab) } - if err := alg.EncodeTextMarshaler(&buf, *(*encoding.TextMarshaler)(unsafe.Pointer(&it)), (flags)); err != nil { + if err := prim.EncodeTextMarshaler(&buf, *(*encoding.TextMarshaler)(unsafe.Pointer(&it)), (flags)); err != nil { return err } case ir.OP_marshal_text_p: _, itab := ins.Vtab() it := convT2I(p, false, itab) - if err := alg.EncodeTextMarshaler(&buf, *(*encoding.TextMarshaler)(unsafe.Pointer(&it)), (flags)); err != nil { + if err := prim.EncodeTextMarshaler(&buf, *(*encoding.TextMarshaler)(unsafe.Pointer(&it)), (flags)); err != nil { return err } case ir.OP_map_write_key: @@ -285,7 +286,7 @@ func Execute(b *[]byte, p unsafe.Pointer, s *vars.Stack, flags uint64, prog *ir. } case ir.OP_is_zero: fv := ins.VField() - if alg.IsZero(p, fv) { + if prim.IsZero(p, fv) { pc = ins.Vi() continue } @@ -334,13 +335,13 @@ func Execute(b *[]byte, p unsafe.Pointer, s *vars.Stack, flags uint64, prog *ir. case reflect.Ptr, reflect.Map : it = convT2I(p, true, itab) default : it = convT2I(p, !vt.Indirect(), itab) } - if err := alg.EncodeJsonMarshaler(&buf, *(*json.Marshaler)(unsafe.Pointer(&it)), (flags)); err != nil { + if err := prim.EncodeJsonMarshaler(&buf, *(*json.Marshaler)(unsafe.Pointer(&it)), (flags)); err != nil { return err } case ir.OP_marshal_p: _, itab := ins.Vtab() it := convT2I(p, false, itab) - if err := alg.EncodeJsonMarshaler(&buf, *(*json.Marshaler)(unsafe.Pointer(&it)), (flags)); err != nil { + if err := prim.EncodeJsonMarshaler(&buf, *(*json.Marshaler)(unsafe.Pointer(&it)), (flags)); err != nil { return err } case ir.OP_unsupported: diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/x86/asm_stubs_amd64_go121.go b/vendor/github.com/bytedance/sonic/internal/encoder/x86/asm_stubs_amd64_go121.go index 6956bd9ba..34a2ff321 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/x86/asm_stubs_amd64_go121.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/x86/asm_stubs_amd64_go121.go @@ -1,5 +1,5 @@ -//go:build go1.21 && !go1.25 -// +build go1.21,!go1.25 +//go:build go1.21 && !go1.26 +// +build go1.21,!go1.26 // Copyright 2023 CloudWeGo Authors // diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/x86/assembler_regabi_amd64.go b/vendor/github.com/bytedance/sonic/internal/encoder/x86/assembler_regabi_amd64.go index d6d451329..620c85900 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/x86/assembler_regabi_amd64.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/x86/assembler_regabi_amd64.go @@ -1,5 +1,5 @@ -//go:build go1.17 && !go1.25 -// +build go1.17,!go1.25 +//go:build go1.17 && !go1.26 +// +build go1.17,!go1.26 /* * Copyright 2021 ByteDance Inc. @@ -28,6 +28,7 @@ import ( "github.com/bytedance/sonic/internal/cpu" "github.com/bytedance/sonic/internal/encoder/alg" "github.com/bytedance/sonic/internal/encoder/ir" + "github.com/bytedance/sonic/internal/encoder/prim" "github.com/bytedance/sonic/internal/encoder/vars" "github.com/bytedance/sonic/internal/jit" "github.com/bytedance/sonic/internal/native/types" @@ -662,6 +663,8 @@ var ( func (self *Assembler) go_panic() { self.Link(_LB_panic) self.Emit("MOVQ", _SP_p, _BX) + self.Emit("MOVQ", _RP, _CX) + self.Emit("MOVQ", _RL, _DI) self.call_go(_F_panic) } @@ -764,7 +767,7 @@ var ( var ( _F_memmove = jit.Func(rt.Memmove) _F_error_number = jit.Func(vars.Error_number) - _F_isValidNumber = jit.Func(rt.IsValidNumber) + _F_isValidNumber = jit.Func(alg.IsValidNumber) ) var ( @@ -784,8 +787,8 @@ const ( ) func init() { - _F_encodeJsonMarshaler = jit.Func(alg.EncodeJsonMarshaler) - _F_encodeTextMarshaler = jit.Func(alg.EncodeTextMarshaler) + _F_encodeJsonMarshaler = jit.Func(prim.EncodeJsonMarshaler) + _F_encodeTextMarshaler = jit.Func(prim.EncodeTextMarshaler) _F_encodeTypedPointer = jit.Func(EncodeTypedPointer) } @@ -1100,7 +1103,7 @@ func (self *Assembler) _asm_OP_is_zero_map(p *ir.Instr) { } var ( - _F_is_zero = jit.Func(alg.IsZero) + _F_is_zero = jit.Func(prim.IsZero) _T_reflect_Type = rt.UnpackIface(reflect.Type(nil)) ) diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/x86/debug_go117.go b/vendor/github.com/bytedance/sonic/internal/encoder/x86/debug_go117.go index 1d1338756..6d7659e68 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/x86/debug_go117.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/x86/debug_go117.go @@ -1,5 +1,5 @@ -//go:build go1.17 && !go1.25 -// +build go1.17,!go1.25 +//go:build go1.17 && !go1.26 +// +build go1.17,!go1.26 /* * Copyright 2021 ByteDance Inc. diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/x86/stbus.go b/vendor/github.com/bytedance/sonic/internal/encoder/x86/stbus.go index 7b6b1f96b..45bb97289 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/x86/stbus.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/x86/stbus.go @@ -21,6 +21,7 @@ import ( _ "unsafe" "github.com/bytedance/sonic/internal/encoder/alg" + "github.com/bytedance/sonic/internal/encoder/prim" "github.com/bytedance/sonic/internal/encoder/vars" "github.com/bytedance/sonic/internal/rt" "github.com/bytedance/sonic/loader" @@ -39,7 +40,7 @@ func ptoenc(p loader.Function) vars.Encoder { func EncodeTypedPointer(buf *[]byte, vt *rt.GoType, vp *unsafe.Pointer, sb *vars.Stack, fv uint64) error { if vt == nil { - return alg.EncodeNil(buf) + return prim.EncodeNil(buf) } else if fn, err := vars.FindOrCompile(vt, (fv&(1<<alg.BitPointerValue)) != 0, compiler); err != nil { return err } else if vt.Indirect() { |
