[chore]: Bump github.com/gin-contrib/gzip from 1.0.1 to 1.1.0 (#3639)

Bumps [github.com/gin-contrib/gzip](https://github.com/gin-contrib/gzip) from 1.0.1 to 1.1.0.
- [Release notes](https://github.com/gin-contrib/gzip/releases)
- [Changelog](https://github.com/gin-contrib/gzip/blob/master/.goreleaser.yaml)
- [Commits](https://github.com/gin-contrib/gzip/compare/v1.0.1...v1.1.0)

---
updated-dependencies:
- dependency-name: github.com/gin-contrib/gzip
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
dependabot[bot] 2025-01-14 13:10:39 +00:00 committed by GitHub
commit 4d423102c1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
519 changed files with 156968 additions and 132058 deletions

View file

@ -0,0 +1,46 @@
// +build amd64,go1.17,!go1.24
/**
* 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 base64
import (
"github.com/cloudwego/base64x"
)
func DecodeBase64(src string) ([]byte, error) {
return base64x.StdEncoding.DecodeString(src)
}
func EncodeBase64(buf []byte, src []byte) []byte {
if len(src) == 0 {
return append(buf, '"', '"')
}
buf = append(buf, '"')
need := base64x.StdEncoding.EncodedLen(len(src))
if cap(buf) - len(buf) < need {
tmp := make([]byte, len(buf), len(buf) + need*2)
copy(tmp, buf)
buf = tmp
}
base64x.StdEncoding.Encode(buf[len(buf):cap(buf)], src)
buf = buf[:len(buf) + need]
buf = append(buf, '"')
return buf
}

View file

@ -0,0 +1,44 @@
// +build !amd64 !go1.17 go1.24
/*
* 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 base64
import (
"encoding/base64"
)
func EncodeBase64(buf []byte, src []byte) []byte {
if len(src) == 0 {
return append(buf, '"', '"')
}
buf = append(buf, '"')
need := base64.StdEncoding.EncodedLen(len(src))
if cap(buf) - len(buf) < need {
tmp := make([]byte, len(buf), len(buf) + need*2)
copy(tmp, buf)
buf = tmp
}
base64.StdEncoding.Encode(buf[len(buf):cap(buf)], src)
buf = buf[:len(buf) + need]
buf = append(buf, '"')
return buf
}
func DecodeBase64(src string) ([]byte, error) {
return base64.StdEncoding.DecodeString(src)
}

View file

@ -24,7 +24,6 @@ import (
)
var (
HasAVX = cpuid.CPU.Has(cpuid.AVX)
HasAVX2 = cpuid.CPU.Has(cpuid.AVX2)
HasSSE = cpuid.CPU.Has(cpuid.SSE)
)
@ -33,7 +32,8 @@ func init() {
switch v := os.Getenv("SONIC_MODE"); v {
case "" : break
case "auto" : break
case "noavx" : HasAVX = false; fallthrough
case "noavx" : HasAVX2 = false
// will also disable avx, act as `noavx`, we remain it to make sure forward compatibility
case "noavx2" : HasAVX2 = false
default : panic(fmt.Sprintf("invalid mode: '%s', should be one of 'auto', 'noavx', 'noavx2'", v))
}

View file

@ -14,51 +14,52 @@
* limitations under the License.
*/
package decoder
package api
import (
`unsafe`
`encoding/json`
`reflect`
`runtime`
`github.com/bytedance/sonic/internal/native`
`github.com/bytedance/sonic/internal/native/types`
`github.com/bytedance/sonic/internal/decoder/consts`
`github.com/bytedance/sonic/internal/decoder/errors`
`github.com/bytedance/sonic/internal/rt`
`github.com/bytedance/sonic/option`
`github.com/bytedance/sonic/utf8`
)
const (
_F_use_int64 = 0
_F_disable_urc = 2
_F_disable_unknown = 3
_F_copy_string = 4
_F_allow_control = consts.F_allow_control
_F_copy_string = consts.F_copy_string
_F_disable_unknown = consts.F_disable_unknown
_F_disable_urc = consts.F_disable_urc
_F_use_int64 = consts.F_use_int64
_F_use_number = consts.F_use_number
_F_validate_string = consts.F_validate_string
_F_use_number = types.B_USE_NUMBER
_F_validate_string = types.B_VALIDATE_STRING
_F_allow_control = types.B_ALLOW_CONTROL
_MaxStack = consts.MaxStack
OptionUseInt64 = consts.OptionUseInt64
OptionUseNumber = consts.OptionUseNumber
OptionUseUnicodeErrors = consts.OptionUseUnicodeErrors
OptionDisableUnknown = consts.OptionDisableUnknown
OptionCopyString = consts.OptionCopyString
OptionValidateString = consts.OptionValidateString
OptionNoValidateJSON = consts.OptionNoValidateJSON
)
type Options uint64
const (
OptionUseInt64 Options = 1 << _F_use_int64
OptionUseNumber Options = 1 << _F_use_number
OptionUseUnicodeErrors Options = 1 << _F_disable_urc
OptionDisableUnknown Options = 1 << _F_disable_unknown
OptionCopyString Options = 1 << _F_copy_string
OptionValidateString Options = 1 << _F_validate_string
type (
Options = consts.Options
MismatchTypeError = errors.MismatchTypeError
SyntaxError = errors.SyntaxError
)
func (self *Decoder) SetOptions(opts Options) {
if (opts & OptionUseNumber != 0) && (opts & OptionUseInt64 != 0) {
if (opts & consts.OptionUseNumber != 0) && (opts & consts.OptionUseInt64 != 0) {
panic("can't set OptionUseInt64 and OptionUseNumber both!")
}
self.f = uint64(opts)
}
// Decoder is the decoder context object
type Decoder struct {
i int
@ -109,44 +110,7 @@ func (self *Decoder) CheckTrailings() error {
// Decode parses the JSON-encoded data from current position and stores the result
// in the value pointed to by val.
func (self *Decoder) Decode(val interface{}) error {
/* validate json if needed */
if (self.f & (1 << _F_validate_string)) != 0 && !utf8.ValidateString(self.s){
dbuf := utf8.CorrectWith(nil, rt.Str2Mem(self.s), "\ufffd")
self.s = rt.Mem2Str(dbuf)
}
vv := rt.UnpackEface(val)
vp := vv.Value
/* check for nil type */
if vv.Type == nil {
return &json.InvalidUnmarshalError{}
}
/* must be a non-nil pointer */
if vp == nil || vv.Type.Kind() != reflect.Ptr {
return &json.InvalidUnmarshalError{Type: vv.Type.Pack()}
}
etp := rt.PtrElem(vv.Type)
/* check the defined pointer type for issue 379 */
if vv.Type.IsNamed() {
newp := vp
etp = vv.Type
vp = unsafe.Pointer(&newp)
}
/* create a new stack, and call the decoder */
sb := newStack()
nb, err := decodeTypedPointer(self.s, self.i, etp, vp, sb, self.f)
/* return the stack back */
self.i = nb
freeStack(sb)
/* avoid GC ahead */
runtime.KeepAlive(vv)
return err
return decodeImpl(&self.s, &self.i, self.f, val)
}
// UseInt64 indicates the Decoder to unmarshal an integer into an interface{} as an
@ -194,53 +158,7 @@ func (self *Decoder) ValidateString() {
// Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is
// a compile option to set the depth of recursive compile for the nested struct type.
func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
cfg := option.DefaultCompileOptions()
for _, opt := range opts {
opt(&cfg)
}
return pretouchRec(map[reflect.Type]bool{vt:true}, cfg)
}
func pretouchType(_vt reflect.Type, opts option.CompileOptions) (map[reflect.Type]bool, error) {
/* compile function */
compiler := newCompiler().apply(opts)
decoder := func(vt *rt.GoType, _ ...interface{}) (interface{}, error) {
if pp, err := compiler.compile(_vt); err != nil {
return nil, err
} else {
as := newAssembler(pp)
as.name = _vt.String()
return as.Load(), nil
}
}
/* find or compile */
vt := rt.UnpackType(_vt)
if val := programCache.Get(vt); val != nil {
return nil, nil
} else if _, err := programCache.Compute(vt, decoder); err == nil {
return compiler.rec, nil
} else {
return nil, err
}
}
func pretouchRec(vtm map[reflect.Type]bool, opts option.CompileOptions) error {
if opts.RecursiveDepth < 0 || len(vtm) == 0 {
return nil
}
next := make(map[reflect.Type]bool)
for vt := range(vtm) {
sub, err := pretouchType(vt, opts)
if err != nil {
return err
}
for svt := range(sub) {
next[svt] = true
}
}
opts.RecursiveDepth -= 1
return pretouchRec(next, opts)
return pretouchImpl(vt, opts...)
}
// Skip skips only one json value, and returns first non-blank character position and its ending position if it is valid.

View file

@ -0,0 +1,38 @@
//go:build go1.17 && !go1.24
// +build go1.17,!go1.24
/*
* 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 api
import (
"github.com/bytedance/sonic/internal/envs"
"github.com/bytedance/sonic/internal/decoder/jitdec"
"github.com/bytedance/sonic/internal/decoder/optdec"
)
var (
pretouchImpl = jitdec.Pretouch
decodeImpl = jitdec.Decode
)
func init() {
if envs.UseOptDec {
pretouchImpl = optdec.Pretouch
decodeImpl = optdec.Decode
}
}

View file

@ -1,6 +1,4 @@
// Code generated by Makefile, DO NOT EDIT.
// Code generated by Makefile, DO NOT EDIT.
// +build go1.17,!go1.24
/*
* Copyright 2021 ByteDance Inc.
@ -18,19 +16,23 @@
* limitations under the License.
*/
package avx
package api
import (
`unsafe`
`github.com/bytedance/sonic/internal/rt`
`github.com/bytedance/sonic/internal/decoder/optdec`
`github.com/bytedance/sonic/internal/envs`
)
var F_u64toa func(out unsafe.Pointer, val uint64) (ret int)
var (
pretouchImpl = optdec.Pretouch
decodeImpl = optdec.Decode
)
var S_u64toa uintptr
//go:nosplit
func u64toa(out *byte, val uint64) (ret int) {
return F_u64toa(rt.NoEscape(unsafe.Pointer(out)), val)
func init() {
// whe in aarch64. we enable all optimize
envs.EnableOptDec()
envs.EnableFastMap()
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package decoder
package api
import (
`bytes`
@ -47,6 +47,12 @@ var bufPool = sync.Pool{
},
}
func freeBytes(buf []byte) {
if rt.CanSizeResue(cap(buf)) {
bufPool.Put(buf[:0])
}
}
// NewStreamDecoder adapts to encoding/json.NewDecoder API.
//
// NewStreamDecoder returns a new decoder that reads from r.
@ -61,25 +67,16 @@ func NewStreamDecoder(r io.Reader) *StreamDecoder {
func (self *StreamDecoder) Decode(val interface{}) (err error) {
// read more data into buf
if self.More() {
// println(string(self.buf))
var s = self.scanp
try_skip:
var e = len(self.buf)
// println("s:", s, "e:", e, "scanned:",self.scanned, "scanp:",self.scanp, self.buf)
var src = rt.Mem2Str(self.buf[s:e])
// if len(src) > 5 {
// println(src[:5], src[len(src)-5:])
// } else {
// println(src)
// }
// try skip
var x = 0;
if y := native.SkipOneFast(&src, &x); y < 0 {
if self.readMore() {
// println("more")
goto try_skip
} else {
// println("no more")
err = SyntaxError{e, self.s, types.ParsingError(-s), ""}
self.setErr(err)
return
@ -89,7 +86,6 @@ func (self *StreamDecoder) Decode(val interface{}) (err error) {
e = x + s
}
// println("decode: ", s, e)
// must copy string here for safety
self.Decoder.Reset(string(self.buf[s:e]))
err = self.Decoder.Decode(val)
@ -101,13 +97,11 @@ func (self *StreamDecoder) Decode(val interface{}) (err error) {
self.scanp = e
_, empty := self.scan()
if empty {
// println("recycle")
// no remain valid bytes, thus we just recycle buffer
mem := self.buf
self.buf = nil
bufPool.Put(mem[:0])
freeBytes(mem)
} else {
// println("keep")
// remain undecoded bytes, move them onto head
n := copy(self.buf, self.buf[self.scanp:])
self.buf = self.buf[:n]
@ -123,7 +117,6 @@ func (self *StreamDecoder) Decode(val interface{}) (err error) {
// InputOffset returns the input stream byte offset of the current decoder position.
// The offset gives the location of the end of the most recently returned token and the beginning of the next token.
func (self *StreamDecoder) InputOffset() int64 {
// println("input offset",self.scanned, self.scanp)
return self.scanned + int64(self.scanp)
}
@ -178,7 +171,7 @@ func (self *StreamDecoder) setErr(err error) {
self.err = err
mem := self.buf[:0]
self.buf = nil
bufPool.Put(mem)
freeBytes(mem)
}
func (self *StreamDecoder) peek() (byte, error) {
@ -237,12 +230,10 @@ func realloc(buf *[]byte) bool {
l := uint(len(*buf))
c := uint(cap(*buf))
if c == 0 {
// println("use pool!")
*buf = bufPool.Get().([]byte)
return true
}
if c - l <= c >> minLeftBufferShift {
// println("realloc!")
e := l+(l>>minLeftBufferShift)
if e <= c {
e = c*2

View file

@ -1,130 +0,0 @@
// +build go1.16,!go1.17
// Copyright 2023 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
//
// 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 decoder
import (
`strconv`
_ `unsafe`
`github.com/bytedance/sonic/internal/jit`
`github.com/bytedance/sonic/internal/rt`
`github.com/twitchyliquid64/golang-asm/obj`
`github.com/twitchyliquid64/golang-asm/obj/x86`
)
var _runtime_writeBarrier uintptr = rt.GcwbAddr()
//go:linkname gcWriteBarrierAX runtime.gcWriteBarrier
func gcWriteBarrierAX()
var (
_V_writeBarrier = jit.Imm(int64(_runtime_writeBarrier))
_F_gcWriteBarrierAX = jit.Func(gcWriteBarrierAX)
)
func (self *_Assembler) WritePtrAX(i int, rec obj.Addr, saveDI bool) {
self.Emit("MOVQ", _V_writeBarrier, _R10)
self.Emit("CMPL", jit.Ptr(_R10, 0), jit.Imm(0))
self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
if saveDI {
self.save(_DI)
}
self.Emit("LEAQ", rec, _DI)
self.Emit("MOVQ", _F_gcWriteBarrierAX, _R10) // MOVQ ${fn}, AX
self.Rjmp("CALL", _R10)
if saveDI {
self.load(_DI)
}
self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
self.Emit("MOVQ", _AX, rec)
self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
}
func (self *_Assembler) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool, saveAX bool) {
if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX {
panic("rec contains AX!")
}
self.Emit("MOVQ", _V_writeBarrier, _R10)
self.Emit("CMPL", jit.Ptr(_R10, 0), jit.Imm(0))
self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
if saveAX {
self.Emit("XCHGQ", ptr, _AX)
} else {
self.Emit("MOVQ", ptr, _AX)
}
if saveDI {
self.save(_DI)
}
self.Emit("LEAQ", rec, _DI)
self.Emit("MOVQ", _F_gcWriteBarrierAX, _R10) // MOVQ ${fn}, AX
self.Rjmp("CALL", _R10)
if saveDI {
self.load(_DI)
}
if saveAX {
self.Emit("XCHGQ", ptr, _AX)
}
self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
self.Emit("MOVQ", ptr, rec)
self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
}
func (self *_ValueDecoder) WritePtrAX(i int, rec obj.Addr, saveDI bool) {
self.Emit("MOVQ", _V_writeBarrier, _R10)
self.Emit("CMPL", jit.Ptr(_R10, 0), jit.Imm(0))
self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
if saveDI {
self.save(_DI)
}
self.Emit("LEAQ", rec, _DI)
self.Emit("MOVQ", _F_gcWriteBarrierAX, _R10) // MOVQ ${fn}, AX
self.Rjmp("CALL", _R10)
if saveDI {
self.load(_DI)
}
self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
self.Emit("MOVQ", _AX, rec)
self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
}
func (self *_ValueDecoder) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool) {
if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX {
panic("rec contains AX!")
}
self.Emit("MOVQ", _V_writeBarrier, _R10)
self.Emit("CMPL", jit.Ptr(_R10, 0), jit.Imm(0))
self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
self.Emit("MOVQ", ptr, _AX)
if saveDI {
self.save(_DI)
}
self.Emit("LEAQ", rec, _DI)
self.Emit("MOVQ", _F_gcWriteBarrierAX, _R10) // MOVQ ${fn}, AX
self.Rjmp("CALL", _R10)
if saveDI {
self.load(_DI)
}
self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
self.Emit("MOVQ", ptr, rec)
self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,36 @@
package consts
import (
`github.com/bytedance/sonic/internal/native/types`
)
const (
F_use_int64 = 0
F_disable_urc = 2
F_disable_unknown = 3
F_copy_string = 4
F_use_number = types.B_USE_NUMBER
F_validate_string = types.B_VALIDATE_STRING
F_allow_control = types.B_ALLOW_CONTROL
F_no_validate_json = types.B_NO_VALIDATE_JSON
)
type Options uint64
const (
OptionUseInt64 Options = 1 << F_use_int64
OptionUseNumber Options = 1 << F_use_number
OptionUseUnicodeErrors Options = 1 << F_disable_urc
OptionDisableUnknown Options = 1 << F_disable_unknown
OptionCopyString Options = 1 << F_copy_string
OptionValidateString Options = 1 << F_validate_string
OptionNoValidateJSON Options = 1 << F_no_validate_json
)
const (
MaxStack = 4096
)

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package decoder
package errors
import (
`encoding/json`
@ -46,7 +46,7 @@ func (self SyntaxError) Description() string {
func (self SyntaxError) description() string {
/* check for empty source */
if self.Src == "" {
return fmt.Sprintf("no sources available: %#v", self)
return fmt.Sprintf("no sources available, the input json is empty: %#v", self)
}
p, x, q, y := calcBounds(len(self.Src), self.Pos)
@ -112,12 +112,12 @@ func clamp_zero(v int) int {
/** JIT Error Helpers **/
var stackOverflow = &json.UnsupportedValueError {
var StackOverflow = &json.UnsupportedValueError {
Str : "Value nesting too deep",
Value : reflect.ValueOf("..."),
}
func error_wrap(src string, pos int, code types.ParsingError) error {
func ErrorWrap(src string, pos int, code types.ParsingError) error {
return *error_wrap_heap(src, pos, code)
}
@ -130,7 +130,7 @@ func error_wrap_heap(src string, pos int, code types.ParsingError) *SyntaxError
}
}
func error_type(vt *rt.GoType) error {
func ErrorType(vt *rt.GoType) error {
return &json.UnmarshalTypeError{Type: vt.Pack()}
}
@ -171,7 +171,7 @@ func (self MismatchTypeError) Description() string {
return fmt.Sprintf("Mismatch type %s with value %s %s", self.Type.String(), swithchJSONType(self.Src, self.Pos), se.description())
}
func error_mismatch(src string, pos int, vt *rt.GoType) error {
func ErrorMismatch(src string, pos int, vt *rt.GoType) error {
return &MismatchTypeError {
Pos : pos,
Src : src,
@ -179,11 +179,11 @@ func error_mismatch(src string, pos int, vt *rt.GoType) error {
}
}
func error_field(name string) error {
func ErrorField(name string) error {
return errors.New("json: unknown field " + strconv.Quote(name))
}
func error_value(value string, vtype reflect.Type) error {
func ErrorValue(value string, vtype reflect.Type) error {
return &json.UnmarshalTypeError {
Type : vtype,
Value : value,

View file

@ -1,733 +0,0 @@
// +build go1.16,!go1.17
/*
* 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 decoder
import (
`encoding/json`
`fmt`
`reflect`
`github.com/bytedance/sonic/internal/jit`
`github.com/bytedance/sonic/internal/native`
`github.com/bytedance/sonic/internal/native/types`
`github.com/twitchyliquid64/golang-asm/obj`
)
/** Crucial Registers:
*
* ST(BX) : ro, decoder stack
* DF(R10) : ro, decoder flags
* EP(R11) : wo, error pointer
* IP(R12) : ro, input pointer
* IL(R13) : ro, input length
* IC(R14) : rw, input cursor
* VP(R15) : ro, value pointer (to an interface{})
*/
const (
_VD_args = 8 // 8 bytes for passing arguments to this functions
_VD_fargs = 64 // 64 bytes for passing arguments to other Go functions
_VD_saves = 40 // 40 bytes for saving the registers before CALL instructions
_VD_locals = 88 // 88 bytes for local variables
)
const (
_VD_offs = _VD_fargs + _VD_saves + _VD_locals
_VD_size = _VD_offs + 8 // 8 bytes for the parent frame pointer
)
var (
_VAR_ss = _VAR_ss_Vt
_VAR_df = jit.Ptr(_SP, _VD_fargs + _VD_saves)
)
var (
_VAR_ss_Vt = jit.Ptr(_SP, _VD_fargs + _VD_saves + 8)
_VAR_ss_Dv = jit.Ptr(_SP, _VD_fargs + _VD_saves + 16)
_VAR_ss_Iv = jit.Ptr(_SP, _VD_fargs + _VD_saves + 24)
_VAR_ss_Ep = jit.Ptr(_SP, _VD_fargs + _VD_saves + 32)
_VAR_ss_Db = jit.Ptr(_SP, _VD_fargs + _VD_saves + 40)
_VAR_ss_Dc = jit.Ptr(_SP, _VD_fargs + _VD_saves + 48)
)
var (
_VAR_cs_LR = jit.Ptr(_SP, _VD_fargs + _VD_saves + 56)
_VAR_cs_p = jit.Ptr(_SP, _VD_fargs + _VD_saves + 64)
_VAR_cs_n = jit.Ptr(_SP, _VD_fargs + _VD_saves + 72)
_VAR_cs_d = jit.Ptr(_SP, _VD_fargs + _VD_saves + 80)
)
type _ValueDecoder struct {
jit.BaseAssembler
}
func (self *_ValueDecoder) build() uintptr {
self.Init(self.compile)
return *(*uintptr)(self.Load("decode_value", _VD_size, _VD_args, argPtrs_generic, localPtrs_generic))
}
/** Function Calling Helpers **/
func (self *_ValueDecoder) save(r ...obj.Addr) {
for i, v := range r {
if i > _VD_saves / 8 - 1 {
panic("too many registers to save")
} else {
self.Emit("MOVQ", v, jit.Ptr(_SP, _VD_fargs + int64(i) * 8))
}
}
}
func (self *_ValueDecoder) load(r ...obj.Addr) {
for i, v := range r {
if i > _VD_saves / 8 - 1 {
panic("too many registers to load")
} else {
self.Emit("MOVQ", jit.Ptr(_SP, _VD_fargs + int64(i) * 8), v)
}
}
}
func (self *_ValueDecoder) call(fn obj.Addr) {
self.Emit("MOVQ", fn, _AX) // MOVQ ${fn}, AX
self.Rjmp("CALL", _AX) // CALL AX
}
func (self *_ValueDecoder) call_go(fn obj.Addr) {
self.save(_REG_go...) // SAVE $REG_go
self.call(fn) // CALL ${fn}
self.load(_REG_go...) // LOAD $REG_go
}
/** Decoder Assembler **/
const (
_S_val = iota + 1
_S_arr
_S_arr_0
_S_obj
_S_obj_0
_S_obj_delim
_S_obj_sep
)
const (
_S_omask_key = (1 << _S_obj_0) | (1 << _S_obj_sep)
_S_omask_end = (1 << _S_obj_0) | (1 << _S_obj)
_S_vmask = (1 << _S_val) | (1 << _S_arr_0)
)
const (
_A_init_len = 1
_A_init_cap = 16
)
const (
_ST_Sp = 0
_ST_Vt = _PtrBytes
_ST_Vp = _PtrBytes * (types.MAX_RECURSE + 1)
)
var (
_V_true = jit.Imm(int64(pbool(true)))
_V_false = jit.Imm(int64(pbool(false)))
_F_value = jit.Imm(int64(native.S_value))
)
var (
_V_max = jit.Imm(int64(types.V_MAX))
_E_eof = jit.Imm(int64(types.ERR_EOF))
_E_invalid = jit.Imm(int64(types.ERR_INVALID_CHAR))
_E_recurse = jit.Imm(int64(types.ERR_RECURSE_EXCEED_MAX))
)
var (
_F_convTslice = jit.Func(convTslice)
_F_convTstring = jit.Func(convTstring)
_F_invalid_vtype = jit.Func(invalid_vtype)
)
var (
_T_map = jit.Type(reflect.TypeOf((map[string]interface{})(nil)))
_T_bool = jit.Type(reflect.TypeOf(false))
_T_int64 = jit.Type(reflect.TypeOf(int64(0)))
_T_eface = jit.Type(reflect.TypeOf((*interface{})(nil)).Elem())
_T_slice = jit.Type(reflect.TypeOf(([]interface{})(nil)))
_T_string = jit.Type(reflect.TypeOf(""))
_T_number = jit.Type(reflect.TypeOf(json.Number("")))
_T_float64 = jit.Type(reflect.TypeOf(float64(0)))
)
var _R_tab = map[int]string {
'[': "_decode_V_ARRAY",
'{': "_decode_V_OBJECT",
':': "_decode_V_KEY_SEP",
',': "_decode_V_ELEM_SEP",
']': "_decode_V_ARRAY_END",
'}': "_decode_V_OBJECT_END",
}
func (self *_ValueDecoder) compile() {
self.Emit("SUBQ", jit.Imm(_VD_size), _SP) // SUBQ $_VD_size, SP
self.Emit("MOVQ", _BP, jit.Ptr(_SP, _VD_offs)) // MOVQ BP, _VD_offs(SP)
self.Emit("LEAQ", jit.Ptr(_SP, _VD_offs), _BP) // LEAQ _VD_offs(SP), BP
/* initialize the state machine */
self.Emit("XORL", _CX, _CX) // XORL CX, CX
self.Emit("MOVQ", _DF, _VAR_df) // MOVQ DF, df
/* initialize digital buffer first */
self.Emit("MOVQ", jit.Imm(_MaxDigitNums), _VAR_ss_Dc) // MOVQ $_MaxDigitNums, ss.Dcap
self.Emit("LEAQ", jit.Ptr(_ST, _DbufOffset), _AX) // LEAQ _DbufOffset(ST), AX
self.Emit("MOVQ", _AX, _VAR_ss_Db) // MOVQ AX, ss.Dbuf
/* add ST offset */
self.Emit("ADDQ", jit.Imm(_FsmOffset), _ST) // ADDQ _FsmOffset, _ST
self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp
self.WriteRecNotAX(0, _VP, jit.Ptr(_ST, _ST_Vp), false) // MOVQ VP, ST.Vp[0]
self.Emit("MOVQ", jit.Imm(_S_val), jit.Ptr(_ST, _ST_Vt)) // MOVQ _S_val, ST.Vt[0]
self.Sjmp("JMP" , "_next") // JMP _next
/* set the value from previous round */
self.Link("_set_value") // _set_value:
self.Emit("MOVL" , jit.Imm(_S_vmask), _DX) // MOVL _S_vmask, DX
self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.Emit("MOVQ" , jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX
self.Sjmp("JNC" , "_vtype_error") // JNC _vtype_error
self.Emit("XORL" , _SI, _SI) // XORL SI, SI
self.Emit("SUBQ" , jit.Imm(1), jit.Ptr(_ST, _ST_Sp)) // SUBQ $1, ST.Sp
self.Emit("XCHGQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // XCHGQ ST.Vp[CX], SI
self.Emit("MOVQ" , _R8, jit.Ptr(_SI, 0)) // MOVQ R8, (SI)
self.WriteRecNotAX(1, _R9, jit.Ptr(_SI, 8), false) // MOVQ R9, 8(SI)
/* check for value stack */
self.Link("_next") // _next:
self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _AX) // MOVQ ST.Sp, AX
self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX
self.Sjmp("JS" , "_return") // JS _return
/* fast path: test up to 4 characters manually */
self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL
self.Sjmp("JAE" , "_decode_V_EOF") // JAE _decode_V_EOF
self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX
self.Emit("MOVQ" , jit.Imm(_BM_space), _DX) // MOVQ _BM_space, DX
self.Emit("CMPQ" , _AX, jit.Imm(' ')) // CMPQ AX, $' '
self.Sjmp("JA" , "_decode_fast") // JA _decode_fast
self.Emit("BTQ" , _AX, _DX) // BTQ _AX, _DX
self.Sjmp("JNC" , "_decode_fast") // JNC _decode_fast
self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC
/* at least 1 to 3 spaces */
for i := 0; i < 3; i++ {
self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL
self.Sjmp("JAE" , "_decode_V_EOF") // JAE _decode_V_EOF
self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX
self.Emit("CMPQ" , _AX, jit.Imm(' ')) // CMPQ AX, $' '
self.Sjmp("JA" , "_decode_fast") // JA _decode_fast
self.Emit("BTQ" , _AX, _DX) // BTQ _AX, _DX
self.Sjmp("JNC" , "_decode_fast") // JNC _decode_fast
self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC
}
/* at least 4 spaces */
self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL
self.Sjmp("JAE" , "_decode_V_EOF") // JAE _decode_V_EOF
self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX
/* fast path: use lookup table to select decoder */
self.Link("_decode_fast") // _decode_fast:
self.Byte(0x48, 0x8d, 0x3d) // LEAQ ?(PC), DI
self.Sref("_decode_tab", 4) // .... &_decode_tab
self.Emit("MOVLQSX", jit.Sib(_DI, _AX, 4, 0), _AX) // MOVLQSX (DI)(AX*4), AX
self.Emit("TESTQ" , _AX, _AX) // TESTQ AX, AX
self.Sjmp("JZ" , "_decode_native") // JZ _decode_native
self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC
self.Emit("ADDQ" , _DI, _AX) // ADDQ DI, AX
self.Rjmp("JMP" , _AX) // JMP AX
/* decode with native decoder */
self.Link("_decode_native") // _decode_native:
self.Emit("MOVQ", _IP, _DI) // MOVQ IP, DI
self.Emit("MOVQ", _IL, _SI) // MOVQ IL, SI
self.Emit("MOVQ", _IC, _DX) // MOVQ IC, DX
self.Emit("LEAQ", _VAR_ss, _CX) // LEAQ ss, CX
self.Emit("MOVQ", _VAR_df, _R8) // MOVQ $df, R8
self.Emit("BTSQ", jit.Imm(_F_allow_control), _R8) // ANDQ $1<<_F_allow_control, R8
self.call(_F_value) // CALL value
self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC
/* check for errors */
self.Emit("MOVQ" , _VAR_ss_Vt, _AX) // MOVQ ss.Vt, AX
self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX
self.Sjmp("JS" , "_parsing_error")
self.Sjmp("JZ" , "_invalid_vtype") // JZ _invalid_vtype
self.Emit("CMPQ" , _AX, _V_max) // CMPQ AX, _V_max
self.Sjmp("JA" , "_invalid_vtype") // JA _invalid_vtype
/* jump table selector */
self.Byte(0x48, 0x8d, 0x3d) // LEAQ ?(PC), DI
self.Sref("_switch_table", 4) // .... &_switch_table
self.Emit("MOVLQSX", jit.Sib(_DI, _AX, 4, -4), _AX) // MOVLQSX -4(DI)(AX*4), AX
self.Emit("ADDQ" , _DI, _AX) // ADDQ DI, AX
self.Rjmp("JMP" , _AX) // JMP AX
/** V_EOF **/
self.Link("_decode_V_EOF") // _decode_V_EOF:
self.Emit("MOVL", _E_eof, _EP) // MOVL _E_eof, EP
self.Sjmp("JMP" , "_error") // JMP _error
/** V_NULL **/
self.Link("_decode_V_NULL") // _decode_V_NULL:
self.Emit("XORL", _R8, _R8) // XORL R8, R8
self.Emit("XORL", _R9, _R9) // XORL R9, R9
self.Emit("LEAQ", jit.Ptr(_IC, -4), _DI) // LEAQ -4(IC), DI
self.Sjmp("JMP" , "_set_value") // JMP _set_value
/** V_TRUE **/
self.Link("_decode_V_TRUE") // _decode_V_TRUE:
self.Emit("MOVQ", _T_bool, _R8) // MOVQ _T_bool, R8
// TODO: maybe modified by users?
self.Emit("MOVQ", _V_true, _R9) // MOVQ _V_true, R9
self.Emit("LEAQ", jit.Ptr(_IC, -4), _DI) // LEAQ -4(IC), DI
self.Sjmp("JMP" , "_set_value") // JMP _set_value
/** V_FALSE **/
self.Link("_decode_V_FALSE") // _decode_V_FALSE:
self.Emit("MOVQ", _T_bool, _R8) // MOVQ _T_bool, R8
self.Emit("MOVQ", _V_false, _R9) // MOVQ _V_false, R9
self.Emit("LEAQ", jit.Ptr(_IC, -5), _DI) // LEAQ -5(IC), DI
self.Sjmp("JMP" , "_set_value") // JMP _set_value
/** V_ARRAY **/
self.Link("_decode_V_ARRAY") // _decode_V_ARRAY
self.Emit("MOVL", jit.Imm(_S_vmask), _DX) // MOVL _S_vmask, DX
self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX
self.Sjmp("JNC" , "_invalid_char") // JNC _invalid_char
/* create a new array */
self.Emit("MOVQ", _T_eface, _AX) // MOVQ _T_eface, AX
self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP)
self.Emit("MOVQ", jit.Imm(_A_init_len), jit.Ptr(_SP, 8)) // MOVQ _A_init_len, 8(SP)
self.Emit("MOVQ", jit.Imm(_A_init_cap), jit.Ptr(_SP, 16)) // MOVQ _A_init_cap, 16(SP)
self.call_go(_F_makeslice) // CALL_GO runtime.makeslice
self.Emit("MOVQ", jit.Ptr(_SP, 24), _DX) // MOVQ 24(SP), DX
/* pack into an interface */
self.Emit("MOVQ", _DX, jit.Ptr(_SP, 0)) // MOVQ DX, (SP)
self.Emit("MOVQ", jit.Imm(_A_init_len), jit.Ptr(_SP, 8)) // MOVQ _A_init_len, 8(SP)
self.Emit("MOVQ", jit.Imm(_A_init_cap), jit.Ptr(_SP, 16)) // MOVQ _A_init_cap, 16(SP)
self.call_go(_F_convTslice) // CALL_GO runtime.convTslice
self.Emit("MOVQ", jit.Ptr(_SP, 24), _R8) // MOVQ 24(SP), R8
/* replace current state with an array */
self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI
self.Emit("MOVQ", jit.Imm(_S_arr), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_arr, ST.Vt[CX]
self.Emit("MOVQ", _T_slice, _AX) // MOVQ _T_slice, AX
self.Emit("MOVQ", _AX, jit.Ptr(_SI, 0)) // MOVQ AX, (SI)
self.WriteRecNotAX(2, _R8, jit.Ptr(_SI, 8), false) // MOVQ R8, 8(SI)
/* add a new slot for the first element */
self.Emit("ADDQ", jit.Imm(1), _CX) // ADDQ $1, CX
self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE)) // CMPQ CX, ${types.MAX_RECURSE}
self.Sjmp("JAE" , "_stack_overflow") // JA _stack_overflow
self.Emit("MOVQ", jit.Ptr(_R8, 0), _AX) // MOVQ (R8), AX
self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp
self.WritePtrAX(3, jit.Sib(_ST, _CX, 8, _ST_Vp), false) // MOVQ AX, ST.Vp[CX]
self.Emit("MOVQ", jit.Imm(_S_arr_0), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_arr_0, ST.Vt[CX]
self.Sjmp("JMP" , "_next") // JMP _next
/** V_OBJECT **/
self.Link("_decode_V_OBJECT") // _decode_V_OBJECT:
self.Emit("MOVL", jit.Imm(_S_vmask), _DX) // MOVL _S_vmask, DX
self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX
self.Sjmp("JNC" , "_invalid_char") // JNC _invalid_char
self.call_go(_F_makemap_small) // CALL_GO runtime.makemap_small
self.Emit("MOVQ", jit.Ptr(_SP, 0), _AX) // MOVQ (SP), AX
self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.Emit("MOVQ", jit.Imm(_S_obj_0), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_obj, ST.Vt[CX]
self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI
self.Emit("MOVQ", _T_map, _DX) // MOVQ _T_map, DX
self.Emit("MOVQ", _DX, jit.Ptr(_SI, 0)) // MOVQ DX, (SI)
self.WritePtrAX(4, jit.Ptr(_SI, 8), false) // MOVQ AX, 8(SI)
self.Sjmp("JMP" , "_next") // JMP _next
/** V_STRING **/
self.Link("_decode_V_STRING") // _decode_V_STRING:
self.Emit("MOVQ", _VAR_ss_Iv, _CX) // MOVQ ss.Iv, CX
self.Emit("MOVQ", _IC, _AX) // MOVQ IC, AX
self.Emit("SUBQ", _CX, _AX) // SUBQ CX, AX
/* check for escapes */
self.Emit("CMPQ", _VAR_ss_Ep, jit.Imm(-1)) // CMPQ ss.Ep, $-1
self.Sjmp("JNE" , "_unquote") // JNE _unquote
self.Emit("SUBQ", jit.Imm(1), _AX) // SUBQ $1, AX
self.Emit("LEAQ", jit.Sib(_IP, _CX, 1, 0), _R8) // LEAQ (IP)(CX), R8
self.Byte(0x48, 0x8d, 0x3d) // LEAQ (PC), DI
self.Sref("_copy_string_end", 4)
self.Emit("BTQ", jit.Imm(_F_copy_string), _VAR_df)
self.Sjmp("JC", "copy_string")
self.Link("_copy_string_end")
self.Emit("XORL", _DX, _DX) // XORL DX, DX
/* strings with no escape sequences */
self.Link("_noescape") // _noescape:
self.Emit("MOVL", jit.Imm(_S_omask_key), _DI) // MOVL _S_omask, DI
self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _SI) // MOVQ ST.Vt[CX], SI
self.Emit("BTQ" , _SI, _DI) // BTQ SI, DI
self.Sjmp("JC" , "_object_key") // JC _object_key
/* check for pre-packed strings, avoid 1 allocation */
self.Emit("TESTQ", _DX, _DX) // TESTQ DX, DX
self.Sjmp("JNZ" , "_packed_str") // JNZ _packed_str
self.Emit("MOVQ" , _R8, jit.Ptr(_SP, 0)) // MOVQ R8, (SP)
self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 8)) // MOVQ AX, 8(SP)
self.call_go(_F_convTstring) // CALL_GO runtime.convTstring
self.Emit("MOVQ" , jit.Ptr(_SP, 16), _R9) // MOVQ 16(SP), R9
/* packed string already in R9 */
self.Link("_packed_str") // _packed_str:
self.Emit("MOVQ", _T_string, _R8) // MOVQ _T_string, R8
self.Emit("MOVQ", _VAR_ss_Iv, _DI) // MOVQ ss.Iv, DI
self.Emit("SUBQ", jit.Imm(1), _DI) // SUBQ $1, DI
self.Sjmp("JMP" , "_set_value") // JMP _set_value
/* the string is an object key, get the map */
self.Link("_object_key")
self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI
self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI
/* add a new delimiter */
self.Emit("ADDQ", jit.Imm(1), _CX) // ADDQ $1, CX
self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE)) // CMPQ CX, ${types.MAX_RECURSE}
self.Sjmp("JAE" , "_stack_overflow") // JA _stack_overflow
self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp
self.Emit("MOVQ", jit.Imm(_S_obj_delim), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_obj_delim, ST.Vt[CX]
/* add a new slot int the map */
self.Emit("MOVQ", _T_map, _DX) // MOVQ _T_map, DX
self.Emit("MOVQ", _DX, jit.Ptr(_SP, 0)) // MOVQ DX, (SP)
self.Emit("MOVQ", _SI, jit.Ptr(_SP, 8)) // MOVQ SI, 8(SP)
self.Emit("MOVQ", _R8, jit.Ptr(_SP, 16)) // MOVQ R9, 16(SP)
self.Emit("MOVQ", _AX, jit.Ptr(_SP, 24)) // MOVQ AX, 24(SP)
self.call_go(_F_mapassign_faststr) // CALL_GO runtime.mapassign_faststr
self.Emit("MOVQ", jit.Ptr(_SP, 32), _AX) // MOVQ 32(SP), AX
/* add to the pointer stack */
self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.WritePtrAX(6, jit.Sib(_ST, _CX, 8, _ST_Vp), false) // MOVQ AX, ST.Vp[CX]
self.Sjmp("JMP" , "_next") // JMP _next
/* allocate memory to store the string header and unquoted result */
self.Link("_unquote") // _unquote:
self.Emit("ADDQ", jit.Imm(15), _AX) // ADDQ $15, AX
self.Emit("MOVQ", _T_byte, _CX) // MOVQ _T_byte, CX
self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP)
self.Emit("MOVQ", _CX, jit.Ptr(_SP, 8)) // MOVQ CX, 8(SP)
self.Emit("MOVB", jit.Imm(0), jit.Ptr(_SP, 16)) // MOVB $0, 16(SP)
self.call_go(_F_mallocgc) // CALL_GO runtime.mallocgc
self.Emit("MOVQ", jit.Ptr(_SP, 24), _R9) // MOVQ 24(SP), R9
/* prepare the unquoting parameters */
self.Emit("MOVQ" , _VAR_ss_Iv, _CX) // MOVQ ss.Iv, CX
self.Emit("LEAQ" , jit.Sib(_IP, _CX, 1, 0), _DI) // LEAQ (IP)(CX), DI
self.Emit("NEGQ" , _CX) // NEGQ CX
self.Emit("LEAQ" , jit.Sib(_IC, _CX, 1, -1), _SI) // LEAQ -1(IC)(CX), SI
self.Emit("LEAQ" , jit.Ptr(_R9, 16), _DX) // LEAQ 16(R8), DX
self.Emit("LEAQ" , _VAR_ss_Ep, _CX) // LEAQ ss.Ep, CX
self.Emit("XORL" , _R8, _R8) // XORL R8, R8
self.Emit("BTQ" , jit.Imm(_F_disable_urc), _VAR_df) // BTQ ${_F_disable_urc}, fv
self.Emit("SETCC", _R8) // SETCC R8
self.Emit("SHLQ" , jit.Imm(types.B_UNICODE_REPLACE), _R8) // SHLQ ${types.B_UNICODE_REPLACE}, R8
/* unquote the string, with R9 been preserved */
self.save(_R9) // SAVE R9
self.call(_F_unquote) // CALL unquote
self.load(_R9) // LOAD R9
/* check for errors */
self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX
self.Sjmp("JS" , "_unquote_error") // JS _unquote_error
self.Emit("MOVL" , jit.Imm(1), _DX) // MOVL $1, DX
self.Emit("LEAQ" , jit.Ptr(_R9, 16), _R8) // ADDQ $16, R8
self.Emit("MOVQ" , _R8, jit.Ptr(_R9, 0)) // MOVQ R8, (R9)
self.Emit("MOVQ" , _AX, jit.Ptr(_R9, 8)) // MOVQ AX, 8(R9)
self.Sjmp("JMP" , "_noescape") // JMP _noescape
/** V_DOUBLE **/
self.Link("_decode_V_DOUBLE") // _decode_V_DOUBLE:
self.Emit("BTQ" , jit.Imm(_F_use_number), _VAR_df) // BTQ _F_use_number, df
self.Sjmp("JC" , "_use_number") // JC _use_number
self.Emit("MOVSD", _VAR_ss_Dv, _X0) // MOVSD ss.Dv, X0
self.Sjmp("JMP" , "_use_float64") // JMP _use_float64
/** V_INTEGER **/
self.Link("_decode_V_INTEGER") // _decode_V_INTEGER:
self.Emit("BTQ" , jit.Imm(_F_use_number), _VAR_df) // BTQ _F_use_number, df
self.Sjmp("JC" , "_use_number") // JC _use_number
self.Emit("BTQ" , jit.Imm(_F_use_int64), _VAR_df) // BTQ _F_use_int64, df
self.Sjmp("JC" , "_use_int64") // JC _use_int64
self.Emit("MOVQ" , _VAR_ss_Iv, _AX) // MOVQ ss.Iv, AX
self.Emit("CVTSQ2SD", _AX, _X0) // CVTSQ2SD AX, X0
/* represent numbers as `float64` */
self.Link("_use_float64") // _use_float64:
self.Emit("MOVSD", _X0, jit.Ptr(_SP, 0)) // MOVSD X0, (SP)
self.call_go(_F_convT64) // CALL_GO runtime.convT64
self.Emit("MOVQ" , _T_float64, _R8) // MOVQ _T_float64, R8
self.Emit("MOVQ" , jit.Ptr(_SP, 8), _R9) // MOVQ 8(SP), R9
self.Emit("MOVQ" , _VAR_ss_Ep, _DI) // MOVQ ss.Ep, DI
self.Sjmp("JMP" , "_set_value") // JMP _set_value
/* represent numbers as `json.Number` */
self.Link("_use_number") // _use_number
self.Emit("MOVQ", _VAR_ss_Ep, _AX) // MOVQ ss.Ep, AX
self.Emit("LEAQ", jit.Sib(_IP, _AX, 1, 0), _SI) // LEAQ (IP)(AX), SI
self.Emit("MOVQ", _IC, _CX) // MOVQ IC, CX
self.Emit("SUBQ", _AX, _CX) // SUBQ AX, CX
self.Emit("MOVQ", _SI, jit.Ptr(_SP, 0)) // MOVQ SI, (SP)
self.Emit("MOVQ", _CX, jit.Ptr(_SP, 8)) // MOVQ CX, 8(SP)
self.call_go(_F_convTstring) // CALL_GO runtime.convTstring
self.Emit("MOVQ", _T_number, _R8) // MOVQ _T_number, R8
self.Emit("MOVQ", jit.Ptr(_SP, 16), _R9) // MOVQ 16(SP), R9
self.Emit("MOVQ", _VAR_ss_Ep, _DI) // MOVQ ss.Ep, DI
self.Sjmp("JMP" , "_set_value") // JMP _set_value
/* represent numbers as `int64` */
self.Link("_use_int64") // _use_int64:
self.Emit("MOVQ", _VAR_ss_Iv, _AX) // MOVQ ss.Iv, AX
self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP)
self.call_go(_F_convT64) // CALL_GO runtime.convT64
self.Emit("MOVQ", _T_int64, _R8) // MOVQ _T_int64, R8
self.Emit("MOVQ", jit.Ptr(_SP, 8), _R9) // MOVQ 8(SP), R9
self.Emit("MOVQ", _VAR_ss_Ep, _DI) // MOVQ ss.Ep, DI
self.Sjmp("JMP" , "_set_value") // JMP _set_value
/** V_KEY_SEP **/
self.Link("_decode_V_KEY_SEP") // _decode_V_KEY_SEP:
// self.Byte(0xcc)
self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
self.Emit("CMPQ", _AX, jit.Imm(_S_obj_delim)) // CMPQ AX, _S_obj_delim
self.Sjmp("JNE" , "_invalid_char") // JNE _invalid_char
self.Emit("MOVQ", jit.Imm(_S_val), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_val, ST.Vt[CX]
self.Emit("MOVQ", jit.Imm(_S_obj), jit.Sib(_ST, _CX, 8, _ST_Vt - 8)) // MOVQ _S_obj, ST.Vt[CX - 1]
self.Sjmp("JMP" , "_next") // JMP _next
/** V_ELEM_SEP **/
self.Link("_decode_V_ELEM_SEP") // _decode_V_ELEM_SEP:
self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.Emit("MOVQ" , jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
self.Emit("CMPQ" , _AX, jit.Imm(_S_arr)) // CMPQ _AX, _S_arr
self.Sjmp("JE" , "_array_sep") // JZ _next
self.Emit("CMPQ" , _AX, jit.Imm(_S_obj)) // CMPQ _AX, _S_arr
self.Sjmp("JNE" , "_invalid_char") // JNE _invalid_char
self.Emit("MOVQ" , jit.Imm(_S_obj_sep), jit.Sib(_ST, _CX, 8, _ST_Vt))
self.Sjmp("JMP" , "_next") // JMP _next
/* arrays */
self.Link("_array_sep")
self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI
self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI
self.Emit("MOVQ", jit.Ptr(_SI, 8), _DX) // MOVQ 8(SI), DX
self.Emit("CMPQ", _DX, jit.Ptr(_SI, 16)) // CMPQ DX, 16(SI)
self.Sjmp("JAE" , "_array_more") // JAE _array_more
/* add a slot for the new element */
self.Link("_array_append") // _array_append:
self.Emit("ADDQ", jit.Imm(1), jit.Ptr(_SI, 8)) // ADDQ $1, 8(SI)
self.Emit("MOVQ", jit.Ptr(_SI, 0), _SI) // MOVQ (SI), SI
self.Emit("ADDQ", jit.Imm(1), _CX) // ADDQ $1, CX
self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE)) // CMPQ CX, ${types.MAX_RECURSE}
self.Sjmp("JAE" , "_stack_overflow")
self.Emit("SHLQ", jit.Imm(1), _DX) // SHLQ $1, DX
self.Emit("LEAQ", jit.Sib(_SI, _DX, 8, 0), _SI) // LEAQ (SI)(DX*8), SI
self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp
self.WriteRecNotAX(7 , _SI, jit.Sib(_ST, _CX, 8, _ST_Vp), false) // MOVQ SI, ST.Vp[CX]
self.Emit("MOVQ", jit.Imm(_S_val), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_val, ST.Vt[CX}
self.Sjmp("JMP" , "_next") // JMP _next
/** V_ARRAY_END **/
self.Link("_decode_V_ARRAY_END") // _decode_V_ARRAY_END:
self.Emit("XORL", _DX, _DX) // XORL DX, DX
self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
self.Emit("CMPQ", _AX, jit.Imm(_S_arr_0)) // CMPQ AX, _S_arr_0
self.Sjmp("JE" , "_first_item") // JE _first_item
self.Emit("CMPQ", _AX, jit.Imm(_S_arr)) // CMPQ AX, _S_arr
self.Sjmp("JNE" , "_invalid_char") // JNE _invalid_char
self.Emit("SUBQ", jit.Imm(1), jit.Ptr(_ST, _ST_Sp)) // SUBQ $1, ST.Sp
self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp)) // MOVQ DX, ST.Vp[CX]
self.Sjmp("JMP" , "_next") // JMP _next
/* first element of an array */
self.Link("_first_item") // _first_item:
self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.Emit("SUBQ", jit.Imm(2), jit.Ptr(_ST, _ST_Sp)) // SUBQ $2, ST.Sp
self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp - 8), _SI) // MOVQ ST.Vp[CX - 1], SI
self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI
self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp - 8)) // MOVQ DX, ST.Vp[CX - 1]
self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp)) // MOVQ DX, ST.Vp[CX]
self.Emit("MOVQ", _DX, jit.Ptr(_SI, 8)) // MOVQ DX, 8(SI)
self.Sjmp("JMP" , "_next") // JMP _next
/** V_OBJECT_END **/
self.Link("_decode_V_OBJECT_END") // _decode_V_OBJECT_END:
self.Emit("MOVL", jit.Imm(_S_omask_end), _DX) // MOVL _S_omask, DI
self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
self.Emit("BTQ" , _AX, _DX)
self.Sjmp("JNC" , "_invalid_char") // JNE _invalid_char
self.Emit("XORL", _AX, _AX) // XORL AX, AX
self.Emit("SUBQ", jit.Imm(1), jit.Ptr(_ST, _ST_Sp)) // SUBQ $1, ST.Sp
self.Emit("MOVQ", _AX, jit.Sib(_ST, _CX, 8, _ST_Vp)) // MOVQ AX, ST.Vp[CX]
self.Sjmp("JMP" , "_next") // JMP _next
/* return from decoder */
self.Link("_return") // _return:
self.Emit("XORL", _EP, _EP) // XORL EP, EP
self.Emit("MOVQ", _EP, jit.Ptr(_ST, _ST_Vp)) // MOVQ EP, ST.Vp[0]
self.Link("_epilogue") // _epilogue:
self.Emit("SUBQ", jit.Imm(_FsmOffset), _ST) // SUBQ _FsmOffset, _ST
self.Emit("MOVQ", jit.Ptr(_SP, _VD_offs), _BP) // MOVQ _VD_offs(SP), BP
self.Emit("ADDQ", jit.Imm(_VD_size), _SP) // ADDQ $_VD_size, SP
self.Emit("RET") // RET
/* array expand */
self.Link("_array_more") // _array_more:
self.Emit("MOVQ" , _T_eface, _AX) // MOVQ _T_eface, AX
self.Emit("MOVOU", jit.Ptr(_SI, 0), _X0) // MOVOU (SI), X0
self.Emit("MOVQ" , jit.Ptr(_SI, 16), _DX) // MOVQ 16(SI), DX
self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP)
self.Emit("MOVOU", _X0, jit.Ptr(_SP, 8)) // MOVOU X0, 8(SP)
self.Emit("MOVQ" , _DX, jit.Ptr(_SP, 24)) // MOVQ DX, 24(SP)
self.Emit("SHLQ" , jit.Imm(1), _DX) // SHLQ $1, DX
self.Emit("MOVQ" , _DX, jit.Ptr(_SP, 32)) // MOVQ DX, 32(SP)
self.call_go(_F_growslice) // CALL_GO runtime.growslice
self.Emit("MOVQ" , jit.Ptr(_SP, 40), _DI) // MOVOU 40(SP), DI
self.Emit("MOVQ" , jit.Ptr(_SP, 48), _DX) // MOVOU 48(SP), DX
self.Emit("MOVQ" , jit.Ptr(_SP, 56), _AX) // MOVQ 56(SP), AX
/* update the slice */
self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI
self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI
self.Emit("MOVQ", _DX, jit.Ptr(_SI, 8)) // MOVQ DX, 8(SI)
self.Emit("MOVQ", _AX, jit.Ptr(_SI, 16)) // MOVQ AX, 16(AX)
self.WriteRecNotAX(8 , _DI, jit.Ptr(_SI, 0), false) // MOVQ R10, (SI)
self.Sjmp("JMP" , "_array_append") // JMP _array_append
/* copy string */
self.Link("copy_string") // pointer: R8, length: AX, return addr: DI
// self.Byte(0xcc)
self.Emit("MOVQ", _R8, _VAR_cs_p)
self.Emit("MOVQ", _AX, _VAR_cs_n)
self.Emit("MOVQ", _DI, _VAR_cs_LR)
self.Emit("MOVQ", _T_byte, _R8)
self.Emit("MOVQ", _R8, jit.Ptr(_SP, 0))
self.Emit("MOVQ", _AX, jit.Ptr(_SP, 8))
self.Emit("MOVQ", _AX, jit.Ptr(_SP, 16))
self.call_go(_F_makeslice)
self.Emit("MOVQ", jit.Ptr(_SP, 24), _R8)
self.Emit("MOVQ", _R8, _VAR_cs_d)
self.Emit("MOVQ", _R8, jit.Ptr(_SP, 0))
self.Emit("MOVQ", _VAR_cs_p, _R8)
self.Emit("MOVQ", _R8, jit.Ptr(_SP, 8))
self.Emit("MOVQ", _VAR_cs_n, _AX)
self.Emit("MOVQ", _AX, jit.Ptr(_SP, 16))
self.call_go(_F_memmove)
self.Emit("MOVQ", _VAR_cs_d, _R8)
self.Emit("MOVQ", _VAR_cs_n, _AX)
self.Emit("MOVQ", _VAR_cs_LR, _DI)
// self.Byte(0xcc)
self.Rjmp("JMP", _DI)
/* error handlers */
self.Link("_stack_overflow")
self.Emit("MOVL" , _E_recurse, _EP) // MOVQ _E_recurse, EP
self.Sjmp("JMP" , "_error") // JMP _error
self.Link("_vtype_error") // _vtype_error:
self.Emit("MOVQ" , _DI, _IC) // MOVQ DI, IC
self.Emit("MOVL" , _E_invalid, _EP) // MOVL _E_invalid, EP
self.Sjmp("JMP" , "_error") // JMP _error
self.Link("_invalid_char") // _invalid_char:
self.Emit("SUBQ" , jit.Imm(1), _IC) // SUBQ $1, IC
self.Emit("MOVL" , _E_invalid, _EP) // MOVL _E_invalid, EP
self.Sjmp("JMP" , "_error") // JMP _error
self.Link("_unquote_error") // _unquote_error:
self.Emit("MOVQ" , _VAR_ss_Iv, _IC) // MOVQ ss.Iv, IC
self.Emit("SUBQ" , jit.Imm(1), _IC) // SUBQ $1, IC
self.Link("_parsing_error") // _parsing_error:
self.Emit("NEGQ" , _AX) // NEGQ AX
self.Emit("MOVQ" , _AX, _EP) // MOVQ AX, EP
self.Link("_error") // _error:
self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0
self.Emit("MOVOU", _X0, jit.Ptr(_VP, 0)) // MOVOU X0, (VP)
self.Sjmp("JMP" , "_epilogue") // JMP _epilogue
/* invalid value type, never returns */
self.Link("_invalid_vtype")
self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP)
self.call(_F_invalid_vtype) // CALL invalid_type
self.Emit("UD2") // UD2
/* switch jump table */
self.Link("_switch_table") // _switch_table:
self.Sref("_decode_V_EOF", 0) // SREF &_decode_V_EOF, $0
self.Sref("_decode_V_NULL", -4) // SREF &_decode_V_NULL, $-4
self.Sref("_decode_V_TRUE", -8) // SREF &_decode_V_TRUE, $-8
self.Sref("_decode_V_FALSE", -12) // SREF &_decode_V_FALSE, $-12
self.Sref("_decode_V_ARRAY", -16) // SREF &_decode_V_ARRAY, $-16
self.Sref("_decode_V_OBJECT", -20) // SREF &_decode_V_OBJECT, $-20
self.Sref("_decode_V_STRING", -24) // SREF &_decode_V_STRING, $-24
self.Sref("_decode_V_DOUBLE", -28) // SREF &_decode_V_DOUBLE, $-28
self.Sref("_decode_V_INTEGER", -32) // SREF &_decode_V_INTEGER, $-32
self.Sref("_decode_V_KEY_SEP", -36) // SREF &_decode_V_KEY_SEP, $-36
self.Sref("_decode_V_ELEM_SEP", -40) // SREF &_decode_V_ELEM_SEP, $-40
self.Sref("_decode_V_ARRAY_END", -44) // SREF &_decode_V_ARRAY_END, $-44
self.Sref("_decode_V_OBJECT_END", -48) // SREF &_decode_V_OBJECT_END, $-48
/* fast character lookup table */
self.Link("_decode_tab") // _decode_tab:
self.Sref("_decode_V_EOF", 0) // SREF &_decode_V_EOF, $0
/* generate rest of the tabs */
for i := 1; i < 256; i++ {
if to, ok := _R_tab[i]; ok {
self.Sref(to, -int64(i) * 4)
} else {
self.Byte(0x00, 0x00, 0x00, 0x00)
}
}
}
/** Generic Decoder **/
var (
_subr_decode_value = new(_ValueDecoder).build()
)
//go:nosplit
func invalid_vtype(vt types.ValueType) {
throw(fmt.Sprintf("invalid value type: %d", vt))
}

View file

@ -1,37 +0,0 @@
// +build go1.16,!go1.17
//
// 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.
//
#include "go_asm.h"
#include "funcdata.h"
#include "textflag.h"
TEXT ·decodeValueStub(SB), NOSPLIT, $0 - 72
NO_LOCAL_POINTERS
PXOR X0, X0
MOVOU X0, rv+48(FP)
MOVQ st+0(FP), BX
MOVQ sp+8(FP), R12
MOVQ sn+16(FP), R13
MOVQ ic+24(FP), R14
MOVQ vp+32(FP), R15
MOVQ df+40(FP), R10
MOVQ ·_subr_decode_value(SB), AX
CALL AX
MOVQ R14, rp+48(FP)
MOVQ R11, ex+56(FP)
RET

View file

@ -14,7 +14,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package decoder
package jitdec
import (
`strconv`

View file

@ -1,4 +1,4 @@
// +build go1.21,!go1.23
// +build go1.21,!go1.24
// Copyright 2023 CloudWeGo Authors
//
@ -14,7 +14,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package decoder
package jitdec
import (
`strconv`

View file

@ -1,4 +1,5 @@
// +build go1.17,!go1.23
//go:build go1.17 && !go1.24
// +build go1.17,!go1.24
/*
* Copyright 2021 ByteDance Inc.
@ -16,21 +17,22 @@
* limitations under the License.
*/
package decoder
package jitdec
import (
`encoding/json`
`fmt`
`math`
`reflect`
`unsafe`
"encoding/json"
"fmt"
"math"
"reflect"
"strings"
"unsafe"
`github.com/bytedance/sonic/internal/caching`
`github.com/bytedance/sonic/internal/jit`
`github.com/bytedance/sonic/internal/native`
`github.com/bytedance/sonic/internal/native/types`
`github.com/bytedance/sonic/internal/rt`
`github.com/twitchyliquid64/golang-asm/obj`
"github.com/bytedance/sonic/internal/caching"
"github.com/bytedance/sonic/internal/jit"
"github.com/bytedance/sonic/internal/native"
"github.com/bytedance/sonic/internal/native/types"
"github.com/bytedance/sonic/internal/rt"
"github.com/twitchyliquid64/golang-asm/obj"
)
/** Register Allocations
@ -292,7 +294,6 @@ var _OpFuncTab = [256]func(*_Assembler, *_Instr) {
_OP_array_clear_p : (*_Assembler)._asm_OP_array_clear_p,
_OP_slice_init : (*_Assembler)._asm_OP_slice_init,
_OP_slice_append : (*_Assembler)._asm_OP_slice_append,
_OP_object_skip : (*_Assembler)._asm_OP_object_skip,
_OP_object_next : (*_Assembler)._asm_OP_object_next,
_OP_struct_field : (*_Assembler)._asm_OP_struct_field,
_OP_unmarshal : (*_Assembler)._asm_OP_unmarshal,
@ -312,6 +313,7 @@ var _OpFuncTab = [256]func(*_Assembler, *_Instr) {
_OP_check_char_0 : (*_Assembler)._asm_OP_check_char_0,
_OP_dismatch_err : (*_Assembler)._asm_OP_dismatch_err,
_OP_go_skip : (*_Assembler)._asm_OP_go_skip,
_OP_skip_emtpy : (*_Assembler)._asm_OP_skip_empty,
_OP_add : (*_Assembler)._asm_OP_add,
_OP_check_empty : (*_Assembler)._asm_OP_check_empty,
_OP_debug : (*_Assembler)._asm_OP_debug,
@ -385,7 +387,7 @@ func (self *_Assembler) prologue() {
var (
_REG_go = []obj.Addr { _ST, _VP, _IP, _IL, _IC }
_REG_rt = []obj.Addr { _ST, _VP, _IP, _IL, _IC, _IL }
_REG_rt = []obj.Addr { _ST, _VP, _IP, _IL, _IC }
)
func (self *_Assembler) save(r ...obj.Addr) {
@ -481,6 +483,7 @@ var (
_V_stackOverflow = jit.Imm(int64(uintptr(unsafe.Pointer(&stackOverflow))))
_I_json_UnsupportedValueError = jit.Itab(_T_error, reflect.TypeOf(new(json.UnsupportedValueError)))
_I_json_MismatchTypeError = jit.Itab(_T_error, reflect.TypeOf(new(MismatchTypeError)))
_I_json_MismatchQuotedError = jit.Itab(_T_error, reflect.TypeOf(new(MismatchQuotedError)))
)
func (self *_Assembler) type_error() {
@ -492,9 +495,9 @@ func (self *_Assembler) type_error() {
func (self *_Assembler) mismatch_error() {
self.Link(_LB_mismatch_error) // _type_error:
self.Emit("MOVQ", _VAR_et, _ET) // MOVQ _VAR_et, ET
self.Emit("MOVQ", _VAR_ic, _EP) // MOVQ _VAR_ic, EP
self.Emit("MOVQ", _I_json_MismatchTypeError, _CX) // MOVQ _I_json_MismatchType, CX
self.Emit("CMPQ", _ET, _CX) // CMPQ ET, CX
self.Emit("MOVQ", jit.Ptr(_ST, _EpOffset), _EP) // MOVQ stack.Ep, EP
self.Sjmp("JE" , _LB_error) // JE _LB_error
self.Emit("MOVQ", _ARG_sp, _AX)
self.Emit("MOVQ", _ARG_sl, _BX)
@ -600,6 +603,28 @@ func (self *_Assembler) _asm_OP_go_skip(p *_Instr) {
self.Sjmp("JMP" , _LB_skip_one) // JMP _skip_one
}
var _F_IndexByte = jit.Func(strings.IndexByte)
func (self *_Assembler) _asm_OP_skip_empty(p *_Instr) {
// self.Byte(0xcc)
self.call_sf(_F_skip_one) // CALL_SF skip_one
// self.Byte(0xcc)
self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX
self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v
self.Emit("BTQ", jit.Imm(_F_disable_unknown), _ARG_fv)
self.Xjmp("JNC", p.vi())
self.Emit("LEAQ", jit.Sib(_IC, _AX, 1, 0), _BX)
self.Emit("MOVQ", _BX, _ARG_sv_n)
self.Emit("LEAQ", jit.Sib(_IP, _AX, 1, 0), _AX)
self.Emit("MOVQ", _AX, _ARG_sv_p)
self.Emit("MOVQ", jit.Imm(':'), _CX)
self.call_go(_F_IndexByte)
// self.Byte(0xcc)
self.Emit("TESTQ", _AX, _AX)
// disallow unknown field
self.Sjmp("JNS", _LB_field_error)
}
func (self *_Assembler) skip_one() {
self.Link(_LB_skip_one) // _skip:
self.Emit("MOVQ", _VAR_ic, _IC) // MOVQ _VAR_ic, IC
@ -972,11 +997,13 @@ var (
var (
_F_decodeJsonUnmarshaler obj.Addr
_F_decodeJsonUnmarshalerQuoted obj.Addr
_F_decodeTextUnmarshaler obj.Addr
)
func init() {
_F_decodeJsonUnmarshaler = jit.Func(decodeJsonUnmarshaler)
_F_decodeJsonUnmarshalerQuoted = jit.Func(decodeJsonUnmarshalerQuoted)
_F_decodeTextUnmarshaler = jit.Func(decodeTextUnmarshaler)
}
@ -1057,18 +1084,18 @@ func (self *_Assembler) mapassign_utext(t reflect.Type, addressable bool) {
var (
_F_skip_one = jit.Imm(int64(native.S_skip_one))
_F_skip_array = jit.Imm(int64(native.S_skip_array))
_F_skip_object = jit.Imm(int64(native.S_skip_object))
_F_skip_number = jit.Imm(int64(native.S_skip_number))
)
func (self *_Assembler) unmarshal_json(t reflect.Type, deref bool) {
func (self *_Assembler) unmarshal_json(t reflect.Type, deref bool, f obj.Addr) {
self.call_sf(_F_skip_one) // CALL_SF skip_one
self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX
self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v
self.Emit("MOVQ", _IC, _VAR_ic) // store for mismatche error skip
self.slice_from_r(_AX, 0) // SLICE_R AX, $0
self.Emit("MOVQ" , _DI, _ARG_sv_p) // MOVQ DI, sv.p
self.Emit("MOVQ" , _SI, _ARG_sv_n) // MOVQ SI, sv.n
self.unmarshal_func(t, _F_decodeJsonUnmarshaler, deref) // UNMARSHAL json, ${t}, ${deref}
self.unmarshal_func(t, f, deref) // UNMARSHAL json, ${t}, ${deref}
}
func (self *_Assembler) unmarshal_text(t reflect.Type, deref bool) {
@ -1103,7 +1130,19 @@ func (self *_Assembler) unmarshal_func(t reflect.Type, fn obj.Addr, deref bool)
self.Emit("MOVQ" , _ARG_sv_n, _DI) // MOVQ sv.n, DI
self.call_go(fn) // CALL_GO ${fn}
self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET
self.Sjmp("JNZ" , _LB_error) // JNZ _error
if fn == _F_decodeJsonUnmarshalerQuoted {
self.Sjmp("JZ" , "_unmarshal_func_end_{n}") // JZ _unmarshal_func_end_{n}
self.Emit("MOVQ", _I_json_MismatchQuotedError, _CX) // MOVQ _I_json_MismatchQuotedError, CX
self.Emit("CMPQ", _ET, _CX) // check if MismatchQuotedError
self.Sjmp("JNE" , _LB_error) // JNE _error
self.Emit("MOVQ", jit.Type(t), _CX) // store current type
self.Emit("MOVQ", _CX, _VAR_et) // store current type as mismatched type
self.Emit("MOVQ", _VAR_ic, _IC) // recover the pos at mismatched, continue to parse
self.Emit("XORL", _ET, _ET) // clear ET
self.Link("_unmarshal_func_end_{n}")
} else {
self.Sjmp("JNE" , _LB_error) // JNE _error
}
}
/** Dynamic Decoding Routine **/
@ -1136,8 +1175,8 @@ func (self *_Assembler) decode_dynamic(vt obj.Addr, vp obj.Addr) {
self.Emit("MOVQ", _I_json_MismatchTypeError, _CX) // MOVQ _I_json_MismatchTypeError, CX
self.Emit("CMPQ", _ET, _CX) // CMPQ ET, CX
self.Sjmp("JNE", _LB_error) // JNE LB_error
self.Emit("MOVQ", _EP, _VAR_ic) // MOVQ EP, VAR_ic
self.Emit("MOVQ", _ET, _VAR_et) // MOVQ ET, VAR_et
self.WriteRecNotAX(14, _EP, jit.Ptr(_ST, _EpOffset), false, false) // MOVQ EP, stack.Ep
self.Link("_decode_dynamic_end_{n}")
}
@ -1146,7 +1185,7 @@ func (self *_Assembler) decode_dynamic(vt obj.Addr, vp obj.Addr) {
var (
_F_memequal = jit.Func(memequal)
_F_memmove = jit.Func(memmove)
_F_growslice = jit.Func(growslice)
_F_growslice = jit.Func(rt.GrowSlice)
_F_makeslice = jit.Func(makeslice)
_F_makemap_small = jit.Func(makemap_small)
_F_mapassign_fast64 = jit.Func(mapassign_fast64)
@ -1698,12 +1737,6 @@ func (self *_Assembler) _asm_OP_slice_append(p *_Instr) {
self.Link("_append_slice_end_{n}")
}
func (self *_Assembler) _asm_OP_object_skip(_ *_Instr) {
self.call_sf(_F_skip_object) // CALL_SF skip_object
self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX
self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v
}
func (self *_Assembler) _asm_OP_object_next(_ *_Instr) {
self.call_sf(_F_skip_one) // CALL_SF skip_one
self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX
@ -1774,11 +1807,19 @@ func (self *_Assembler) _asm_OP_struct_field(p *_Instr) {
}
func (self *_Assembler) _asm_OP_unmarshal(p *_Instr) {
self.unmarshal_json(p.vt(), true)
if iv := p.i64(); iv != 0 {
self.unmarshal_json(p.vt(), true, _F_decodeJsonUnmarshalerQuoted)
} else {
self.unmarshal_json(p.vt(), true, _F_decodeJsonUnmarshaler)
}
}
func (self *_Assembler) _asm_OP_unmarshal_p(p *_Instr) {
self.unmarshal_json(p.vt(), false)
if iv := p.i64(); iv != 0 {
self.unmarshal_json(p.vt(), false, _F_decodeJsonUnmarshalerQuoted)
} else {
self.unmarshal_json(p.vt(), false, _F_decodeJsonUnmarshaler)
}
}
func (self *_Assembler) _asm_OP_unmarshal_text(p *_Instr) {

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package decoder
package jitdec
import (
`encoding/json`
@ -77,7 +77,6 @@ const (
_OP_array_clear_p
_OP_slice_init
_OP_slice_append
_OP_object_skip
_OP_object_next
_OP_struct_field
_OP_unmarshal
@ -97,6 +96,7 @@ const (
_OP_check_char_0
_OP_dismatch_err
_OP_go_skip
_OP_skip_emtpy
_OP_add
_OP_check_empty
_OP_debug
@ -155,7 +155,6 @@ var _OpNames = [256]string {
_OP_array_skip : "array_skip",
_OP_slice_init : "slice_init",
_OP_slice_append : "slice_append",
_OP_object_skip : "object_skip",
_OP_object_next : "object_next",
_OP_struct_field : "struct_field",
_OP_unmarshal : "unmarshal",
@ -271,6 +270,13 @@ func newInsVt(op _Op, vt reflect.Type) _Instr {
}
}
func newInsVtI(op _Op, vt reflect.Type, iv int) _Instr {
return _Instr {
u: packOp(op) | rt.PackInt(iv),
p: unsafe.Pointer(rt.UnpackType(vt)),
}
}
func newInsVf(op _Op, vf *caching.FieldMap) _Instr {
return _Instr {
u: packOp(op),
@ -452,6 +458,10 @@ func (self *_Program) rtt(op _Op, vt reflect.Type) {
*self = append(*self, newInsVt(op, vt))
}
func (self *_Program) rtti(op _Op, vt reflect.Type, iv int) {
*self = append(*self, newInsVtI(op, vt, iv))
}
func (self *_Program) fmv(op _Op, vf *caching.FieldMap) {
*self = append(*self, newInsVf(op, vf))
}
@ -527,35 +537,54 @@ func (self *_Compiler) compile(vt reflect.Type) (ret _Program, err error) {
return
}
func (self *_Compiler) checkMarshaler(p *_Program, vt reflect.Type) bool {
const (
checkMarshalerFlags_quoted = 1
)
func (self *_Compiler) checkMarshaler(p *_Program, vt reflect.Type, flags int, exec bool) bool {
pt := reflect.PtrTo(vt)
/* check for `json.Unmarshaler` with pointer receiver */
if pt.Implements(jsonUnmarshalerType) {
p.rtt(_OP_unmarshal_p, pt)
if exec {
p.add(_OP_lspace)
p.rtti(_OP_unmarshal_p, pt, flags)
}
return true
}
/* check for `json.Unmarshaler` */
if vt.Implements(jsonUnmarshalerType) {
p.add(_OP_lspace)
self.compileUnmarshalJson(p, vt)
if exec {
p.add(_OP_lspace)
self.compileUnmarshalJson(p, vt, flags)
}
return true
}
if flags == checkMarshalerFlags_quoted {
// text marshaler shouldn't be supported for quoted string
return false
}
/* check for `encoding.TextMarshaler` with pointer receiver */
if pt.Implements(encodingTextUnmarshalerType) {
p.add(_OP_lspace)
self.compileUnmarshalTextPtr(p, pt)
if exec {
p.add(_OP_lspace)
self.compileUnmarshalTextPtr(p, pt, flags)
}
return true
}
/* check for `encoding.TextUnmarshaler` */
if vt.Implements(encodingTextUnmarshalerType) {
p.add(_OP_lspace)
self.compileUnmarshalText(p, vt)
if exec {
p.add(_OP_lspace)
self.compileUnmarshalText(p, vt, flags)
}
return true
}
return false
}
@ -567,7 +596,7 @@ func (self *_Compiler) compileOne(p *_Program, sp int, vt reflect.Type) {
return
}
if self.checkMarshaler(p, vt) {
if self.checkMarshaler(p, vt, 0, true) {
return
}
@ -690,7 +719,7 @@ func (self *_Compiler) compilePtr(p *_Program, sp int, et reflect.Type) {
/* dereference all the way down */
for et.Kind() == reflect.Ptr {
if self.checkMarshaler(p, et) {
if self.checkMarshaler(p, et, 0, true) {
return
}
et = et.Elem()
@ -872,7 +901,24 @@ func (self *_Compiler) compileStructBody(p *_Program, sp int, vt reflect.Type) {
n := p.pc()
p.add(_OP_is_null)
skip := self.checkIfSkip(p, vt, '{')
j := p.pc()
p.chr(_OP_check_char_0, '{')
p.rtt(_OP_dismatch_err, vt)
/* special case for empty object */
if len(fv) == 0 {
p.pin(j)
s := p.pc()
p.add(_OP_skip_emtpy)
p.pin(s)
p.pin(n)
return
}
skip := p.pc()
p.add(_OP_go_skip)
p.pin(j)
p.int(_OP_add, 1)
p.add(_OP_save)
p.add(_OP_lspace)
@ -890,11 +936,6 @@ func (self *_Compiler) compileStructBody(p *_Program, sp int, vt reflect.Type) {
p.chr(_OP_check_char, '}')
p.chr(_OP_match_char, ',')
/* special case of an empty struct */
if len(fv) == 0 {
p.add(_OP_object_skip)
goto end_of_object
}
/* match the remaining fields */
p.add(_OP_lspace)
@ -930,7 +971,6 @@ func (self *_Compiler) compileStructBody(p *_Program, sp int, vt reflect.Type) {
p.int(_OP_goto, y0)
}
end_of_object:
p.pin(x)
p.pin(y1)
p.add(_OP_drop)
@ -938,7 +978,22 @@ end_of_object:
p.pin(skip)
}
func (self *_Compiler) compileStructFieldStrUnmarshal(p *_Program, vt reflect.Type) {
p.add(_OP_lspace)
n0 := p.pc()
p.add(_OP_is_null)
self.checkMarshaler(p, vt, checkMarshalerFlags_quoted, true)
p.pin(n0)
}
func (self *_Compiler) compileStructFieldStr(p *_Program, sp int, vt reflect.Type) {
// according to std, json.Unmarshaler should be called before stringize
// see https://github.com/bytedance/sonic/issues/670
if self.checkMarshaler(p, vt, checkMarshalerFlags_quoted, false) {
self.compileStructFieldStrUnmarshal(p, vt)
return
}
n1 := -1
ft := vt
sv := false
@ -1106,7 +1161,7 @@ func (self *_Compiler) compileUnmarshalEnd(p *_Program, vt reflect.Type, i int)
p.pin(j)
}
func (self *_Compiler) compileUnmarshalJson(p *_Program, vt reflect.Type) {
func (self *_Compiler) compileUnmarshalJson(p *_Program, vt reflect.Type, flags int) {
i := p.pc()
v := _OP_unmarshal
p.add(_OP_is_null)
@ -1117,11 +1172,11 @@ func (self *_Compiler) compileUnmarshalJson(p *_Program, vt reflect.Type) {
}
/* call the unmarshaler */
p.rtt(v, vt)
p.rtti(v, vt, flags)
self.compileUnmarshalEnd(p, vt, i)
}
func (self *_Compiler) compileUnmarshalText(p *_Program, vt reflect.Type) {
func (self *_Compiler) compileUnmarshalText(p *_Program, vt reflect.Type, iv int) {
i := p.pc()
v := _OP_unmarshal_text
p.add(_OP_is_null)
@ -1134,15 +1189,15 @@ func (self *_Compiler) compileUnmarshalText(p *_Program, vt reflect.Type) {
}
/* call the unmarshaler */
p.rtt(v, vt)
p.rtti(v, vt, iv)
self.compileUnmarshalEnd(p, vt, i)
}
func (self *_Compiler) compileUnmarshalTextPtr(p *_Program, vt reflect.Type) {
func (self *_Compiler) compileUnmarshalTextPtr(p *_Program, vt reflect.Type, iv int) {
i := p.pc()
p.add(_OP_is_null)
p.chr(_OP_match_char, '"')
p.rtt(_OP_unmarshal_text_p, vt)
p.rtti(_OP_unmarshal_text_p, vt, iv)
p.pin(i)
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package decoder
package jitdec
import (
`os`

View file

@ -0,0 +1,140 @@
package jitdec
import (
`unsafe`
`encoding/json`
`reflect`
`runtime`
`github.com/bytedance/sonic/internal/decoder/consts`
`github.com/bytedance/sonic/internal/decoder/errors`
`github.com/bytedance/sonic/internal/rt`
`github.com/bytedance/sonic/utf8`
`github.com/bytedance/sonic/option`
)
type (
MismatchTypeError = errors.MismatchTypeError
SyntaxError = errors.SyntaxError
)
const (
_F_allow_control = consts.F_allow_control
_F_copy_string = consts.F_copy_string
_F_disable_unknown = consts.F_disable_unknown
_F_disable_urc = consts.F_disable_urc
_F_use_int64 = consts.F_use_int64
_F_use_number = consts.F_use_number
_F_no_validate_json = consts.F_no_validate_json
_F_validate_string = consts.F_validate_string
)
var (
error_wrap = errors.ErrorWrap
error_type = errors.ErrorType
error_field = errors.ErrorField
error_value = errors.ErrorValue
error_mismatch = errors.ErrorMismatch
stackOverflow = errors.StackOverflow
)
// Decode parses the JSON-encoded data from current position and stores the result
// in the value pointed to by val.
func Decode(s *string, i *int, f uint64, val interface{}) error {
/* validate json if needed */
if (f & (1 << _F_validate_string)) != 0 && !utf8.ValidateString(*s){
dbuf := utf8.CorrectWith(nil, rt.Str2Mem(*s), "\ufffd")
*s = rt.Mem2Str(dbuf)
}
vv := rt.UnpackEface(val)
vp := vv.Value
/* check for nil type */
if vv.Type == nil {
return &json.InvalidUnmarshalError{}
}
/* must be a non-nil pointer */
if vp == nil || vv.Type.Kind() != reflect.Ptr {
return &json.InvalidUnmarshalError{Type: vv.Type.Pack()}
}
etp := rt.PtrElem(vv.Type)
/* check the defined pointer type for issue 379 */
if vv.Type.IsNamed() {
newp := vp
etp = vv.Type
vp = unsafe.Pointer(&newp)
}
/* create a new stack, and call the decoder */
sb := newStack()
nb, err := decodeTypedPointer(*s, *i, etp, vp, sb, f)
/* return the stack back */
*i = nb
freeStack(sb)
/* avoid GC ahead */
runtime.KeepAlive(vv)
return err
}
// Pretouch compiles vt ahead-of-time to avoid JIT compilation on-the-fly, in
// order to reduce the first-hit latency.
//
// Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is
// a compile option to set the depth of recursive compile for the nested struct type.
func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
cfg := option.DefaultCompileOptions()
for _, opt := range opts {
opt(&cfg)
}
return pretouchRec(map[reflect.Type]bool{vt:true}, cfg)
}
func pretouchType(_vt reflect.Type, opts option.CompileOptions) (map[reflect.Type]bool, error) {
/* compile function */
compiler := newCompiler().apply(opts)
decoder := func(vt *rt.GoType, _ ...interface{}) (interface{}, error) {
if pp, err := compiler.compile(_vt); err != nil {
return nil, err
} else {
as := newAssembler(pp)
as.name = _vt.String()
return as.Load(), nil
}
}
/* find or compile */
vt := rt.UnpackType(_vt)
if val := programCache.Get(vt); val != nil {
return nil, nil
} else if _, err := programCache.Compute(vt, decoder); err == nil {
return compiler.rec, nil
} else {
return nil, err
}
}
func pretouchRec(vtm map[reflect.Type]bool, opts option.CompileOptions) error {
if opts.RecursiveDepth < 0 || len(vtm) == 0 {
return nil
}
next := make(map[reflect.Type]bool)
for vt := range(vtm) {
sub, err := pretouchType(vt, opts)
if err != nil {
return err
}
for svt := range(sub) {
next[svt] = true
}
}
opts.RecursiveDepth -= 1
return pretouchRec(next, opts)
}

View file

@ -1,4 +1,4 @@
// +build go1.17,!go1.23
// +build go1.17,!go1.24
/*
* Copyright 2021 ByteDance Inc.
@ -16,7 +16,7 @@
* limitations under the License.
*/
package decoder
package jitdec
import (
`encoding/json`

View file

@ -1,4 +1,4 @@
// +build go1.17,!go1.23
// +build go1.17,!go1.24
//
// Copyright 2021 ByteDance Inc.

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package decoder
package jitdec
import (
`sync`
@ -36,6 +36,7 @@ const (
_PtrBytes = _PTR_SIZE / 8
_FsmOffset = (_MaxStack + 1) * _PtrBytes
_DbufOffset = _FsmOffset + int64(unsafe.Sizeof(types.StateMachine{})) + types.MAX_RECURSE * _PtrBytes
_EpOffset = _DbufOffset + _MaxDigitNums
_StackSize = unsafe.Sizeof(_Stack{})
)
@ -53,6 +54,7 @@ type _Stack struct {
mm types.StateMachine
vp [types.MAX_RECURSE]unsafe.Pointer
dp [_MaxDigitNums]byte
ep unsafe.Pointer
}
type _Decoder func(

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package decoder
package jitdec
import (
`encoding`
@ -39,6 +39,20 @@ func decodeJsonUnmarshaler(vv interface{}, s string) error {
return vv.(json.Unmarshaler).UnmarshalJSON(rt.Str2Mem(s))
}
// used to distinguish between MismatchQuoted and other MismatchedTyped errors, see issue #670 and #716
type MismatchQuotedError struct {}
func (*MismatchQuotedError) Error() string {
return "mismatch quoted"
}
func decodeJsonUnmarshalerQuoted(vv interface{}, s string) error {
if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
return &MismatchQuotedError{}
}
return vv.(json.Unmarshaler).UnmarshalJSON(rt.Str2Mem(s[1:len(s)-1]))
}
func decodeTextUnmarshaler(vv interface{}, s string) error {
return vv.(encoding.TextUnmarshaler).UnmarshalText(rt.Str2Mem(s))
}

View file

@ -1,4 +1,4 @@
// +build go1.16,!go1.20
// +build go1.17,!go1.20
/*
* Copyright 2021 ByteDance Inc.
@ -16,7 +16,7 @@
* limitations under the License.
*/
package decoder
package jitdec
import (
`unsafe`
@ -72,11 +72,6 @@ func mallocgc(size uintptr, typ *rt.GoType, needzero bool) unsafe.Pointer
//goland:noinspection GoUnusedParameter
func makeslice(et *rt.GoType, len int, cap int) unsafe.Pointer
//go:noescape
//go:linkname growslice runtime.growslice
//goland:noinspection GoUnusedParameter
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
//go:linkname makemap_small runtime.makemap_small
func makemap_small() unsafe.Pointer

View file

@ -16,7 +16,7 @@
* limitations under the License.
*/
package decoder
package jitdec
import (
`unsafe`
@ -72,11 +72,6 @@ func mallocgc(size uintptr, typ *rt.GoType, needzero bool) unsafe.Pointer
//goland:noinspection GoUnusedParameter
func makeslice(et *rt.GoType, len int, cap int) unsafe.Pointer
//go:noescape
//go:linkname growslice reflect.growslice
//goland:noinspection GoUnusedParameter
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
//go:linkname makemap_small runtime.makemap_small
func makemap_small() unsafe.Pointer

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package decoder
package jitdec
import (
`encoding`

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package decoder
package jitdec
import (
`unsafe`

View file

@ -0,0 +1,174 @@
package optdec
import (
"fmt"
"reflect"
caching "github.com/bytedance/sonic/internal/optcaching"
"github.com/bytedance/sonic/internal/rt"
"github.com/bytedance/sonic/internal/resolver"
)
const (
_MAX_FIELDS = 50 // cutoff at 50 fields struct
)
func (c *compiler) compileIntStringOption(vt reflect.Type) decFunc {
switch vt.Size() {
case 4:
switch vt.Kind() {
case reflect.Uint:
fallthrough
case reflect.Uintptr:
return &u32StringDecoder{}
case reflect.Int:
return &i32StringDecoder{}
}
case 8:
switch vt.Kind() {
case reflect.Uint:
fallthrough
case reflect.Uintptr:
return &u64StringDecoder{}
case reflect.Int:
return &i64StringDecoder{}
}
default:
panic("not supported pointer size: " + fmt.Sprint(vt.Size()))
}
panic("unreachable")
}
func isInteger(vt reflect.Type) bool {
switch vt.Kind() {
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr, reflect.Int: return true
default: return false
}
}
func (c *compiler) assertStringOptTypes(vt reflect.Type) {
if c.depth > _CompileMaxDepth {
panic(*stackOverflow)
}
c.depth += 1
defer func () {
c.depth -= 1
}()
if isInteger(vt) {
return
}
switch vt.Kind() {
case reflect.String, reflect.Bool, reflect.Float32, reflect.Float64:
return
case reflect.Ptr: c.assertStringOptTypes(vt.Elem())
default:
panicForInvalidStrType(vt)
}
}
func (c *compiler) compileFieldStringOption(vt reflect.Type) decFunc {
c.assertStringOptTypes(vt)
unmDec := c.tryCompilePtrUnmarshaler(vt, true)
if unmDec != nil {
return unmDec
}
switch vt.Kind() {
case reflect.String:
if vt == jsonNumberType {
return &numberStringDecoder{}
}
return &strStringDecoder{}
case reflect.Bool:
return &boolStringDecoder{}
case reflect.Int8:
return &i8StringDecoder{}
case reflect.Int16:
return &i16StringDecoder{}
case reflect.Int32:
return &i32StringDecoder{}
case reflect.Int64:
return &i64StringDecoder{}
case reflect.Uint8:
return &u8StringDecoder{}
case reflect.Uint16:
return &u16StringDecoder{}
case reflect.Uint32:
return &u32StringDecoder{}
case reflect.Uint64:
return &u64StringDecoder{}
case reflect.Float32:
return &f32StringDecoder{}
case reflect.Float64:
return &f64StringDecoder{}
case reflect.Uint:
fallthrough
case reflect.Uintptr:
fallthrough
case reflect.Int:
return c.compileIntStringOption(vt)
case reflect.Ptr:
return &ptrStrDecoder{
typ: rt.UnpackType(vt.Elem()),
deref: c.compileFieldStringOption(vt.Elem()),
}
default:
panicForInvalidStrType(vt)
return nil
}
}
func (c *compiler) compileStruct(vt reflect.Type) decFunc {
c.enter(vt)
defer c.exit(vt)
if c.namedPtr {
c.namedPtr = false
return c.compileStructBody(vt)
}
if c.depth >= c.opts.MaxInlineDepth + 1 || (c.counts > 0 && vt.NumField() >= _MAX_FIELDS) {
return &recuriveDecoder{
typ: rt.UnpackType(vt),
}
} else {
return c.compileStructBody(vt)
}
}
func (c *compiler) compileStructBody(vt reflect.Type) decFunc {
fv := resolver.ResolveStruct(vt)
entries := make([]fieldEntry, 0, len(fv))
for _, f := range fv {
var dec decFunc
/* dealt with field tag options */
if f.Opts&resolver.F_stringize != 0 {
dec = c.compileFieldStringOption(f.Type)
} else {
dec = c.compile(f.Type)
}
/* deal with embedded pointer fields */
if f.Path[0].Kind == resolver.F_deref {
dec = &embeddedFieldPtrDecoder{
field: f,
fieldDec: dec,
fieldName: f.Name,
}
}
entries = append(entries, fieldEntry{
FieldMeta: f,
fieldDec: dec,
})
}
return &structDecoder{
fieldMap: caching.NewFieldLookup(fv),
fields: entries,
structName: vt.Name(),
typ: vt,
}
}

View file

@ -0,0 +1,449 @@
package optdec
import (
"encoding/json"
"fmt"
"reflect"
"github.com/bytedance/sonic/option"
"github.com/bytedance/sonic/internal/rt"
"github.com/bytedance/sonic/internal/caching"
)
var (
programCache = caching.CreateProgramCache()
)
func findOrCompile(vt *rt.GoType) (decFunc, error) {
makeDecoder := func(vt *rt.GoType, _ ...interface{}) (interface{}, error) {
ret, err := newCompiler().compileType(vt.Pack())
return ret, err
}
if val := programCache.Get(vt); val != nil {
return val.(decFunc), nil
} else if ret, err := programCache.Compute(vt, makeDecoder); err == nil {
return ret.(decFunc), nil
} else {
return nil, err
}
}
type compiler struct {
visited map[reflect.Type]bool
depth int
counts int
opts option.CompileOptions
namedPtr bool
}
func newCompiler() *compiler {
return &compiler{
visited: make(map[reflect.Type]bool),
opts: option.DefaultCompileOptions(),
}
}
func (self *compiler) apply(opts option.CompileOptions) *compiler {
self.opts = opts
return self
}
const _CompileMaxDepth = 4096
func (c *compiler) enter(vt reflect.Type) {
c.visited[vt] = true
c.depth += 1
if c.depth > _CompileMaxDepth {
panic(*stackOverflow)
}
}
func (c *compiler) exit(vt reflect.Type) {
c.visited[vt] = false
c.depth -= 1
}
func (c *compiler) compileInt(vt reflect.Type) decFunc {
switch vt.Size() {
case 4:
switch vt.Kind() {
case reflect.Uint:
fallthrough
case reflect.Uintptr:
return &u32Decoder{}
case reflect.Int:
return &i32Decoder{}
}
case 8:
switch vt.Kind() {
case reflect.Uint:
fallthrough
case reflect.Uintptr:
return &u64Decoder{}
case reflect.Int:
return &i64Decoder{}
}
default:
panic("not supported pointer size: " + fmt.Sprint(vt.Size()))
}
panic("unreachable")
}
func (c *compiler) rescue(ep *error) {
if val := recover(); val != nil {
if err, ok := val.(error); ok {
*ep = err
} else {
panic(val)
}
}
}
func (c *compiler) compileType(vt reflect.Type) (rt decFunc, err error) {
defer c.rescue(&err)
rt = c.compile(vt)
return rt, err
}
func (c *compiler) compile(vt reflect.Type) decFunc {
if c.visited[vt] {
return &recuriveDecoder{
typ: rt.UnpackType(vt),
}
}
dec := c.tryCompilePtrUnmarshaler(vt, false)
if dec != nil {
return dec
}
return c.compileBasic(vt)
}
func (c *compiler) compileBasic(vt reflect.Type) decFunc {
defer func() {
c.counts += 1
}()
switch vt.Kind() {
case reflect.Bool:
return &boolDecoder{}
case reflect.Int8:
return &i8Decoder{}
case reflect.Int16:
return &i16Decoder{}
case reflect.Int32:
return &i32Decoder{}
case reflect.Int64:
return &i64Decoder{}
case reflect.Uint8:
return &u8Decoder{}
case reflect.Uint16:
return &u16Decoder{}
case reflect.Uint32:
return &u32Decoder{}
case reflect.Uint64:
return &u64Decoder{}
case reflect.Float32:
return &f32Decoder{}
case reflect.Float64:
return &f64Decoder{}
case reflect.Uint:
fallthrough
case reflect.Uintptr:
fallthrough
case reflect.Int:
return c.compileInt(vt)
case reflect.String:
return c.compileString(vt)
case reflect.Array:
return c.compileArray(vt)
case reflect.Interface:
return c.compileInterface(vt)
case reflect.Map:
return c.compileMap(vt)
case reflect.Ptr:
return c.compilePtr(vt)
case reflect.Slice:
return c.compileSlice(vt)
case reflect.Struct:
return c.compileStruct(vt)
default:
panic(&json.UnmarshalTypeError{Type: vt})
}
}
func (c *compiler) compilePtr(vt reflect.Type) decFunc {
c.enter(vt)
defer c.exit(vt)
// specail logic for Named Ptr, issue 379
if reflect.PtrTo(vt.Elem()) != vt {
c.namedPtr = true
return &ptrDecoder{
typ: rt.UnpackType(vt.Elem()),
deref: c.compileBasic(vt.Elem()),
}
}
return &ptrDecoder{
typ: rt.UnpackType(vt.Elem()),
deref: c.compile(vt.Elem()),
}
}
func (c *compiler) compileArray(vt reflect.Type) decFunc {
c.enter(vt)
defer c.exit(vt)
return &arrayDecoder{
len: vt.Len(),
elemType: rt.UnpackType(vt.Elem()),
elemDec: c.compile(vt.Elem()),
typ: vt,
}
}
func (c *compiler) compileString(vt reflect.Type) decFunc {
if vt == jsonNumberType {
return &numberDecoder{}
}
return &stringDecoder{}
}
func (c *compiler) tryCompileSliceUnmarshaler(vt reflect.Type) decFunc {
pt := reflect.PtrTo(vt.Elem())
if pt.Implements(jsonUnmarshalerType) {
return &sliceDecoder{
elemType: rt.UnpackType(vt.Elem()),
elemDec: c.compile(vt.Elem()),
typ: vt,
}
}
if pt.Implements(encodingTextUnmarshalerType) {
return &sliceDecoder{
elemType: rt.UnpackType(vt.Elem()),
elemDec: c.compile(vt.Elem()),
typ: vt,
}
}
return nil
}
func (c *compiler) compileSlice(vt reflect.Type) decFunc {
c.enter(vt)
defer c.exit(vt)
// Some common slice, use a decoder, to avoid function calls
et := rt.UnpackType(vt.Elem())
/* first checking `[]byte` */
if et.Kind() == reflect.Uint8 /* []byte */ {
return c.compileSliceBytes(vt)
}
dec := c.tryCompileSliceUnmarshaler(vt)
if dec != nil {
return dec
}
if vt == reflect.TypeOf([]interface{}{}) {
return &sliceEfaceDecoder{}
}
if et.IsInt32() {
return &sliceI32Decoder{}
}
if et.IsInt64() {
return &sliceI64Decoder{}
}
if et.IsUint32() {
return &sliceU32Decoder{}
}
if et.IsUint64() {
return &sliceU64Decoder{}
}
if et.Kind() == reflect.String {
return &sliceStringDecoder{}
}
return &sliceDecoder{
elemType: rt.UnpackType(vt.Elem()),
elemDec: c.compile(vt.Elem()),
typ: vt,
}
}
func (c *compiler) compileSliceBytes(vt reflect.Type) decFunc {
ep := reflect.PtrTo(vt.Elem())
if ep.Implements(jsonUnmarshalerType) {
return &sliceBytesUnmarshalerDecoder{
elemType: rt.UnpackType(vt.Elem()),
elemDec: c.compile(vt.Elem()),
typ: vt,
}
}
if ep.Implements(encodingTextUnmarshalerType) {
return &sliceBytesUnmarshalerDecoder{
elemType: rt.UnpackType(vt.Elem()),
elemDec: c.compile(vt.Elem()),
typ: vt,
}
}
return &sliceBytesDecoder{}
}
func (c *compiler) compileInterface(vt reflect.Type) decFunc {
c.enter(vt)
defer c.exit(vt)
if vt.NumMethod() == 0 {
return &efaceDecoder{}
}
if vt.Implements(jsonUnmarshalerType) {
return &unmarshalJSONDecoder{
typ: rt.UnpackType(vt),
}
}
if vt.Implements(encodingTextUnmarshalerType) {
return &unmarshalTextDecoder{
typ: rt.UnpackType(vt),
}
}
return &ifaceDecoder{
typ: rt.UnpackType(vt),
}
}
func (c *compiler) compileMap(vt reflect.Type) decFunc {
c.enter(vt)
defer c.exit(vt)
// check the key unmarshaler at first
decKey := tryCompileKeyUnmarshaler(vt)
if decKey != nil {
return &mapDecoder{
mapType: rt.MapType(rt.UnpackType(vt)),
keyDec: decKey,
elemDec: c.compile(vt.Elem()),
}
}
// Most common map, use a decoder, to avoid function calls
if vt == reflect.TypeOf(map[string]interface{}{}) {
return &mapEfaceDecoder{}
} else if vt == reflect.TypeOf(map[string]string{}) {
return &mapStringDecoder{}
}
// Some common integer map later
mt := rt.MapType(rt.UnpackType(vt))
if mt.Key.Kind() == reflect.String {
return &mapStrKeyDecoder{
mapType: mt,
assign: rt.GetMapStrAssign(vt),
elemDec: c.compile(vt.Elem()),
}
}
if mt.Key.IsInt64() {
return &mapI64KeyDecoder{
mapType: mt,
elemDec: c.compile(vt.Elem()),
assign: rt.GetMap64Assign(vt),
}
}
if mt.Key.IsInt32() {
return &mapI32KeyDecoder{
mapType: mt,
elemDec: c.compile(vt.Elem()),
assign: rt.GetMap32Assign(vt),
}
}
if mt.Key.IsUint64() {
return &mapU64KeyDecoder{
mapType: mt,
elemDec: c.compile(vt.Elem()),
assign: rt.GetMap64Assign(vt),
}
}
if mt.Key.IsUint32() {
return &mapU32KeyDecoder{
mapType: mt,
elemDec: c.compile(vt.Elem()),
assign: rt.GetMap32Assign(vt),
}
}
// Generic map
return &mapDecoder{
mapType: mt,
keyDec: c.compileMapKey(vt),
elemDec: c.compile(vt.Elem()),
}
}
func tryCompileKeyUnmarshaler(vt reflect.Type) decKey {
pt := reflect.PtrTo(vt.Key())
/* check for `encoding.TextUnmarshaler` with pointer receiver */
if pt.Implements(encodingTextUnmarshalerType) {
return decodeKeyTextUnmarshaler
}
/* not support map key with `json.Unmarshaler` */
return nil
}
func (c *compiler) compileMapKey(vt reflect.Type) decKey {
switch vt.Key().Kind() {
case reflect.Int8:
return decodeKeyI8
case reflect.Int16:
return decodeKeyI16
case reflect.Uint8:
return decodeKeyU8
case reflect.Uint16:
return decodeKeyU16
default:
panic(&json.UnmarshalTypeError{Type: vt})
}
}
// maybe vt is a named type, and not a pointer receiver, see issue 379
func (c *compiler) tryCompilePtrUnmarshaler(vt reflect.Type, strOpt bool) decFunc {
pt := reflect.PtrTo(vt)
/* check for `json.Unmarshaler` with pointer receiver */
if pt.Implements(jsonUnmarshalerType) {
return &unmarshalJSONDecoder{
typ: rt.UnpackType(pt),
strOpt: strOpt,
}
}
/* check for `encoding.TextMarshaler` with pointer receiver */
if pt.Implements(encodingTextUnmarshalerType) {
/* TextUnmarshal not support ,strig tag */
if strOpt {
panicForInvalidStrType(vt)
}
return &unmarshalTextDecoder{
typ: rt.UnpackType(pt),
}
}
return nil
}
func panicForInvalidStrType(vt reflect.Type) {
panic(error_type(rt.UnpackType(vt)))
}

View file

@ -0,0 +1,60 @@
package optdec
import "math"
/*
Copied from sonic-rs
// JSON Value Type
const NULL: u64 = 0;
const BOOL: u64 = 2;
const FALSE: u64 = BOOL;
const TRUE: u64 = (1 << 3) | BOOL;
const NUMBER: u64 = 3;
const UINT: u64 = NUMBER;
const SINT: u64 = (1 << 3) | NUMBER;
const REAL: u64 = (2 << 3) | NUMBER;
const RAWNUMBER: u64 = (3 << 3) | NUMBER;
const STRING: u64 = 4;
const STRING_COMMON: u64 = STRING;
const STRING_HASESCAPED: u64 = (1 << 3) | STRING;
const OBJECT: u64 = 6;
const ARRAY: u64 = 7;
/// JSON Type Mask
const POS_MASK: u64 = (!0) << 32;
const POS_BITS: u64 = 32;
const TYPE_MASK: u64 = 0xFF;
const TYPE_BITS: u64 = 8;
*/
const (
// BasicType: 3 bits
KNull = 0 // xxxxx000
KBool = 2 // xxxxx010
KNumber = 3 // xxxxx011
KString = 4 // xxxxx100
KRaw = 5 // xxxxx101
KObject = 6 // xxxxx110
KArray = 7 // xxxxx111
// SubType: 2 bits
KFalse = (0 << 3) | KBool // xxx00_010, 2
KTrue = (1 << 3) | KBool // xxx01_010, 10
KUint = (0 << 3) | KNumber // xxx00_011, 3
KSint = (1 << 3) | KNumber // xxx01_011, 11
KReal = (2 << 3) | KNumber // xxx10_011, 19
KRawNumber = (3 << 3) | KNumber // xxx11_011, 27
KStringCommon = KString // xxx00_100, 4
KStringEscaped = (1 << 3) | KString // xxx01_100, 12
)
const (
PosMask = math.MaxUint64 << 32
PosBits = 32
TypeMask = 0xFF
TypeBits = 8
ConLenMask = uint64(math.MaxUint32)
ConLenBits = 32
)

View file

@ -0,0 +1,3 @@
package optdec
type context = Context

View file

@ -0,0 +1,160 @@
package optdec
import (
"reflect"
"unsafe"
"encoding/json"
"github.com/bytedance/sonic/internal/rt"
"github.com/bytedance/sonic/option"
"github.com/bytedance/sonic/internal/decoder/errors"
"github.com/bytedance/sonic/internal/decoder/consts"
)
type (
MismatchTypeError = errors.MismatchTypeError
SyntaxError = errors.SyntaxError
)
const (
_F_allow_control = consts.F_allow_control
_F_copy_string = consts.F_copy_string
_F_disable_unknown = consts.F_disable_unknown
_F_disable_urc = consts.F_disable_urc
_F_use_int64 = consts.F_use_int64
_F_use_number = consts.F_use_number
_F_validate_string = consts.F_validate_string
)
type Options = consts.Options
const (
OptionUseInt64 = consts.OptionUseInt64
OptionUseNumber = consts.OptionUseNumber
OptionUseUnicodeErrors = consts.OptionUseUnicodeErrors
OptionDisableUnknown = consts.OptionDisableUnknown
OptionCopyString = consts.OptionCopyString
OptionValidateString = consts.OptionValidateString
)
func Decode(s *string, i *int, f uint64, val interface{}) error {
vv := rt.UnpackEface(val)
vp := vv.Value
/* check for nil type */
if vv.Type == nil {
return &json.InvalidUnmarshalError{}
}
/* must be a non-nil pointer */
if vp == nil || vv.Type.Kind() != reflect.Ptr {
return &json.InvalidUnmarshalError{Type: vv.Type.Pack()}
}
etp := rt.PtrElem(vv.Type)
/* check the defined pointer type for issue 379 */
if vv.Type.IsNamed() {
newp := vp
etp = vv.Type
vp = unsafe.Pointer(&newp)
}
dec, err := findOrCompile(etp)
if err != nil {
return err
}
/* parse into document */
ctx, err := NewContext(*s, *i, uint64(f), etp)
defer ctx.Delete()
if ctx.Parser.Utf8Inv {
*s = ctx.Parser.Json
}
if err != nil {
goto fix_error;
}
err = dec.FromDom(vp, ctx.Root(), &ctx)
fix_error:
err = fix_error(*s, *i, err)
// update position at last
*i += ctx.Parser.Pos()
return err
}
func fix_error(json string, pos int, err error) error {
if e, ok := err.(SyntaxError); ok {
return SyntaxError{
Pos: int(e.Pos) + pos,
Src: json,
Msg: e.Msg,
}
}
if e, ok := err.(MismatchTypeError); ok {
return &MismatchTypeError {
Pos: int(e.Pos) + pos,
Src: json,
Type: e.Type,
}
}
return err
}
// Pretouch compiles vt ahead-of-time to avoid JIT compilation on-the-fly, in
// order to reduce the first-hit latency.
//
// Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is
// a compile option to set the depth of recursive compile for the nested struct type.
func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
cfg := option.DefaultCompileOptions()
for _, opt := range opts {
opt(&cfg)
}
return pretouchRec(map[reflect.Type]bool{vt:true}, cfg)
}
func pretouchType(_vt reflect.Type, opts option.CompileOptions) (map[reflect.Type]bool, error) {
/* compile function */
compiler := newCompiler().apply(opts)
decoder := func(vt *rt.GoType, _ ...interface{}) (interface{}, error) {
if f, err := compiler.compileType(_vt); err != nil {
return nil, err
} else {
return f, nil
}
}
/* find or compile */
vt := rt.UnpackType(_vt)
if val := programCache.Get(vt); val != nil {
return nil, nil
} else if _, err := programCache.Compute(vt, decoder); err == nil {
return compiler.visited, nil
} else {
return nil, err
}
}
func pretouchRec(vtm map[reflect.Type]bool, opts option.CompileOptions) error {
if opts.RecursiveDepth < 0 || len(vtm) == 0 {
return nil
}
next := make(map[reflect.Type]bool)
for vt := range(vtm) {
sub, err := pretouchType(vt, opts)
if err != nil {
return err
}
for svt := range(sub) {
next[svt] = true
}
}
opts.RecursiveDepth -= 1
return pretouchRec(next, opts)
}

View file

@ -0,0 +1,73 @@
/*
* 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 optdec
import (
"encoding/json"
"errors"
"reflect"
"strconv"
"github.com/bytedance/sonic/internal/rt"
)
/** JIT Error Helpers **/
var stackOverflow = &json.UnsupportedValueError{
Str: "Value nesting too deep",
Value: reflect.ValueOf("..."),
}
func error_type(vt *rt.GoType) error {
return &json.UnmarshalTypeError{Type: vt.Pack()}
}
func error_mismatch(node Node, ctx *context, typ reflect.Type) error {
return MismatchTypeError{
Pos: node.Position(),
Src: ctx.Parser.Json,
Type: typ,
}
}
func newUnmatched(pos int, vt *rt.GoType) error {
return MismatchTypeError{
Pos: pos,
Src: "",
Type: vt.Pack(),
}
}
func error_field(name string) error {
return errors.New("json: unknown field " + strconv.Quote(name))
}
func error_value(value string, vtype reflect.Type) error {
return &json.UnmarshalTypeError{
Type: vtype,
Value: value,
}
}
func error_syntax(pos int, src string, msg string) error {
return SyntaxError{
Pos: pos,
Src: src,
Msg: msg,
}
}

View file

@ -0,0 +1,281 @@
package optdec
import (
"encoding/json"
"math"
"unsafe"
"github.com/bytedance/sonic/internal/rt"
"github.com/bytedance/sonic/internal/resolver"
)
type decFunc interface {
FromDom(vp unsafe.Pointer, node Node, ctx *context) error
}
type ptrDecoder struct {
typ *rt.GoType
deref decFunc
}
// Pointer Value is allocated in the Caller
func (d *ptrDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*unsafe.Pointer)(vp) = nil
return nil
}
if *(*unsafe.Pointer)(vp) == nil {
*(*unsafe.Pointer)(vp) = rt.Mallocgc(d.typ.Size, d.typ, true)
}
return d.deref.FromDom(*(*unsafe.Pointer)(vp), node, ctx)
}
type embeddedFieldPtrDecoder struct {
field resolver.FieldMeta
fieldDec decFunc
fieldName string
}
// Pointer Value is allocated in the Caller
func (d *embeddedFieldPtrDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
// seek into the pointer
vp = unsafe.Pointer(uintptr(vp) - uintptr(d.field.Path[0].Size))
for _, f := range d.field.Path {
deref := rt.UnpackType(f.Type)
vp = unsafe.Pointer(uintptr(vp) + f.Size)
if f.Kind == resolver.F_deref {
if *(*unsafe.Pointer)(vp) == nil {
*(*unsafe.Pointer)(vp) = rt.Mallocgc(deref.Size, deref, true)
}
vp = *(*unsafe.Pointer)(vp)
}
}
return d.fieldDec.FromDom(vp, node, ctx)
}
type i8Decoder struct{}
func (d *i8Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
ret, ok := node.AsI64(ctx)
if !ok || ret > math.MaxInt8 || ret < math.MinInt8 {
return error_mismatch(node, ctx, int8Type)
}
*(*int8)(vp) = int8(ret)
return nil
}
type i16Decoder struct{}
func (d *i16Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
ret, ok := node.AsI64(ctx)
if !ok || ret > math.MaxInt16 || ret < math.MinInt16 {
return error_mismatch(node, ctx, int16Type)
}
*(*int16)(vp) = int16(ret)
return nil
}
type i32Decoder struct{}
func (d *i32Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
ret, ok := node.AsI64(ctx)
if !ok || ret > math.MaxInt32 || ret < math.MinInt32 {
return error_mismatch(node, ctx, int32Type)
}
*(*int32)(vp) = int32(ret)
return nil
}
type i64Decoder struct{}
func (d *i64Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
ret, ok := node.AsI64(ctx)
if !ok {
return error_mismatch(node, ctx, int64Type)
}
*(*int64)(vp) = int64(ret)
return nil
}
type u8Decoder struct{}
func (d *u8Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
ret, ok := node.AsU64(ctx)
if !ok || ret > math.MaxUint8 {
err := error_mismatch(node, ctx, uint8Type)
return err
}
*(*uint8)(vp) = uint8(ret)
return nil
}
type u16Decoder struct{}
func (d *u16Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
ret, ok := node.AsU64(ctx)
if !ok || ret > math.MaxUint16 {
return error_mismatch(node, ctx, uint16Type)
}
*(*uint16)(vp) = uint16(ret)
return nil
}
type u32Decoder struct{}
func (d *u32Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
ret, ok := node.AsU64(ctx)
if !ok || ret > math.MaxUint32 {
return error_mismatch(node, ctx, uint32Type)
}
*(*uint32)(vp) = uint32(ret)
return nil
}
type u64Decoder struct{}
func (d *u64Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
ret, ok := node.AsU64(ctx)
if !ok {
return error_mismatch(node, ctx, uint64Type)
}
*(*uint64)(vp) = uint64(ret)
return nil
}
type f32Decoder struct{}
func (d *f32Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
ret, ok := node.AsF64(ctx)
if !ok || ret > math.MaxFloat32 || ret < -math.MaxFloat32 {
return error_mismatch(node, ctx, float32Type)
}
*(*float32)(vp) = float32(ret)
return nil
}
type f64Decoder struct{}
func (d *f64Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
ret, ok := node.AsF64(ctx)
if !ok {
return error_mismatch(node, ctx, float64Type)
}
*(*float64)(vp) = float64(ret)
return nil
}
type boolDecoder struct {
}
func (d *boolDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
ret, ok := node.AsBool()
if !ok {
return error_mismatch(node, ctx, boolType)
}
*(*bool)(vp) = bool(ret)
return nil
}
type stringDecoder struct {
}
func (d *stringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
ret, ok := node.AsStr(ctx)
if !ok {
return error_mismatch(node, ctx, stringType)
}
*(*string)(vp) = ret
return nil
}
type numberDecoder struct {
}
func (d *numberDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
num, ok := node.AsNumber(ctx)
if !ok {
return error_mismatch(node, ctx, jsonNumberType)
}
*(*json.Number)(vp) = num
return nil
}
type recuriveDecoder struct {
typ *rt.GoType
}
func (d *recuriveDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
dec, err := findOrCompile(d.typ)
if err != nil {
return err
}
return dec.FromDom(vp, node, ctx)
}

View file

@ -0,0 +1,110 @@
package optdec
import (
"encoding/json"
"strconv"
"github.com/bytedance/sonic/internal/native"
"github.com/bytedance/sonic/internal/utils"
"github.com/bytedance/sonic/internal/native/types"
)
func SkipNumberFast(json string, start int) (int, bool) {
// find the number ending, we pasred in native, it alway valid
pos := start
for pos < len(json) && json[pos] != ']' && json[pos] != '}' && json[pos] != ',' {
if json[pos] >= '0' && json[pos] <= '9' || json[pos] == '.' || json[pos] == '-' || json[pos] == '+' || json[pos] == 'e' || json[pos] == 'E' {
pos += 1
} else {
break
}
}
// if not found number, return false
if pos == start {
return pos, false
}
return pos, true
}
func isSpace(c byte) bool {
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
}
// pos is the start index of the raw
func ValidNumberFast(raw string) bool {
ret := utils.SkipNumber(raw, 0)
if ret < 0 {
return false
}
// check trainling chars
for ret < len(raw) {
return false
}
return true
}
func SkipOneFast2(json string, pos *int) (int, error) {
// find the number ending, we pasred in sonic-cpp, it alway valid
start := native.SkipOneFast(&json, pos)
if start < 0 {
return -1, error_syntax(*pos, json, types.ParsingError(-start).Error())
}
return start, nil
}
func SkipOneFast(json string, pos int) (string, error) {
// find the number ending, we pasred in sonic-cpp, it alway valid
start := native.SkipOneFast(&json, &pos)
if start < 0 {
// TODO: details error code
return "", error_syntax(pos, json, types.ParsingError(-start).Error())
}
return json[start:pos], nil
}
func ParseI64(raw string) (int64, error) {
i64, err := strconv.ParseInt(raw, 10, 64)
if err != nil {
return 0, err
}
return i64, nil
}
func ParseBool(raw string) (bool, error) {
var b bool
err := json.Unmarshal([]byte(raw), &b)
if err != nil {
return false, err
}
return b, nil
}
func ParseU64(raw string) (uint64, error) {
u64, err := strconv.ParseUint(raw, 10, 64)
if err != nil {
return 0, err
}
return u64, nil
}
func ParseF64(raw string) (float64, error) {
f64, err := strconv.ParseFloat(raw, 64)
if err != nil {
return 0, err
}
return f64, nil
}
func Unquote(raw string) (string, error) {
var u string
err := json.Unmarshal([]byte(raw), &u)
if err != nil {
return "", err
}
return u, nil
}

View file

@ -0,0 +1,169 @@
package optdec
import (
"encoding"
"encoding/json"
"unsafe"
"reflect"
"github.com/bytedance/sonic/internal/rt"
)
type efaceDecoder struct {
}
func (d *efaceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*interface{})(vp) = interface{}(nil)
return nil
}
eface := *(*rt.GoEface)(vp)
// not pointer type, or nil pointer, or *interface{}
if eface.Value == nil || eface.Type.Kind() != reflect.Ptr || rt.PtrElem(eface.Type) == anyType {
ret, err := node.AsEface(ctx)
if err != nil {
return err
}
*(*interface{})(vp) = ret
return nil
}
etp := rt.PtrElem(eface.Type)
vp = eface.Value
/* check the defined pointer type for issue 379 */
if eface.Type.IsNamed() {
newp := vp
etp = eface.Type
vp = unsafe.Pointer(&newp)
}
dec, err := findOrCompile(etp)
if err != nil {
return err
}
return dec.FromDom(vp, node, ctx)
}
type ifaceDecoder struct {
typ *rt.GoType
}
func (d *ifaceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*unsafe.Pointer)(vp) = nil
return nil
}
iface := *(*rt.GoIface)(vp)
if iface.Itab == nil {
return error_type(d.typ)
}
vt := iface.Itab.Vt
// not pointer type, or nil pointer, or *interface{}
if vp == nil || vt.Kind() != reflect.Ptr || rt.PtrElem(vt) == anyType {
ret, err := node.AsEface(ctx)
if err != nil {
return err
}
*(*interface{})(vp) = ret
return nil
}
etp := rt.PtrElem(vt)
vp = iface.Value
/* check the defined pointer type for issue 379 */
if vt.IsNamed() {
newp := vp
etp = vt
vp = unsafe.Pointer(&newp)
}
dec, err := findOrCompile(etp)
if err != nil {
return err
}
return dec.FromDom(vp, node, ctx)
}
type unmarshalTextDecoder struct {
typ *rt.GoType
}
func (d *unmarshalTextDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*unsafe.Pointer)(vp) = nil
return nil
}
txt, ok := node.AsStringText(ctx)
if !ok {
return error_mismatch(node, ctx, d.typ.Pack())
}
v := *(*interface{})(unsafe.Pointer(&rt.GoEface{
Type: d.typ,
Value: vp,
}))
// fast path
if u, ok := v.(encoding.TextUnmarshaler); ok {
return u.UnmarshalText(txt)
}
// slow path
rv := reflect.ValueOf(v)
if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
return u.UnmarshalText(txt)
}
return error_type(d.typ)
}
type unmarshalJSONDecoder struct {
typ *rt.GoType
strOpt bool
}
func (d *unmarshalJSONDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
v := *(*interface{})(unsafe.Pointer(&rt.GoEface{
Type: d.typ,
Value: vp,
}))
var input []byte
if d.strOpt && node.IsNull() {
input = []byte("null")
} else if d.strOpt {
s, ok := node.AsStringText(ctx)
if !ok {
return error_mismatch(node, ctx, d.typ.Pack())
}
input = s
} else {
input = []byte(node.AsRaw(ctx))
}
// fast path
if u, ok := v.(json.Unmarshaler); ok {
return u.UnmarshalJSON((input))
}
// slow path
rv := reflect.ValueOf(v)
if u, ok := rv.Interface().(json.Unmarshaler); ok {
return u.UnmarshalJSON(input)
}
return error_type(d.typ)
}

View file

@ -0,0 +1,430 @@
package optdec
import (
"encoding"
"encoding/json"
"math"
"reflect"
"unsafe"
"github.com/bytedance/sonic/internal/rt"
)
/** Decoder for most common map types: map[string]interface{}, map[string]string **/
type mapEfaceDecoder struct {
}
func (d *mapEfaceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*map[string]interface{})(vp) = nil
return nil
}
return node.AsMapEface(ctx, vp)
}
type mapStringDecoder struct {
}
func (d *mapStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*map[string]string)(vp) = nil
return nil
}
return node.AsMapString(ctx, vp)
}
/** Decoder for map with string key **/
type mapStrKeyDecoder struct {
mapType *rt.GoMapType
elemDec decFunc
assign rt.MapStrAssign
typ reflect.Type
}
func (d *mapStrKeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*unsafe.Pointer)(vp) = nil
return nil
}
obj, ok := node.AsObj()
if !ok {
return error_mismatch(node, ctx, d.mapType.Pack())
}
// allocate map
m := *(*unsafe.Pointer)(vp)
if m == nil {
m = rt.Makemap(&d.mapType.GoType, obj.Len())
}
var gerr error
next := obj.Children()
for i := 0; i < obj.Len(); i++ {
keyn := NewNode(next)
key, _ := keyn.AsStr(ctx)
valn := NewNode(PtrOffset(next, 1))
valp := d.assign(d.mapType, m, key)
err := d.elemDec.FromDom(valp, valn, ctx)
if gerr == nil && err != nil {
gerr = err
}
next = valn.Next()
}
*(*unsafe.Pointer)(vp) = m
return gerr
}
/** Decoder for map with int32 or int64 key **/
type mapI32KeyDecoder struct {
mapType *rt.GoMapType
elemDec decFunc
assign rt.Map32Assign
}
func (d *mapI32KeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*unsafe.Pointer)(vp) = nil
return nil
}
obj, ok := node.AsObj()
if !ok {
return error_mismatch(node, ctx, d.mapType.Pack())
}
// allocate map
m := *(*unsafe.Pointer)(vp)
if m == nil {
m = rt.Makemap(&d.mapType.GoType, obj.Len())
}
next := obj.Children()
var gerr error
for i := 0; i < obj.Len(); i++ {
keyn := NewNode(next)
k, ok := keyn.ParseI64(ctx)
if !ok || k > math.MaxInt32 || k < math.MinInt32 {
if gerr == nil {
gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
}
valn := NewNode(PtrOffset(next, 1))
next = valn.Next()
continue
}
key := int32(k)
ku32 := *(*uint32)(unsafe.Pointer(&key))
valn := NewNode(PtrOffset(next, 1))
valp := d.assign(d.mapType, m, ku32)
err := d.elemDec.FromDom(valp, valn, ctx)
if gerr == nil && err != nil {
gerr = err
}
next = valn.Next()
}
*(*unsafe.Pointer)(vp) = m
return gerr
}
type mapI64KeyDecoder struct {
mapType *rt.GoMapType
elemDec decFunc
assign rt.Map64Assign
}
func (d *mapI64KeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*unsafe.Pointer)(vp) = nil
return nil
}
obj, ok := node.AsObj()
if !ok {
return error_mismatch(node, ctx, d.mapType.Pack())
}
// allocate map
m := *(*unsafe.Pointer)(vp)
if m == nil {
m = rt.Makemap(&d.mapType.GoType, obj.Len())
}
var gerr error
next := obj.Children()
for i := 0; i < obj.Len(); i++ {
keyn := NewNode(next)
key, ok := keyn.ParseI64(ctx)
if !ok {
if gerr == nil {
gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
}
valn := NewNode(PtrOffset(next, 1))
next = valn.Next()
continue
}
ku64 := *(*uint64)(unsafe.Pointer(&key))
valn := NewNode(PtrOffset(next, 1))
valp := d.assign(d.mapType, m, ku64)
err := d.elemDec.FromDom(valp, valn, ctx)
if gerr == nil && err != nil {
gerr = err
}
next = valn.Next()
}
*(*unsafe.Pointer)(vp) = m
return gerr
}
/** Decoder for map with unt32 or uint64 key **/
type mapU32KeyDecoder struct {
mapType *rt.GoMapType
elemDec decFunc
assign rt.Map32Assign
}
func (d *mapU32KeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*unsafe.Pointer)(vp) = nil
return nil
}
obj, ok := node.AsObj()
if !ok {
return error_mismatch(node, ctx, d.mapType.Pack())
}
// allocate map
m := *(*unsafe.Pointer)(vp)
if m == nil {
m = rt.Makemap(&d.mapType.GoType, obj.Len())
}
var gerr error
next := obj.Children()
for i := 0; i < obj.Len(); i++ {
keyn := NewNode(next)
k, ok := keyn.ParseU64(ctx)
if !ok || k > math.MaxUint32 {
if gerr == nil {
gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
}
valn := NewNode(PtrOffset(next, 1))
next = valn.Next()
continue
}
key := uint32(k)
valn := NewNode(PtrOffset(next, 1))
valp := d.assign(d.mapType, m, key)
err := d.elemDec.FromDom(valp, valn, ctx)
if gerr == nil && err != nil {
gerr = err
}
next = valn.Next()
}
*(*unsafe.Pointer)(vp) = m
return gerr
}
type mapU64KeyDecoder struct {
mapType *rt.GoMapType
elemDec decFunc
assign rt.Map64Assign
}
func (d *mapU64KeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*unsafe.Pointer)(vp) = nil
return nil
}
obj, ok := node.AsObj()
if !ok {
return error_mismatch(node, ctx, d.mapType.Pack())
}
// allocate map
m := *(*unsafe.Pointer)(vp)
if m == nil {
m = rt.Makemap(&d.mapType.GoType, obj.Len())
}
var gerr error
next := obj.Children()
for i := 0; i < obj.Len(); i++ {
keyn := NewNode(next)
key, ok := keyn.ParseU64(ctx)
if !ok {
if gerr == nil {
gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
}
valn := NewNode(PtrOffset(next, 1))
next = valn.Next()
continue
}
valn := NewNode(PtrOffset(next, 1))
valp := d.assign(d.mapType, m, key)
err := d.elemDec.FromDom(valp, valn, ctx)
if gerr == nil && err != nil {
gerr = err
}
next = valn.Next()
}
*(*unsafe.Pointer)(vp) = m
return gerr
}
/** Decoder for generic cases */
type decKey func(dec *mapDecoder, raw string, ctx *context) (interface{}, error)
func decodeKeyU8(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
key, err := Unquote(raw)
if err != nil {
return nil, err
}
ret, err := ParseU64(key)
if err != nil {
return nil, err
}
if ret > math.MaxUint8 {
return nil, error_value(key, dec.mapType.Key.Pack())
}
return uint8(ret), nil
}
func decodeKeyU16(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
key, err := Unquote(raw)
if err != nil {
return nil, err
}
ret, err := ParseU64(key)
if err != nil {
return nil, err
}
if ret > math.MaxUint16 {
return nil, error_value(key, dec.mapType.Key.Pack())
}
return uint16(ret), nil
}
func decodeKeyI8(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
key, err := Unquote(raw)
if err != nil {
return nil, err
}
ret, err := ParseI64(key)
if err != nil {
return nil, err
}
if ret > math.MaxInt8 || ret < math.MinInt8 {
return nil, error_value(key, dec.mapType.Key.Pack())
}
return int8(ret), nil
}
func decodeKeyI16(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
key, err := Unquote(raw)
if err != nil {
return nil, err
}
ret, err := ParseI64(key)
if err != nil {
return nil, err
}
if ret > math.MaxInt16 || ret < math.MinInt16 {
return nil, error_value(key, dec.mapType.Key.Pack())
}
return int16(ret), nil
}
func decodeKeyJSONUnmarshaler(dec *mapDecoder, raw string, _ *context) (interface{}, error) {
ret := reflect.New(dec.mapType.Key.Pack()).Interface()
err := ret.(json.Unmarshaler).UnmarshalJSON([]byte(raw))
if err != nil {
return nil, err
}
return ret, nil
}
func decodeKeyTextUnmarshaler(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
key, err := Unquote(raw)
if err != nil {
return nil, err
}
ret := reflect.New(dec.mapType.Key.Pack()).Interface()
err = ret.(encoding.TextUnmarshaler).UnmarshalText([]byte(key))
if err != nil {
return nil, err
}
return ret, nil
}
type mapDecoder struct {
mapType *rt.GoMapType
keyDec decKey
elemDec decFunc
}
func (d *mapDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*unsafe.Pointer)(vp) = nil
return nil
}
obj, ok := node.AsObj()
if !ok {
return error_mismatch(node, ctx, d.mapType.Pack())
}
// allocate map
m := *(*unsafe.Pointer)(vp)
if m == nil {
m = rt.Makemap(&d.mapType.GoType, obj.Len())
}
next := obj.Children()
var gerr error
for i := 0; i < obj.Len(); i++ {
keyn := NewNode(next)
raw := keyn.AsRaw(ctx)
key, err := d.keyDec(d, raw, ctx)
if err != nil {
if gerr == nil {
gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
}
valn := NewNode(PtrOffset(next, 1))
next = valn.Next()
continue
}
valn := NewNode(PtrOffset(next, 1))
keyp := rt.UnpackEface(key).Value
valp := rt.Mapassign(d.mapType, m, keyp)
err = d.elemDec.FromDom(valp, valn, ctx)
if gerr == nil && err != nil {
gerr = err
}
next = valn.Next()
}
*(*unsafe.Pointer)(vp) = m
return gerr
}

View file

@ -0,0 +1,269 @@
package optdec
import (
"fmt"
"reflect"
"unsafe"
"sync"
"github.com/bytedance/sonic/internal/native"
"github.com/bytedance/sonic/internal/native/types"
"github.com/bytedance/sonic/internal/rt"
"github.com/bytedance/sonic/utf8"
)
type ErrorCode int
const (
SONIC_OK = 0;
SONIC_CONTROL_CHAR = 1;
SONIC_INVALID_ESCAPED = 2;
SONIC_INVALID_NUM = 3;
SONIC_FLOAT_INF = 4;
SONIC_EOF = 5;
SONIC_INVALID_CHAR = 6;
SONIC_EXPECT_KEY = 7;
SONIC_EXPECT_COLON = 8;
SONIC_EXPECT_OBJ_COMMA_OR_END = 9;
SONIC_EXPECT_ARR_COMMA_OR_END = 10;
SONIC_VISIT_FAILED = 11;
SONIC_INVALID_ESCAPED_UTF = 12;
SONIC_INVALID_LITERAL = 13;
SONIC_STACK_OVERFLOW = 14;
)
var ParsingErrors = []string{
SONIC_OK : "ok",
SONIC_CONTROL_CHAR : "control chars in string",
SONIC_INVALID_ESCAPED : "invalid escaped chars in string",
SONIC_INVALID_NUM : "invalid number",
SONIC_FLOAT_INF : "float infinity",
SONIC_EOF : "eof",
SONIC_INVALID_CHAR : "invalid chars",
SONIC_EXPECT_KEY : "expect a json key",
SONIC_EXPECT_COLON : "expect a `:`",
SONIC_EXPECT_OBJ_COMMA_OR_END : "expect a `,` or `}`",
SONIC_EXPECT_ARR_COMMA_OR_END : "expect a `,` or `]`",
SONIC_VISIT_FAILED : "failed in json visitor",
SONIC_INVALID_ESCAPED_UTF : "invalid escaped unicodes",
SONIC_INVALID_LITERAL : "invalid literal(true/false/null)",
SONIC_STACK_OVERFLOW : "json is exceeded max depth 4096, cause stack overflow",
}
func (code ErrorCode) Error() string {
return ParsingErrors[code]
}
type node struct {
typ uint64
val uint64
}
// should consitent with native/parser.c
type _nospaceBlock struct {
_ [8]byte
_ [8]byte
}
// should consitent with native/parser.c
type nodeBuf struct {
ncur uintptr
parent int64
depth uint64
nstart uintptr
nend uintptr
stat jsonStat
}
func (self *nodeBuf) init(nodes []node) {
self.ncur = uintptr(unsafe.Pointer(&nodes[0]))
self.nstart = self.ncur
self.nend = self.ncur + uintptr(cap(nodes)) * unsafe.Sizeof(node{})
self.parent = -1
}
// should consitent with native/parser.c
type Parser struct {
Json string
padded []byte
nodes []node
dbuf []byte
backup []node
options uint64
// JSON cursor
start uintptr
cur uintptr
end uintptr
_nbk _nospaceBlock
// node buffer cursor
nbuf nodeBuf
Utf8Inv bool
isEface bool
}
// only when parse non-empty object/array are needed.
type jsonStat struct {
object uint32
array uint32
str uint32
number uint32
array_elems uint32
object_keys uint32
max_depth uint32
}
var (
defaultJsonPaddedCap uintptr = 1 << 20 // 1 Mb
defaultNodesCap uintptr = (1 << 20) / unsafe.Sizeof(node{}) // 1 Mb
)
var parsePool sync.Pool = sync.Pool {
New: func () interface{} {
return &Parser{
options: 0,
padded: make([]byte, 0, defaultJsonPaddedCap),
nodes: make([]node, defaultNodesCap, defaultNodesCap),
dbuf: make([]byte, types.MaxDigitNums, types.MaxDigitNums),
}
},
}
var padding string = "x\"x\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
func newParser(data string, pos int, opt uint64) *Parser {
p := parsePool.Get().(*Parser)
/* validate json if needed */
if (opt & (1 << _F_validate_string)) != 0 && !utf8.ValidateString(data){
dbuf := utf8.CorrectWith(nil, rt.Str2Mem(data[pos:]), "\ufffd")
dbuf = append(dbuf, padding...)
p.Json = rt.Mem2Str(dbuf[:len(dbuf) - len(padding)])
p.Utf8Inv = true
p.start = uintptr((*rt.GoString)(unsafe.Pointer(&p.Json)).Ptr)
} else {
p.Json = data
// TODO: prevent too large JSON
p.padded = append(p.padded, data[pos:]...)
p.padded = append(p.padded, padding...)
p.start = uintptr((*rt.GoSlice)(unsafe.Pointer(&p.padded)).Ptr)
}
p.cur = p.start
p.end = p.cur + uintptr(len(p.Json))
p.options = opt
p.nbuf.init(p.nodes)
return p
}
func (p *Parser) Pos() int {
return int(p.cur - p.start)
}
func (p *Parser) JsonBytes() []byte {
if p.Utf8Inv {
return (rt.Str2Mem(p.Json))
} else {
return p.padded
}
}
var nodeType = rt.UnpackType(reflect.TypeOf(node{}))
//go:inline
func calMaxNodeCap(jsonSize int) int {
return jsonSize / 2 + 2
}
func (p *Parser) parse() ErrorCode {
// when decode into struct, we should decode number as possible
old := p.options
if !p.isEface {
p.options &^= 1 << _F_use_number
}
// fast path with limited node buffer
err := ErrorCode(native.ParseWithPadding(unsafe.Pointer(p)))
if err != SONIC_VISIT_FAILED {
p.options = old
return err
}
// check OoB here
offset := p.nbuf.ncur - p.nbuf.nstart
curLen := offset / unsafe.Sizeof(node{})
if curLen != uintptr(len(p.nodes)) {
panic(fmt.Sprintf("current len: %d, real len: %d cap: %d", curLen, len(p.nodes), cap(p.nodes)))
}
// node buf is not enough, continue parse
// the maxCap is always meet all valid JSON
maxCap := calMaxNodeCap(len(p.Json))
slice := rt.GoSlice{
Ptr: rt.Mallocgc(uintptr(maxCap) * nodeType.Size, nodeType, false),
Len: maxCap,
Cap: maxCap,
}
rt.Memmove(unsafe.Pointer(slice.Ptr), unsafe.Pointer(&p.nodes[0]), offset)
p.backup = p.nodes
p.nodes = *(*[]node)(unsafe.Pointer(&slice))
// update node cursor
p.nbuf.nstart = uintptr(unsafe.Pointer(&p.nodes[0]))
p.nbuf.nend = p.nbuf.nstart + uintptr(cap(p.nodes)) * unsafe.Sizeof(node{})
p.nbuf.ncur = p.nbuf.nstart + offset
// continue parse json
err = ErrorCode(native.ParseWithPadding(unsafe.Pointer(p)))
p.options = old
return err
}
func (p *Parser) reset() {
p.options = 0
p.padded = p.padded[:0]
// nodes is too large here, we will not reset it and use small backup nodes buffer
if p.backup != nil {
p.nodes = p.backup
p.backup = nil
}
p.start = 0
p.cur = 0
p.end = 0
p.Json = ""
p.nbuf = nodeBuf{}
p._nbk = _nospaceBlock{}
p.Utf8Inv = false
p.isEface = false
}
func (p *Parser) free() {
p.reset()
parsePool.Put(p)
}
//go:noinline
func (p *Parser) fixError(code ErrorCode) error {
if code == SONIC_OK {
return nil
}
if p.Pos() == 0 {
code = SONIC_EOF;
}
pos := p.Pos() - 1
return error_syntax(pos, p.Json, ParsingErrors[code])
}
func Parse(data string, opt uint64) error {
p := newParser(data, 0, opt)
err := p.parse()
p.free()
return err
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,224 @@
package optdec
import (
"reflect"
"unsafe"
"github.com/bytedance/sonic/internal/rt"
)
type sliceDecoder struct {
elemType *rt.GoType
elemDec decFunc
typ reflect.Type
}
var (
emptyPtr = &struct{}{}
)
func (d *sliceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*rt.GoSlice)(vp) = rt.GoSlice{}
return nil
}
arr, ok := node.AsArr()
if !ok {
return error_mismatch(node, ctx, d.typ)
}
slice := rt.MakeSlice(vp, d.elemType, arr.Len())
elems := slice.Ptr
next := arr.Children()
var gerr error
for i := 0; i < arr.Len(); i++ {
val := NewNode(next)
elem := unsafe.Pointer(uintptr(elems) + uintptr(i)*d.elemType.Size)
err := d.elemDec.FromDom(elem, val, ctx)
if gerr == nil && err != nil {
gerr = err
}
next = val.Next()
}
*(*rt.GoSlice)(vp) = *slice
return gerr
}
type arrayDecoder struct {
len int
elemType *rt.GoType
elemDec decFunc
typ reflect.Type
}
//go:nocheckptr
func (d *arrayDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
arr, ok := node.AsArr()
if !ok {
return error_mismatch(node, ctx, d.typ)
}
next := arr.Children()
i := 0
var gerr error
for ; i < d.len && i < arr.Len(); i++ {
elem := unsafe.Pointer(uintptr(vp) + uintptr(i)*d.elemType.Size)
val := NewNode(next)
err := d.elemDec.FromDom(elem, val, ctx)
if gerr == nil && err != nil {
gerr = err
}
next = val.Next()
}
/* zero rest of array */
ptr := unsafe.Pointer(uintptr(vp) + uintptr(i)*d.elemType.Size)
n := uintptr(d.len-i) * d.elemType.Size
rt.ClearMemory(d.elemType, ptr, n)
return gerr
}
type sliceEfaceDecoder struct {
}
func (d *sliceEfaceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*rt.GoSlice)(vp) = rt.GoSlice{}
return nil
}
return node.AsSliceEface(ctx, vp)
}
type sliceI32Decoder struct {
}
func (d *sliceI32Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*rt.GoSlice)(vp) = rt.GoSlice{}
return nil
}
return node.AsSliceI32(ctx, vp)
}
type sliceI64Decoder struct {
}
func (d *sliceI64Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*rt.GoSlice)(vp) = rt.GoSlice{}
return nil
}
return node.AsSliceI64(ctx, vp)
}
type sliceU32Decoder struct {
}
func (d *sliceU32Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*rt.GoSlice)(vp) = rt.GoSlice{}
return nil
}
return node.AsSliceU32(ctx, vp)
}
type sliceU64Decoder struct {
}
func (d *sliceU64Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*rt.GoSlice)(vp) = rt.GoSlice{}
return nil
}
return node.AsSliceU64(ctx, vp)
}
type sliceStringDecoder struct {
}
func (d *sliceStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*rt.GoSlice)(vp) = rt.GoSlice{}
return nil
}
return node.AsSliceString(ctx, vp)
}
type sliceBytesDecoder struct {
}
func (d *sliceBytesDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*rt.GoSlice)(vp) = rt.GoSlice{}
return nil
}
s, err := node.AsSliceBytes(ctx)
if err != nil {
return err
}
*(*[]byte)(vp) = s
return nil
}
type sliceBytesUnmarshalerDecoder struct {
elemType *rt.GoType
elemDec decFunc
typ reflect.Type
}
func (d *sliceBytesUnmarshalerDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*rt.GoSlice)(vp) = rt.GoSlice{}
return nil
}
/* parse JSON string into `[]byte` */
if node.IsStr() {
slice, err := node.AsSliceBytes(ctx)
if err != nil {
return err
}
*(*[]byte)(vp) = slice
return nil
}
/* parse JSON array into `[]byte` */
arr, ok := node.AsArr()
if !ok {
return error_mismatch(node, ctx, d.typ)
}
slice := rt.MakeSlice(vp, d.elemType, arr.Len())
elems := slice.Ptr
var gerr error
next := arr.Children()
for i := 0; i < arr.Len(); i++ {
child := NewNode(next)
elem := unsafe.Pointer(uintptr(elems) + uintptr(i)*d.elemType.Size)
err := d.elemDec.FromDom(elem, child, ctx)
if gerr == nil && err != nil {
gerr = err
}
next = child.Next()
}
*(*rt.GoSlice)(vp) = *slice
return gerr
}

View file

@ -0,0 +1,360 @@
package optdec
import (
"encoding/json"
"math"
"unsafe"
"github.com/bytedance/sonic/internal/rt"
)
type ptrStrDecoder struct {
typ *rt.GoType
deref decFunc
}
// Pointer Value is allocated in the Caller
func (d *ptrStrDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*unsafe.Pointer)(vp) = nil
return nil
}
s, ok := node.AsStrRef(ctx)
if !ok {
return error_mismatch(node, ctx, stringType)
}
if s == "null" {
*(*unsafe.Pointer)(vp) = nil
return nil
}
if *(*unsafe.Pointer)(vp) == nil {
*(*unsafe.Pointer)(vp) = rt.Mallocgc(d.typ.Size, d.typ, true)
}
return d.deref.FromDom(*(*unsafe.Pointer)(vp), node, ctx)
}
type boolStringDecoder struct {
}
func (d *boolStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
s, ok := node.AsStrRef(ctx)
if !ok {
return error_mismatch(node, ctx, stringType)
}
if s == "null" {
return nil
}
b, err := ParseBool(s)
if err != nil {
return error_mismatch(node, ctx, boolType)
}
*(*bool)(vp) = b
return nil
}
func parseI64(node Node, ctx *context) (int64, error, bool) {
if node.IsNull() {
return 0, nil, true
}
s, ok := node.AsStrRef(ctx)
if !ok {
return 0, error_mismatch(node, ctx, stringType), false
}
if s == "null" {
return 0, nil, true
}
ret, err := ParseI64(s)
return ret, err, false
}
type i8StringDecoder struct{}
func (d *i8StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseI64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
if ret > math.MaxInt8 || ret < math.MinInt8 {
return error_mismatch(node, ctx, int8Type)
}
*(*int8)(vp) = int8(ret)
return nil
}
type i16StringDecoder struct{}
func (d *i16StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseI64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
if ret > math.MaxInt16 || ret < math.MinInt16 {
return error_mismatch(node, ctx, int16Type)
}
*(*int16)(vp) = int16(ret)
return nil
}
type i32StringDecoder struct{}
func (d *i32StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseI64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
if ret > math.MaxInt32 || ret < math.MinInt32 {
return error_mismatch(node, ctx, int32Type)
}
*(*int32)(vp) = int32(ret)
return nil
}
type i64StringDecoder struct{}
func (d *i64StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseI64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
*(*int64)(vp) = int64(ret)
return nil
}
func parseU64(node Node, ctx *context) (uint64, error, bool) {
if node.IsNull() {
return 0, nil, true
}
s, ok := node.AsStrRef(ctx)
if !ok {
return 0, error_mismatch(node, ctx, stringType), false
}
if s == "null" {
return 0, nil, true
}
ret, err := ParseU64(s)
return ret, err, false
}
type u8StringDecoder struct{}
func (d *u8StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseU64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
if ret > math.MaxUint8 {
return error_mismatch(node, ctx, uint8Type)
}
*(*uint8)(vp) = uint8(ret)
return nil
}
type u16StringDecoder struct{}
func (d *u16StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseU64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
if ret > math.MaxUint16 {
return error_mismatch(node, ctx, uint16Type)
}
*(*uint16)(vp) = uint16(ret)
return nil
}
type u32StringDecoder struct{}
func (d *u32StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseU64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
if ret > math.MaxUint32 {
return error_mismatch(node, ctx, uint32Type)
}
*(*uint32)(vp) = uint32(ret)
return nil
}
type u64StringDecoder struct{}
func (d *u64StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseU64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
*(*uint64)(vp) = uint64(ret)
return nil
}
type f32StringDecoder struct{}
func (d *f32StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
s, ok := node.AsStrRef(ctx)
if !ok {
return error_mismatch(node, ctx, stringType)
}
if s == "null" {
return nil
}
ret, err := ParseF64(s)
if err != nil || ret > math.MaxFloat32 || ret < -math.MaxFloat32 {
return error_mismatch(node, ctx, float32Type)
}
*(*float32)(vp) = float32(ret)
return nil
}
type f64StringDecoder struct{}
func (d *f64StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
s, ok := node.AsStrRef(ctx)
if !ok {
return error_mismatch(node, ctx, stringType)
}
if s == "null" {
return nil
}
ret, err := ParseF64(s)
if err != nil {
return error_mismatch(node, ctx, float64Type)
}
*(*float64)(vp) = float64(ret)
return nil
}
/* parse string field with string options */
type strStringDecoder struct{}
func (d *strStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
s, ok := node.AsStrRef(ctx)
if !ok {
return error_mismatch(node, ctx, stringType)
}
if s == "null" {
return nil
}
s, err := Unquote(s)
if err != nil {
return error_mismatch(node, ctx, stringType)
}
*(*string)(vp) = s
return nil
}
type numberStringDecoder struct{}
func (d *numberStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
s, ok := node.AsStrRef(ctx)
if !ok {
return error_mismatch(node, ctx, stringType)
}
if s == "null" {
return nil
}
num, ok := node.ParseNumber(ctx)
if !ok {
return error_mismatch(node, ctx, jsonNumberType)
}
end, ok := SkipNumberFast(s, 0)
// has error or trailing chars
if !ok || end != len(s) {
return error_mismatch(node, ctx, jsonNumberType)
}
*(*json.Number)(vp) = json.Number(num)
return nil
}

View file

@ -0,0 +1,61 @@
package optdec
import (
"reflect"
"unsafe"
caching "github.com/bytedance/sonic/internal/optcaching"
"github.com/bytedance/sonic/internal/resolver"
)
type fieldEntry struct {
resolver.FieldMeta
fieldDec decFunc
}
type structDecoder struct {
fieldMap caching.FieldLookup
fields []fieldEntry
structName string
typ reflect.Type
}
func (d *structDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
var gerr error
obj, ok := node.AsObj()
if !ok {
return error_mismatch(node, ctx, d.typ)
}
next := obj.Children()
for i := 0; i < obj.Len(); i++ {
key, _ := NewNode(next).AsStrRef(ctx)
val := NewNode(PtrOffset(next, 1))
next = val.Next()
// find field idx
idx := d.fieldMap.Get(key)
if idx == -1 {
if Options(ctx.Options())&OptionDisableUnknown != 0 {
return error_field(key)
}
continue
}
offset := d.fields[idx].Path[0].Size
elem := unsafe.Pointer(uintptr(vp) + offset)
err := d.fields[idx].fieldDec.FromDom(elem, val, ctx)
// deal with mismatch type errors
if gerr == nil && err != nil {
// TODO: better error info
gerr = err
}
}
return gerr
}

View file

@ -0,0 +1,60 @@
/*
* 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 optdec
import (
"encoding"
"encoding/base64"
"encoding/json"
"reflect"
"unsafe"
"github.com/bytedance/sonic/internal/rt"
)
var (
boolType = reflect.TypeOf(bool(false))
byteType = reflect.TypeOf(byte(0))
intType = reflect.TypeOf(int(0))
int8Type = reflect.TypeOf(int8(0))
int16Type = reflect.TypeOf(int16(0))
int32Type = reflect.TypeOf(int32(0))
int64Type = reflect.TypeOf(int64(0))
uintType = reflect.TypeOf(uint(0))
uint8Type = reflect.TypeOf(uint8(0))
uint16Type = reflect.TypeOf(uint16(0))
uint32Type = reflect.TypeOf(uint32(0))
uint64Type = reflect.TypeOf(uint64(0))
float32Type = reflect.TypeOf(float32(0))
float64Type = reflect.TypeOf(float64(0))
stringType = reflect.TypeOf("")
bytesType = reflect.TypeOf([]byte(nil))
jsonNumberType = reflect.TypeOf(json.Number(""))
base64CorruptInputError = reflect.TypeOf(base64.CorruptInputError(0))
anyType = rt.UnpackType(reflect.TypeOf((*interface{})(nil)).Elem())
)
var (
errorType = reflect.TypeOf((*error)(nil)).Elem()
jsonUnmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
encodingTextUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
)
func rtype(t reflect.Type) (*rt.GoItab, *rt.GoType) {
p := (*rt.GoIface)(unsafe.Pointer(&t))
return p.Itab, (*rt.GoType)(p.Value)
}

View file

@ -14,15 +14,16 @@
* limitations under the License.
*/
package encoder
package alg
import (
"encoding"
"reflect"
"strconv"
"sync"
"unsafe"
"github.com/bytedance/sonic/internal/native"
"github.com/bytedance/sonic/internal/encoder/vars"
"github.com/bytedance/sonic/internal/rt"
)
@ -32,8 +33,8 @@ type _MapPair struct {
m [32]byte
}
type _MapIterator struct {
it rt.GoMapIterator // must be the first field
type MapIterator struct {
It rt.GoMapIterator // must be the first field
kv rt.GoSlice // slice of _MapPair
ki int
}
@ -44,43 +45,43 @@ var (
)
func init() {
if unsafe.Offsetof(_MapIterator{}.it) != 0 {
if unsafe.Offsetof(MapIterator{}.It) != 0 {
panic("_MapIterator.it is not the first field")
}
}
func newIterator() *_MapIterator {
func newIterator() *MapIterator {
if v := iteratorPool.Get(); v == nil {
return new(_MapIterator)
return new(MapIterator)
} else {
return resetIterator(v.(*_MapIterator))
return resetIterator(v.(*MapIterator))
}
}
func resetIterator(p *_MapIterator) *_MapIterator {
func resetIterator(p *MapIterator) *MapIterator {
p.ki = 0
p.it = rt.GoMapIterator{}
p.It = rt.GoMapIterator{}
p.kv.Len = 0
return p
}
func (self *_MapIterator) at(i int) *_MapPair {
func (self *MapIterator) at(i int) *_MapPair {
return (*_MapPair)(unsafe.Pointer(uintptr(self.kv.Ptr) + uintptr(i) * unsafe.Sizeof(_MapPair{})))
}
func (self *_MapIterator) add() (p *_MapPair) {
func (self *MapIterator) add() (p *_MapPair) {
p = self.at(self.kv.Len)
self.kv.Len++
return
}
func (self *_MapIterator) data() (p []_MapPair) {
func (self *MapIterator) data() (p []_MapPair) {
*(*rt.GoSlice)(unsafe.Pointer(&p)) = self.kv
return
}
func (self *_MapIterator) append(t *rt.GoType, k unsafe.Pointer, v unsafe.Pointer) (err error) {
func (self *MapIterator) append(t *rt.GoType, k unsafe.Pointer, v unsafe.Pointer) (err error) {
p := self.add()
p.v = v
@ -94,26 +95,26 @@ func (self *_MapIterator) append(t *rt.GoType, k unsafe.Pointer, v unsafe.Pointe
return nil
}
func (self *_MapIterator) appendGeneric(p *_MapPair, t *rt.GoType, v reflect.Kind, k unsafe.Pointer) error {
func (self *MapIterator) appendGeneric(p *_MapPair, t *rt.GoType, v reflect.Kind, k unsafe.Pointer) error {
switch v {
case reflect.Int : p.k = rt.Mem2Str(p.m[:native.I64toa(&p.m[0], int64(*(*int)(k)))]) ; return nil
case reflect.Int8 : p.k = rt.Mem2Str(p.m[:native.I64toa(&p.m[0], int64(*(*int8)(k)))]) ; return nil
case reflect.Int16 : p.k = rt.Mem2Str(p.m[:native.I64toa(&p.m[0], int64(*(*int16)(k)))]) ; return nil
case reflect.Int32 : p.k = rt.Mem2Str(p.m[:native.I64toa(&p.m[0], int64(*(*int32)(k)))]) ; return nil
case reflect.Int64 : p.k = rt.Mem2Str(p.m[:native.I64toa(&p.m[0], *(*int64)(k))]) ; return nil
case reflect.Uint : p.k = rt.Mem2Str(p.m[:native.U64toa(&p.m[0], uint64(*(*uint)(k)))]) ; return nil
case reflect.Uint8 : p.k = rt.Mem2Str(p.m[:native.U64toa(&p.m[0], uint64(*(*uint8)(k)))]) ; return nil
case reflect.Uint16 : p.k = rt.Mem2Str(p.m[:native.U64toa(&p.m[0], uint64(*(*uint16)(k)))]) ; return nil
case reflect.Uint32 : p.k = rt.Mem2Str(p.m[:native.U64toa(&p.m[0], uint64(*(*uint32)(k)))]) ; return nil
case reflect.Uint64 : p.k = rt.Mem2Str(p.m[:native.U64toa(&p.m[0], *(*uint64)(k))]) ; return nil
case reflect.Uintptr : p.k = rt.Mem2Str(p.m[:native.U64toa(&p.m[0], uint64(*(*uintptr)(k)))]) ; return nil
case reflect.Int : p.k = rt.Mem2Str(strconv.AppendInt(p.m[:0], int64(*(*int)(k)), 10)) ; return nil
case reflect.Int8 : p.k = rt.Mem2Str(strconv.AppendInt(p.m[:0], int64(*(*int8)(k)), 10)) ; return nil
case reflect.Int16 : p.k = rt.Mem2Str(strconv.AppendInt(p.m[:0], int64(*(*int16)(k)), 10)) ; return nil
case reflect.Int32 : p.k = rt.Mem2Str(strconv.AppendInt(p.m[:0], int64(*(*int32)(k)), 10)) ; return nil
case reflect.Int64 : p.k = rt.Mem2Str(strconv.AppendInt(p.m[:0], int64(*(*int64)(k)), 10)) ; return nil
case reflect.Uint : p.k = rt.Mem2Str(strconv.AppendUint(p.m[:0], uint64(*(*uint)(k)), 10)) ; return nil
case reflect.Uint8 : p.k = rt.Mem2Str(strconv.AppendUint(p.m[:0], uint64(*(*uint8)(k)), 10)) ; return nil
case reflect.Uint16 : p.k = rt.Mem2Str(strconv.AppendUint(p.m[:0], uint64(*(*uint16)(k)), 10)) ; return nil
case reflect.Uint32 : p.k = rt.Mem2Str(strconv.AppendUint(p.m[:0], uint64(*(*uint32)(k)), 10)) ; return nil
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.Interface : return self.appendInterface(p, t, k)
case reflect.Struct, reflect.Ptr : return self.appendConcrete(p, t, k)
default : panic("unexpected map key type")
}
}
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) (err error) {
// compiler has already checked that the type implements the encoding.MarshalText interface
if !t.Indirect() {
k = *(*unsafe.Pointer)(k)
@ -127,7 +128,7 @@ func (self *_MapIterator) appendConcrete(p *_MapPair, t *rt.GoType, k unsafe.Poi
return
}
func (self *_MapIterator) appendInterface(p *_MapPair, t *rt.GoType, k unsafe.Pointer) (err error) {
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 {
@ -137,17 +138,17 @@ func (self *_MapIterator) appendInterface(p *_MapPair, t *rt.GoType, k unsafe.Po
}
}
func iteratorStop(p *_MapIterator) {
func IteratorStop(p *MapIterator) {
iteratorPool.Put(p)
}
func iteratorNext(p *_MapIterator) {
func IteratorNext(p *MapIterator) {
i := p.ki
t := &p.it
t := &p.It
/* check for unordered iteration */
if i < 0 {
mapiternext(t)
rt.Mapiternext(t)
return
}
@ -164,25 +165,25 @@ func iteratorNext(p *_MapIterator) {
p.ki++
}
func iteratorStart(t *rt.GoMapType, m *rt.GoMap, fv uint64) (*_MapIterator, error) {
func IteratorStart(t *rt.GoMapType, m *rt.GoMap, fv uint64) (*MapIterator, error) {
it := newIterator()
mapiterinit(t, m, &it.it)
rt.Mapiterinit(t, m, &it.It)
/* check for key-sorting, empty map don't need sorting */
if m.Count == 0 || (fv & uint64(SortMapKeys)) == 0 {
if m.Count == 0 || (fv & (1<<BitSortMapKeys)) == 0 {
it.ki = -1
return it, nil
}
/* pre-allocate space if needed */
if m.Count > it.kv.Cap {
it.kv = growslice(iteratorPair, it.kv, m.Count)
it.kv = rt.GrowSlice(iteratorPair, it.kv, m.Count)
}
/* dump all the key-value pairs */
for ; it.it.K != nil; mapiternext(&it.it) {
if err := it.append(t.Key, it.it.K, it.it.V); err != nil {
iteratorStop(it)
for ; it.It.K != nil; rt.Mapiternext(&it.It) {
if err := it.append(t.Key, it.It.K, it.It.V); err != nil {
IteratorStop(it)
return nil, err
}
}
@ -193,7 +194,13 @@ func iteratorStart(t *rt.GoMapType, m *rt.GoMap, fv uint64) (*_MapIterator, erro
}
/* load the first pair into iterator */
it.it.V = it.at(0).v
it.it.K = unsafe.Pointer(&it.at(0).k)
it.It.V = it.at(0).v
it.It.K = unsafe.Pointer(&it.at(0).k)
return it, nil
}
func asText(v unsafe.Pointer) (string, error) {
text := rt.AssertI2I(rt.UnpackType(vars.EncodingTextMarshalerType), *(*rt.GoIface)(v))
r, e := (*(*encoding.TextMarshaler)(unsafe.Pointer(&text))).MarshalText()
return rt.Mem2Str(r), e
}

View file

@ -0,0 +1,31 @@
/**
* Copyright 2024 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 alg
const (
BitSortMapKeys = iota
BitEscapeHTML
BitCompactMarshaler
BitNoQuoteTextMarshaler
BitNoNullSliceOrMap
BitValidateString
BitNoValidateJSONMarshaler
BitNoEncoderNewline
BitEncodeNullForInfOrNan
BitPointerValue = 63
)

View file

@ -0,0 +1,95 @@
/**
* Copyright 2024 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 alg
import (
"encoding"
"encoding/json"
"github.com/bytedance/sonic/internal/encoder/vars"
"github.com/bytedance/sonic/internal/rt"
)
func Compact(p *[]byte, v []byte) error {
buf := vars.NewBuffer()
err := json.Compact(buf, v)
/* check for errors */
if err != nil {
return err
}
/* add to result */
v = buf.Bytes()
*p = append(*p, v...)
/* return the buffer into pool */
vars.FreeBuffer(buf)
return nil
}
func EncodeNil(rb *[]byte) error {
*rb = append(*rb, 'n', 'u', 'l', 'l')
return nil
}
// func Make_EncodeTypedPointer(computor func(*rt.GoType, ...interface{}) (interface{}, error)) func(*[]byte, *rt.GoType, *unsafe.Pointer, *vars.Stack, uint64) error {
// return func(buf *[]byte, vt *rt.GoType, vp *unsafe.Pointer, sb *vars.Stack, fv uint64) error {
// if vt == nil {
// return EncodeNil(buf)
// } else if fn, err := vars.FindOrCompile(vt, (fv&(1<<BitPointerValue)) != 0, computor); err != nil {
// return err
// } else if vt.Indirect() {
// err := fn(buf, *vp, sb, fv)
// return err
// } else {
// err := fn(buf, unsafe.Pointer(vp), sb, fv)
// return err
// }
// }
// }
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 {
return Compact(buf, ret)
}
if opt&(1<<BitNoValidateJSONMarshaler) == 0 {
if ok, s := Valid(ret); !ok {
return vars.Error_marshaler(ret, s)
}
}
*buf = append(*buf, ret...)
return nil
}
}
func EncodeTextMarshaler(buf *[]byte, val encoding.TextMarshaler, opt uint64) error {
if ret, err := val.MarshalText(); err != nil {
return err
} else {
if opt&(1<<BitNoQuoteTextMarshaler) != 0 {
*buf = append(*buf, ret...)
return nil
}
*buf = Quote(*buf, rt.Mem2Str(ret), false)
return nil
}
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package encoder
package alg
// Algorithm 3-way Radix Quicksort, d means the radix.
// Reference: https://algs4.cs.princeton.edu/51radix/Quick3string.java.html

View file

@ -0,0 +1,198 @@
//go:build (amd64 && go1.16 && !go1.24) || (arm64 && go1.20 && !go1.24)
// +build amd64,go1.16,!go1.24 arm64,go1.20,!go1.24
/**
* Copyright 2024 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 alg
import (
"runtime"
"unsafe"
"github.com/bytedance/sonic/internal/native"
"github.com/bytedance/sonic/internal/native/types"
"github.com/bytedance/sonic/internal/rt"
)
// Valid validates json and returns first non-blank character position,
// if it is only one valid json value.
// Otherwise returns invalid character position using start.
//
// Note: it does not check for the invalid UTF-8 characters.
func Valid(data []byte) (ok bool, start int) {
n := len(data)
if n == 0 {
return false, -1
}
s := rt.Mem2Str(data)
p := 0
m := types.NewStateMachine()
ret := native.ValidateOne(&s, &p, m, 0)
types.FreeStateMachine(m)
if ret < 0 {
return false, p-1
}
/* check for trailing spaces */
for ;p < n; p++ {
if (types.SPACE_MASK & (1 << data[p])) == 0 {
return false, p
}
}
return true, ret
}
var typeByte = rt.UnpackEface(byte(0)).Type
//go:nocheckptr
func Quote(buf []byte, val string, double bool) []byte {
if len(val) == 0 {
if double {
return append(buf, `"\"\""`...)
}
return append(buf, `""`...)
}
if double {
buf = append(buf, `"\"`...)
} else {
buf = append(buf, `"`...)
}
sp := rt.IndexChar(val, 0)
nb := len(val)
b := (*rt.GoSlice)(unsafe.Pointer(&buf))
// input buffer
for nb > 0 {
// output buffer
dp := unsafe.Pointer(uintptr(b.Ptr) + uintptr(b.Len))
dn := b.Cap - b.Len
// call native.Quote, dn is byte count it outputs
opts := uint64(0)
if double {
opts = types.F_DOUBLE_UNQUOTE
}
ret := native.Quote(sp, nb, dp, &dn, opts)
// update *buf length
b.Len += dn
// no need more output
if ret >= 0 {
break
}
// double buf size
*b = rt.GrowSlice(typeByte, *b, b.Cap*2)
// ret is the complement of consumed input
ret = ^ret
// update input buffer
nb -= ret
sp = unsafe.Pointer(uintptr(sp) + uintptr(ret))
}
runtime.KeepAlive(buf)
runtime.KeepAlive(sp)
if double {
buf = append(buf, `\""`...)
} else {
buf = append(buf, `"`...)
}
return buf
}
func HtmlEscape(dst []byte, src []byte) []byte {
var sidx int
dst = append(dst, src[:0]...) // avoid check nil dst
sbuf := (*rt.GoSlice)(unsafe.Pointer(&src))
dbuf := (*rt.GoSlice)(unsafe.Pointer(&dst))
/* grow dst if it is shorter */
if cap(dst)-len(dst) < len(src)+types.BufPaddingSize {
cap := len(src)*3/2 + types.BufPaddingSize
*dbuf = rt.GrowSlice(typeByte, *dbuf, cap)
}
for sidx < sbuf.Len {
sp := rt.Add(sbuf.Ptr, uintptr(sidx))
dp := rt.Add(dbuf.Ptr, uintptr(dbuf.Len))
sn := sbuf.Len - sidx
dn := dbuf.Cap - dbuf.Len
nb := native.HTMLEscape(sp, sn, dp, &dn)
/* check for errors */
if dbuf.Len += dn; nb >= 0 {
break
}
/* not enough space, grow the slice and try again */
sidx += ^nb
*dbuf = rt.GrowSlice(typeByte, *dbuf, dbuf.Cap*2)
}
return dst
}
func F64toa(buf []byte, v float64) ([]byte) {
if v == 0 {
return append(buf, '0')
}
buf = rt.GuardSlice2(buf, 64)
ret := native.F64toa((*byte)(rt.IndexByte(buf, len(buf))), v)
if ret > 0 {
return buf[:len(buf)+ret]
} else {
return buf
}
}
func F32toa(buf []byte, v float32) ([]byte) {
if v == 0 {
return append(buf, '0')
}
buf = rt.GuardSlice2(buf, 64)
ret := native.F32toa((*byte)(rt.IndexByte(buf, len(buf))), v)
if ret > 0 {
return buf[:len(buf)+ret]
} else {
return buf
}
}
func I64toa(buf []byte, v int64) ([]byte) {
buf = rt.GuardSlice2(buf, 32)
ret := native.I64toa((*byte)(rt.IndexByte(buf, len(buf))), v)
if ret > 0 {
return buf[:len(buf)+ret]
} else {
return buf
}
}
func U64toa(buf []byte, v uint64) ([]byte) {
buf = rt.GuardSlice2(buf, 32)
ret := native.U64toa((*byte)(rt.IndexByte(buf, len(buf))), v)
if ret > 0 {
return buf[:len(buf)+ret]
} else {
return buf
}
}

View file

@ -0,0 +1,148 @@
// +build !amd64,!arm64 go1.24 !go1.16 arm64,!go1.20
/**
* Copyright 2024 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 alg
import (
_ "unsafe"
"unicode/utf8"
"strconv"
"bytes"
"encoding/json"
"github.com/bytedance/sonic/internal/rt"
)
// Valid validates json and returns first non-blank character position,
// if it is only one valid json value.
// Otherwise returns invalid character position using start.
//
// Note: it does not check for the invalid UTF-8 characters.
func Valid(data []byte) (ok bool, start int) {
ok = json.Valid(data)
return ok, 0
}
var typeByte = rt.UnpackEface(byte(0)).Type
func Quote(e []byte, s string, double bool) []byte {
if len(s) == 0 {
if double {
return append(e, `"\"\""`...)
}
return append(e, `""`...)
}
b := e
ss := len(e)
e = append(e, '"')
start := 0
for i := 0; i < len(s); {
if b := s[i]; b < utf8.RuneSelf {
if rt.SafeSet[b] {
i++
continue
}
if start < i {
e = append(e, s[start:i]...)
}
e = append(e, '\\')
switch b {
case '\\', '"':
e = append(e, b)
case '\n':
e = append(e, 'n')
case '\r':
e = append(e, 'r')
case '\t':
e = append(e, 't')
default:
// This encodes bytes < 0x20 except for \t, \n and \r.
// If escapeHTML is set, it also escapes <, >, and &
// because they can lead to security holes when
// user-controlled strings are rendered into JSON
// and served to some browsers.
e = append(e, `u00`...)
e = append(e, rt.Hex[b>>4])
e = append(e, rt.Hex[b&0xF])
}
i++
start = i
continue
}
c, size := utf8.DecodeRuneInString(s[i:])
// if correct && c == utf8.RuneError && size == 1 {
// if start < i {
// e = append(e, s[start:i]...)
// }
// e = append(e, `\ufffd`...)
// i += size
// start = i
// continue
// }
if c == '\u2028' || c == '\u2029' {
if start < i {
e = append(e, s[start:i]...)
}
e = append(e, `\u202`...)
e = append(e, rt.Hex[c&0xF])
i += size
start = i
continue
}
i += size
}
if start < len(s) {
e = append(e, s[start:]...)
}
e = append(e, '"')
if double {
return strconv.AppendQuote(b, string(e[ss:]))
} else {
return e
}
}
func HtmlEscape(dst []byte, src []byte) []byte {
buf := bytes.NewBuffer(dst)
json.HTMLEscape(buf, src)
return buf.Bytes()
}
func F64toa(buf []byte, v float64) ([]byte) {
bs := bytes.NewBuffer(buf)
_ = json.NewEncoder(bs).Encode(v)
return bs.Bytes()
}
func F32toa(buf []byte, v float32) ([]byte) {
bs := bytes.NewBuffer(buf)
_ = json.NewEncoder(bs).Encode(v)
return bs.Bytes()
}
func I64toa(buf []byte, v int64) ([]byte) {
return strconv.AppendInt(buf, int64(v), 10)
}
func U64toa(buf []byte, v uint64) ([]byte) {
return strconv.AppendUint(buf, v, 10)
}

View file

@ -1,51 +0,0 @@
// +build go1.16,!go1.17
// Copyright 2023 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
//
// 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 encoder
import (
`strconv`
`github.com/bytedance/sonic/internal/jit`
`github.com/twitchyliquid64/golang-asm/obj`
`github.com/twitchyliquid64/golang-asm/obj/x86`
)
var (
_V_writeBarrier = jit.Imm(int64(_runtime_writeBarrier))
_F_gcWriteBarrierAX = jit.Func(gcWriteBarrierAX)
)
func (self *_Assembler) WritePtr(i int, ptr obj.Addr, rec obj.Addr) {
if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX {
panic("rec contains AX!")
}
self.Emit("MOVQ", _V_writeBarrier, _R10)
self.Emit("CMPL", jit.Ptr(_R10, 0), jit.Imm(0))
self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
self.Emit("MOVQ", ptr, _AX)
self.xsave(_DI)
self.Emit("LEAQ", rec, _DI)
self.Emit("MOVQ", _F_gcWriteBarrierAX, _R10) // MOVQ ${fn}, AX
self.Rjmp("CALL", _R10)
self.xload(_DI)
self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
self.Emit("MOVQ", ptr, rec)
self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,205 +0,0 @@
// +build go1.17,!go1.23
/*
* 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 encoder
import (
`fmt`
`os`
`runtime`
`strings`
`unsafe`
`github.com/bytedance/sonic/internal/jit`
`github.com/twitchyliquid64/golang-asm/obj`
)
const _FP_debug = 128
var (
debugSyncGC = os.Getenv("SONIC_SYNC_GC") != ""
debugAsyncGC = os.Getenv("SONIC_NO_ASYNC_GC") == ""
debugCheckPtr = os.Getenv("SONIC_CHECK_POINTER") != ""
)
var (
_Instr_End = newInsOp(_OP_is_nil)
_F_gc = jit.Func(gc)
_F_println = jit.Func(println_wrapper)
_F_print = jit.Func(print)
)
func (self *_Assembler) dsave(r ...obj.Addr) {
for i, v := range r {
if i > _FP_debug / 8 - 1 {
panic("too many registers to save")
} else {
self.Emit("MOVQ", v, jit.Ptr(_SP, _FP_fargs + _FP_saves + _FP_locals + int64(i) * 8))
}
}
}
func (self *_Assembler) dload(r ...obj.Addr) {
for i, v := range r {
if i > _FP_debug / 8 - 1 {
panic("too many registers to load")
} else {
self.Emit("MOVQ", jit.Ptr(_SP, _FP_fargs + _FP_saves + _FP_locals + int64(i) * 8), v)
}
}
}
func println_wrapper(i int, op1 int, op2 int){
println(i, " Intrs ", op1, _OpNames[op1], "next: ", op2, _OpNames[op2])
}
func print(i int){
println(i)
}
func gc() {
if !debugSyncGC {
return
}
runtime.GC()
// debug.FreeOSMemory()
}
func (self *_Assembler) dcall(fn obj.Addr) {
self.Emit("MOVQ", fn, _R10) // MOVQ ${fn}, R10
self.Rjmp("CALL", _R10) // CALL R10
}
func (self *_Assembler) debug_gc() {
if !debugSyncGC {
return
}
self.dsave(_REG_debug...)
self.dcall(_F_gc)
self.dload(_REG_debug...)
}
func (self *_Assembler) debug_instr(i int, v *_Instr) {
if debugSyncGC {
if i+1 == len(self.p) {
self.print_gc(i, v, &_Instr_End)
} else {
next := &(self.p[i+1])
self.print_gc(i, v, next)
name := _OpNames[next.op()]
if strings.Contains(name, "save") {
return
}
}
// self.debug_gc()
}
}
//go:noescape
//go:linkname checkptrBase runtime.checkptrBase
func checkptrBase(p unsafe.Pointer) uintptr
//go:noescape
//go:linkname findObject runtime.findObject
func findObject(p, refBase, refOff uintptr) (base uintptr, s unsafe.Pointer, objIndex uintptr)
var (
_F_checkptr = jit.Func(checkptr)
_F_printptr = jit.Func(printptr)
)
var (
_R10 = jit.Reg("R10")
)
var _REG_debug = []obj.Addr {
jit.Reg("AX"),
jit.Reg("BX"),
jit.Reg("CX"),
jit.Reg("DX"),
jit.Reg("DI"),
jit.Reg("SI"),
jit.Reg("BP"),
jit.Reg("SP"),
jit.Reg("R8"),
jit.Reg("R9"),
jit.Reg("R10"),
jit.Reg("R11"),
jit.Reg("R12"),
jit.Reg("R13"),
jit.Reg("R14"),
jit.Reg("R15"),
}
func checkptr(ptr uintptr) {
if ptr == 0 {
return
}
fmt.Printf("pointer: %x\n", ptr)
f := checkptrBase(unsafe.Pointer(uintptr(ptr)))
if f == 0 {
fmt.Printf("! unknown-based pointer: %x\n", ptr)
} else if f == 1 {
fmt.Printf("! stack pointer: %x\n", ptr)
} else {
fmt.Printf("base: %x\n", f)
}
findobj(ptr)
}
func findobj(ptr uintptr) {
base, s, objIndex := findObject(ptr, 0, 0)
if s != nil && base == 0 {
fmt.Printf("! invalid pointer: %x\n", ptr)
}
fmt.Printf("objIndex: %d\n", objIndex)
}
func (self *_Assembler) check_ptr(ptr obj.Addr, lea bool) {
if !debugCheckPtr {
return
}
self.dsave(_REG_debug...)
if lea {
self.Emit("LEAQ", ptr, _R10)
} else {
self.Emit("MOVQ", ptr, _R10)
}
self.Emit("MOVQ", _R10, jit.Ptr(_SP, 0))
self.dcall(_F_checkptr)
self.dload(_REG_debug...)
}
func printptr(i int, ptr uintptr) {
fmt.Printf("[%d] ptr: %x\n", i, ptr)
}
func (self *_Assembler) print_ptr(i int, ptr obj.Addr, lea bool) {
self.dsave(_REG_debug...)
if lea {
self.Emit("LEAQ", ptr, _R10)
} else {
self.Emit("MOVQ", ptr, _R10)
}
self.Emit("MOVQ", jit.Imm(int64(i)), _AX)
self.Emit("MOVQ", _R10, _BX)
self.dcall(_F_printptr)
self.dload(_REG_debug...)
}

View file

@ -0,0 +1,24 @@
//go:build !race
// +build !race
/*
* 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 encoder
func encodeIntoCheckRace(buf *[]byte, val interface{}, opts Options) error {
return encodeInto(buf, val, opts)
}

View file

@ -0,0 +1,54 @@
//go:build race
// +build race
/*
* 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 encoder
import (
`encoding/json`
`github.com/bytedance/sonic/internal/rt`
)
func helpDetectDataRace(val interface{}) {
var out []byte
defer func() {
if v := recover(); v != nil {
// NOTICE: help user to locate where panic occurs
println("panic when encoding on: ", truncate(out))
panic(v)
}
}()
out, _ = json.Marshal(val)
}
func encodeIntoCheckRace(buf *[]byte, val interface{}, opts Options) error {
err := encodeInto(buf, val, opts)
/* put last to make the panic from sonic will always be caught at first */
helpDetectDataRace(val)
return err
}
func truncate(json []byte) string {
if len(json) <= 256 {
return rt.Mem2Str(json)
} else {
return rt.Mem2Str(json[len(json)-256:])
}
}

View file

@ -17,72 +17,62 @@
package encoder
import (
`bytes`
`encoding/json`
`reflect`
`runtime`
`unsafe`
"bytes"
"encoding/json"
"reflect"
"runtime"
"unsafe"
`github.com/bytedance/sonic/internal/native`
`github.com/bytedance/sonic/internal/native/types`
`github.com/bytedance/sonic/internal/rt`
`github.com/bytedance/sonic/utf8`
`github.com/bytedance/sonic/option`
"github.com/bytedance/sonic/utf8"
"github.com/bytedance/sonic/internal/encoder/alg"
"github.com/bytedance/sonic/internal/encoder/vars"
"github.com/bytedance/sonic/internal/rt"
"github.com/bytedance/sonic/option"
)
// Options is a set of encoding options.
type Options uint64
const (
bitSortMapKeys = iota
bitEscapeHTML
bitCompactMarshaler
bitNoQuoteTextMarshaler
bitNoNullSliceOrMap
bitValidateString
bitNoValidateJSONMarshaler
bitNoEncoderNewline
// used for recursive compile
bitPointerValue = 63
)
const (
// SortMapKeys indicates that the keys of a map needs to be sorted
// before serializing into JSON.
// WARNING: This hurts performance A LOT, USE WITH CARE.
SortMapKeys Options = 1 << bitSortMapKeys
SortMapKeys Options = 1 << alg.BitSortMapKeys
// EscapeHTML indicates encoder to escape all HTML characters
// after serializing into JSON (see https://pkg.go.dev/encoding/json#HTMLEscape).
// WARNING: This hurts performance A LOT, USE WITH CARE.
EscapeHTML Options = 1 << bitEscapeHTML
EscapeHTML Options = 1 << alg.BitEscapeHTML
// CompactMarshaler indicates that the output JSON from json.Marshaler
// is always compact and needs no validation
CompactMarshaler Options = 1 << bitCompactMarshaler
CompactMarshaler Options = 1 << alg.BitCompactMarshaler
// NoQuoteTextMarshaler indicates that the output text from encoding.TextMarshaler
// is always escaped string and needs no quoting
NoQuoteTextMarshaler Options = 1 << bitNoQuoteTextMarshaler
NoQuoteTextMarshaler Options = 1 << alg.BitNoQuoteTextMarshaler
// NoNullSliceOrMap indicates all empty Array or Object are encoded as '[]' or '{}',
// instead of 'null'
NoNullSliceOrMap Options = 1 << bitNoNullSliceOrMap
// instead of 'null'.
// NOTE: The priority of this option is lower than json tag `omitempty`.
NoNullSliceOrMap Options = 1 << alg.BitNoNullSliceOrMap
// ValidateString indicates that encoder should validate the input string
// before encoding it into JSON.
ValidateString Options = 1 << bitValidateString
ValidateString Options = 1 << alg.BitValidateString
// NoValidateJSONMarshaler indicates that the encoder should not validate the output string
// after encoding the JSONMarshaler to JSON.
NoValidateJSONMarshaler Options = 1 << bitNoValidateJSONMarshaler
NoValidateJSONMarshaler Options = 1 << alg.BitNoValidateJSONMarshaler
// NoEncoderNewline indicates that the encoder should not add a newline after every message
NoEncoderNewline Options = 1 << bitNoEncoderNewline
NoEncoderNewline Options = 1 << alg.BitNoEncoderNewline
// CompatibleWithStd is used to be compatible with std encoder.
CompatibleWithStd Options = SortMapKeys | EscapeHTML | CompactMarshaler
// Encode Infinity or Nan float into `null`, instead of returning an error.
EncodeNullForInfOrNan Options = 1 << alg.BitEncodeNullForInfOrNan
)
// Encoder represents a specific set of encoder configurations.
@ -171,53 +161,45 @@ func (enc *Encoder) SetIndent(prefix, indent string) {
// Quote returns the JSON-quoted version of s.
func Quote(s string) string {
var n int
var p []byte
/* check for empty string */
if s == "" {
return `""`
}
/* allocate space for result */
n = len(s) + 2
p = make([]byte, 0, n)
/* call the encoder */
_ = encodeString(&p, s)
return rt.Mem2Str(p)
buf := make([]byte, 0, len(s)+2)
buf = alg.Quote(buf, s, false)
return rt.Mem2Str(buf)
}
// Encode returns the JSON encoding of val, encoded with opts.
func Encode(val interface{}, opts Options) ([]byte, error) {
var ret []byte
buf := newBytes()
err := encodeInto(&buf, val, opts)
buf := vars.NewBytes()
err := encodeIntoCheckRace(buf, val, opts)
/* check for errors */
if err != nil {
freeBytes(buf)
vars.FreeBytes(buf)
return nil, err
}
/* htmlescape or correct UTF-8 if opts enable */
old := buf
buf = encodeFinish(old, opts)
pbuf := ((*rt.GoSlice)(unsafe.Pointer(&buf))).Ptr
pold := ((*rt.GoSlice)(unsafe.Pointer(&old))).Ptr
*buf = encodeFinish(*old, opts)
pbuf := ((*rt.GoSlice)(unsafe.Pointer(buf))).Ptr
pold := ((*rt.GoSlice)(unsafe.Pointer(old))).Ptr
/* return when allocated a new buffer */
if pbuf != pold {
freeBytes(old)
return buf, nil
vars.FreeBytes(old)
return *buf, nil
}
/* make a copy of the result */
ret = make([]byte, len(buf))
copy(ret, buf)
freeBytes(buf)
if rt.CanSizeResue(cap(*buf)) {
ret = make([]byte, len(*buf))
copy(ret, *buf)
vars.FreeBytes(buf)
} else {
ret = *buf
}
/* return the buffer into pool */
return ret, nil
}
@ -225,7 +207,7 @@ func Encode(val interface{}, opts Options) ([]byte, error) {
// EncodeInto is like Encode but uses a user-supplied buffer instead of allocating
// a new one.
func EncodeInto(buf *[]byte, val interface{}, opts Options) error {
err := encodeInto(buf, val, opts)
err := encodeIntoCheckRace(buf, val, opts)
if err != nil {
return err
}
@ -234,15 +216,15 @@ func EncodeInto(buf *[]byte, val interface{}, opts Options) error {
}
func encodeInto(buf *[]byte, val interface{}, opts Options) error {
stk := newStack()
stk := vars.NewStack()
efv := rt.UnpackEface(val)
err := encodeTypedPointer(buf, efv.Type, &efv.Value, stk, uint64(opts))
/* return the stack into pool */
if err != nil {
resetStack(stk)
vars.ResetStack(stk)
}
freeStack(stk)
vars.FreeStack(stk)
/* avoid GC ahead */
runtime.KeepAlive(buf)
@ -254,13 +236,12 @@ func encodeFinish(buf []byte, opts Options) []byte {
if opts & EscapeHTML != 0 {
buf = HTMLEscape(nil, buf)
}
if opts & ValidateString != 0 && !utf8.Validate(buf) {
if (opts & ValidateString != 0) && !utf8.Validate(buf) {
buf = utf8.CorrectWith(nil, buf, `\ufffd`)
}
return buf
}
var typeByte = rt.UnpackType(reflect.TypeOf(byte(0)))
// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
@ -269,7 +250,7 @@ var typeByte = rt.UnpackType(reflect.TypeOf(byte(0)))
// escaping within <script> tags, so an alternative JSON encoding must
// be used.
func HTMLEscape(dst []byte, src []byte) []byte {
return htmlEscape(dst, src)
return alg.HtmlEscape(dst, src)
}
// EncodeIndented is like Encode but applies Indent to format the output.
@ -277,37 +258,40 @@ func HTMLEscape(dst []byte, src []byte) []byte {
// followed by one or more copies of indent according to the indentation nesting.
func EncodeIndented(val interface{}, prefix string, indent string, opts Options) ([]byte, error) {
var err error
var out []byte
var buf *bytes.Buffer
/* encode into the buffer */
out = newBytes()
err = EncodeInto(&out, val, opts)
out := vars.NewBytes()
err = EncodeInto(out, val, opts)
/* check for errors */
if err != nil {
freeBytes(out)
vars.FreeBytes(out)
return nil, err
}
/* indent the JSON */
buf = newBuffer()
err = json.Indent(buf, out, prefix, indent)
buf = vars.NewBuffer()
err = json.Indent(buf, *out, prefix, indent)
vars.FreeBytes(out)
/* check for errors */
if err != nil {
freeBytes(out)
freeBuffer(buf)
vars.FreeBuffer(buf)
return nil, err
}
/* copy to the result buffer */
ret := make([]byte, buf.Len())
copy(ret, buf.Bytes())
/* return the buffers into pool */
freeBytes(out)
freeBuffer(buf)
var ret []byte
if rt.CanSizeResue(cap(buf.Bytes())) {
ret = make([]byte, buf.Len())
copy(ret, buf.Bytes())
/* return the buffers into pool */
vars.FreeBuffer(buf)
} else {
ret = buf.Bytes()
}
return ret, nil
}
@ -330,26 +314,5 @@ func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
//
// Note: it does not check for the invalid UTF-8 characters.
func Valid(data []byte) (ok bool, start int) {
n := len(data)
if n == 0 {
return false, -1
}
s := rt.Mem2Str(data)
p := 0
m := types.NewStateMachine()
ret := native.ValidateOne(&s, &p, m, types.F_VALIDATE_STRING)
types.FreeStateMachine(m)
if ret < 0 {
return false, p-1
}
/* check for trailing spaces */
for ;p < n; p++ {
if (types.SPACE_MASK & (1 << data[p])) == 0 {
return false, p
}
}
return true, ret
return alg.Valid(data)
}

View file

@ -0,0 +1,473 @@
/*
* 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 ir
import (
"fmt"
"reflect"
"strconv"
"strings"
"unsafe"
"github.com/bytedance/sonic/internal/encoder/vars"
"github.com/bytedance/sonic/internal/rt"
)
type Op uint8
const (
OP_null Op = iota + 1
OP_empty_arr
OP_empty_obj
OP_bool
OP_i8
OP_i16
OP_i32
OP_i64
OP_u8
OP_u16
OP_u32
OP_u64
OP_f32
OP_f64
OP_str
OP_bin
OP_quote
OP_number
OP_eface
OP_iface
OP_byte
OP_text
OP_deref
OP_index
OP_load
OP_save
OP_drop
OP_drop_2
OP_recurse
OP_is_nil
OP_is_nil_p1
OP_is_zero_1
OP_is_zero_2
OP_is_zero_4
OP_is_zero_8
OP_is_zero_map
OP_goto
OP_map_iter
OP_map_stop
OP_map_check_key
OP_map_write_key
OP_map_value_next
OP_slice_len
OP_slice_next
OP_marshal
OP_marshal_p
OP_marshal_text
OP_marshal_text_p
OP_cond_set
OP_cond_testc
)
const (
_INT_SIZE = 32 << (^uint(0) >> 63)
_PTR_SIZE = 32 << (^uintptr(0) >> 63)
_PTR_BYTE = unsafe.Sizeof(uintptr(0))
)
const OpSize = unsafe.Sizeof(NewInsOp(0))
var OpNames = [256]string{
OP_null: "null",
OP_empty_arr: "empty_arr",
OP_empty_obj: "empty_obj",
OP_bool: "bool",
OP_i8: "i8",
OP_i16: "i16",
OP_i32: "i32",
OP_i64: "i64",
OP_u8: "u8",
OP_u16: "u16",
OP_u32: "u32",
OP_u64: "u64",
OP_f32: "f32",
OP_f64: "f64",
OP_str: "str",
OP_bin: "bin",
OP_quote: "quote",
OP_number: "number",
OP_eface: "eface",
OP_iface: "iface",
OP_byte: "byte",
OP_text: "text",
OP_deref: "deref",
OP_index: "index",
OP_load: "load",
OP_save: "save",
OP_drop: "drop",
OP_drop_2: "drop_2",
OP_recurse: "recurse",
OP_is_nil: "is_nil",
OP_is_nil_p1: "is_nil_p1",
OP_is_zero_1: "is_zero_1",
OP_is_zero_2: "is_zero_2",
OP_is_zero_4: "is_zero_4",
OP_is_zero_8: "is_zero_8",
OP_is_zero_map: "is_zero_map",
OP_goto: "goto",
OP_map_iter: "map_iter",
OP_map_stop: "map_stop",
OP_map_check_key: "map_check_key",
OP_map_write_key: "map_write_key",
OP_map_value_next: "map_value_next",
OP_slice_len: "slice_len",
OP_slice_next: "slice_next",
OP_marshal: "marshal",
OP_marshal_p: "marshal_p",
OP_marshal_text: "marshal_text",
OP_marshal_text_p: "marshal_text_p",
OP_cond_set: "cond_set",
OP_cond_testc: "cond_testc",
}
func (self Op) String() string {
if ret := OpNames[self]; ret != "" {
return ret
} else {
return "<invalid>"
}
}
func OP_int() Op {
switch _INT_SIZE {
case 32:
return OP_i32
case 64:
return OP_i64
default:
panic("unsupported int size")
}
}
func OP_uint() Op {
switch _INT_SIZE {
case 32:
return OP_u32
case 64:
return OP_u64
default:
panic("unsupported uint size")
}
}
func OP_uintptr() Op {
switch _PTR_SIZE {
case 32:
return OP_u32
case 64:
return OP_u64
default:
panic("unsupported pointer size")
}
}
func OP_is_zero_ints() Op {
switch _INT_SIZE {
case 32:
return OP_is_zero_4
case 64:
return OP_is_zero_8
default:
panic("unsupported integer size")
}
}
type Instr struct {
o Op
u int // union {op: 8, _: 8, vi: 48}, vi maybe int or len(str)
p unsafe.Pointer // maybe GoString.Ptr, or *GoType
}
func NewInsOp(op Op) Instr {
return Instr{o: op}
}
func NewInsVi(op Op, vi int) Instr {
return Instr{o: op, u: vi}
}
func NewInsVs(op Op, vs string) Instr {
return Instr{
o: op,
u: len(vs),
p: (*rt.GoString)(unsafe.Pointer(&vs)).Ptr,
}
}
func NewInsVt(op Op, vt reflect.Type) Instr {
return Instr{
o: op,
p: unsafe.Pointer(rt.UnpackType(vt)),
}
}
type typAndTab struct {
vt *rt.GoType
itab *rt.GoItab
}
func NewInsVtab(op Op, vt reflect.Type, itab *rt.GoItab) Instr {
return Instr{
o: op,
p: unsafe.Pointer(&typAndTab{
vt: rt.UnpackType(vt),
itab: itab,
}),
}
}
func NewInsVp(op Op, vt reflect.Type, pv bool) Instr {
i := 0
if pv {
i = 1
}
return Instr{
o: op,
u: i,
p: unsafe.Pointer(rt.UnpackType(vt)),
}
}
func (self Instr) Op() Op {
return Op(self.o)
}
func (self Instr) Vi() int {
return self.u
}
func (self Instr) Vf() uint8 {
return (*rt.GoType)(self.p).KindFlags
}
func (self Instr) Vs() (v string) {
(*rt.GoString)(unsafe.Pointer(&v)).Ptr = self.p
(*rt.GoString)(unsafe.Pointer(&v)).Len = self.Vi()
return
}
func (self Instr) Vk() reflect.Kind {
return (*rt.GoType)(self.p).Kind()
}
func (self Instr) Vt() reflect.Type {
return (*rt.GoType)(self.p).Pack()
}
func (self Instr) Vr() *rt.GoType {
return (*rt.GoType)(self.p)
}
func (self Instr) Vp() (vt reflect.Type, pv bool) {
return (*rt.GoType)(self.p).Pack(), self.u == 1
}
func (self Instr) Vtab() (vt *rt.GoType, itab *rt.GoItab) {
tt := (*typAndTab)(self.p)
return tt.vt, tt.itab
}
func (self Instr) Vp2() (vt *rt.GoType, pv bool) {
return (*rt.GoType)(self.p), self.u == 1
}
func (self Instr) I64() int64 {
return int64(self.Vi())
}
func (self Instr) Byte() byte {
return byte(self.Vi())
}
func (self Instr) Vlen() int {
return int((*rt.GoType)(self.p).Size)
}
func (self Instr) isBranch() bool {
switch self.Op() {
case OP_goto:
fallthrough
case OP_is_nil:
fallthrough
case OP_is_nil_p1:
fallthrough
case OP_is_zero_1:
fallthrough
case OP_is_zero_2:
fallthrough
case OP_is_zero_4:
fallthrough
case OP_is_zero_8:
fallthrough
case OP_map_check_key:
fallthrough
case OP_map_write_key:
fallthrough
case OP_slice_next:
fallthrough
case OP_cond_testc:
return true
default:
return false
}
}
func (self Instr) Disassemble() string {
switch self.Op() {
case OP_byte:
return fmt.Sprintf("%-18s%s", self.Op().String(), strconv.QuoteRune(rune(self.Vi())))
case OP_text:
return fmt.Sprintf("%-18s%s", self.Op().String(), strconv.Quote(self.Vs()))
case OP_index:
return fmt.Sprintf("%-18s%d", self.Op().String(), self.Vi())
case OP_recurse:
fallthrough
case OP_map_iter:
return fmt.Sprintf("%-18s%s", self.Op().String(), self.Vt())
case OP_marshal:
fallthrough
case OP_marshal_p:
fallthrough
case OP_marshal_text:
fallthrough
case OP_marshal_text_p:
vt, _ := self.Vtab()
return fmt.Sprintf("%-18s%s", self.Op().String(), vt.Pack())
case OP_goto:
fallthrough
case OP_is_nil:
fallthrough
case OP_is_nil_p1:
fallthrough
case OP_is_zero_1:
fallthrough
case OP_is_zero_2:
fallthrough
case OP_is_zero_4:
fallthrough
case OP_is_zero_8:
fallthrough
case OP_is_zero_map:
fallthrough
case OP_cond_testc:
fallthrough
case OP_map_check_key:
fallthrough
case OP_map_write_key:
return fmt.Sprintf("%-18sL_%d", self.Op().String(), self.Vi())
case OP_slice_next:
return fmt.Sprintf("%-18sL_%d, %s", self.Op().String(), self.Vi(), self.Vt())
default:
return fmt.Sprintf("%#v", self)
}
}
type (
Program []Instr
)
func (self Program) PC() int {
return len(self)
}
func (self Program) Tag(n int) {
if n >= vars.MaxStack {
panic("type nesting too deep")
}
}
func (self Program) Pin(i int) {
v := &self[i]
v.u = self.PC()
}
func (self Program) Rel(v []int) {
for _, i := range v {
self.Pin(i)
}
}
func (self *Program) Add(op Op) {
*self = append(*self, NewInsOp(op))
}
func (self *Program) Key(op Op) {
*self = append(*self,
NewInsVi(OP_byte, '"'),
NewInsOp(op),
NewInsVi(OP_byte, '"'),
)
}
func (self *Program) Int(op Op, vi int) {
*self = append(*self, NewInsVi(op, vi))
}
func (self *Program) Str(op Op, vs string) {
*self = append(*self, NewInsVs(op, vs))
}
func (self *Program) Rtt(op Op, vt reflect.Type) {
*self = append(*self, NewInsVt(op, vt))
}
func (self *Program) Vp(op Op, vt reflect.Type, pv bool) {
*self = append(*self, NewInsVp(op, vt, pv))
}
func (self *Program) Vtab(op Op, vt reflect.Type, itab *rt.GoItab) {
*self = append(*self, NewInsVtab(op, vt, itab))
}
func (self Program) Disassemble() string {
nb := len(self)
tab := make([]bool, nb+1)
ret := make([]string, 0, nb+1)
/* prescan to get all the labels */
for _, ins := range self {
if ins.isBranch() {
tab[ins.Vi()] = true
}
}
/* disassemble each instruction */
for i, ins := range self {
if !tab[i] {
ret = append(ret, "\t"+ins.Disassemble())
} else {
ret = append(ret, fmt.Sprintf("L_%d:\n\t%s", i, ins.Disassemble()))
}
}
/* add the last label, if needed */
if tab[nb] {
ret = append(ret, fmt.Sprintf("L_%d:", nb))
}
/* add an "end" indicator, and join all the strings */
return strings.Join(append(ret, "\tend"), "\n")
}

View file

@ -1,193 +0,0 @@
/*
* 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 encoder
import (
`bytes`
`sync`
`unsafe`
`errors`
`reflect`
`github.com/bytedance/sonic/internal/caching`
`github.com/bytedance/sonic/option`
`github.com/bytedance/sonic/internal/rt`
)
const (
_MaxStack = 4096 // 4k states
_StackSize = unsafe.Sizeof(_Stack{})
)
var (
bytesPool = sync.Pool{}
stackPool = sync.Pool{}
bufferPool = sync.Pool{}
programCache = caching.CreateProgramCache()
)
type _State struct {
x int
f uint64
p unsafe.Pointer
q unsafe.Pointer
}
type _Stack struct {
sp uint64
sb [_MaxStack]_State
}
type _Encoder func(
rb *[]byte,
vp unsafe.Pointer,
sb *_Stack,
fv uint64,
) error
var _KeepAlive struct {
rb *[]byte
vp unsafe.Pointer
sb *_Stack
fv uint64
err error
frame [_FP_offs]byte
}
var errCallShadow = errors.New("DON'T CALL THIS!")
// Faker func of _Encoder, used to export its stackmap as _Encoder's
func _Encoder_Shadow(rb *[]byte, vp unsafe.Pointer, sb *_Stack, fv uint64) (err error) {
// align to assembler_amd64.go: _FP_offs
var frame [_FP_offs]byte
// must keep all args and frames noticeable to GC
_KeepAlive.rb = rb
_KeepAlive.vp = vp
_KeepAlive.sb = sb
_KeepAlive.fv = fv
_KeepAlive.err = err
_KeepAlive.frame = frame
return errCallShadow
}
func newBytes() []byte {
if ret := bytesPool.Get(); ret != nil {
return ret.([]byte)
} else {
return make([]byte, 0, option.DefaultEncoderBufferSize)
}
}
func newStack() *_Stack {
if ret := stackPool.Get(); ret == nil {
return new(_Stack)
} else {
return ret.(*_Stack)
}
}
func resetStack(p *_Stack) {
memclrNoHeapPointers(unsafe.Pointer(p), _StackSize)
}
func newBuffer() *bytes.Buffer {
if ret := bufferPool.Get(); ret != nil {
return ret.(*bytes.Buffer)
} else {
return bytes.NewBuffer(make([]byte, 0, option.DefaultEncoderBufferSize))
}
}
func freeBytes(p []byte) {
p = p[:0]
bytesPool.Put(p)
}
func freeStack(p *_Stack) {
p.sp = 0
stackPool.Put(p)
}
func freeBuffer(p *bytes.Buffer) {
p.Reset()
bufferPool.Put(p)
}
func makeEncoder(vt *rt.GoType, ex ...interface{}) (interface{}, error) {
if pp, err := newCompiler().compile(vt.Pack(), ex[0].(bool)); err != nil {
return nil, err
} else {
as := newAssembler(pp)
as.name = vt.String()
return as.Load(), nil
}
}
func findOrCompile(vt *rt.GoType, pv bool) (_Encoder, error) {
if val := programCache.Get(vt); val != nil {
return val.(_Encoder), nil
} else if ret, err := programCache.Compute(vt, makeEncoder, pv); err == nil {
return ret.(_Encoder), nil
} else {
return nil, err
}
}
func pretouchType(_vt reflect.Type, opts option.CompileOptions, v uint8) (map[reflect.Type]uint8, error) {
/* compile function */
compiler := newCompiler().apply(opts)
encoder := func(vt *rt.GoType, ex ...interface{}) (interface{}, error) {
if pp, err := compiler.compile(_vt, ex[0].(bool)); err != nil {
return nil, err
} else {
as := newAssembler(pp)
as.name = vt.String()
return as.Load(), nil
}
}
/* find or compile */
vt := rt.UnpackType(_vt)
if val := programCache.Get(vt); val != nil {
return nil, nil
} else if _, err := programCache.Compute(vt, encoder, v == 1); err == nil {
return compiler.rec, nil
} else {
return nil, err
}
}
func pretouchRec(vtm map[reflect.Type]uint8, opts option.CompileOptions) error {
if opts.RecursiveDepth < 0 || len(vtm) == 0 {
return nil
}
next := make(map[reflect.Type]uint8)
for vt, v := range vtm {
sub, err := pretouchType(vt, opts, v)
if err != nil {
return err
}
for svt, v := range sub {
next[svt] = v
}
}
opts.RecursiveDepth -= 1
return pretouchRec(next, opts)
}

View file

@ -0,0 +1,97 @@
/*
* 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 encoder
import (
"errors"
"reflect"
"unsafe"
"github.com/bytedance/sonic/internal/encoder/vars"
"github.com/bytedance/sonic/internal/encoder/x86"
"github.com/bytedance/sonic/internal/rt"
"github.com/bytedance/sonic/option"
)
func ForceUseJit() {
x86.SetCompiler(makeEncoderX86)
pretouchType = pretouchTypeX86
encodeTypedPointer = x86.EncodeTypedPointer
vars.UseVM = false
}
func init() {
if vars.UseVM {
ForceUseVM()
} else {
ForceUseJit()
}
}
var _KeepAlive struct {
rb *[]byte
vp unsafe.Pointer
sb *vars.Stack
fv uint64
err error
frame [x86.FP_offs]byte
}
var errCallShadow = errors.New("DON'T CALL THIS!")
// Faker func of _Encoder, used to export its stackmap as _Encoder's
func _Encoder_Shadow(rb *[]byte, vp unsafe.Pointer, sb *vars.Stack, fv uint64) (err error) {
// align to assembler_amd64.go: x86.FP_offs
var frame [x86.FP_offs]byte
// must keep all args and frames noticeable to GC
_KeepAlive.rb = rb
_KeepAlive.vp = vp
_KeepAlive.sb = sb
_KeepAlive.fv = fv
_KeepAlive.err = err
_KeepAlive.frame = frame
return errCallShadow
}
func makeEncoderX86(vt *rt.GoType, ex ...interface{}) (interface{}, error) {
pp, err := NewCompiler().Compile(vt.Pack(), ex[0].(bool))
if err != nil {
return nil, err
}
as := x86.NewAssembler(pp)
as.Name = vt.String()
return as.Load(), nil
}
func pretouchTypeX86(_vt reflect.Type, opts option.CompileOptions, v uint8) (map[reflect.Type]uint8, error) {
/* compile function */
compiler := NewCompiler().apply(opts)
/* find or compile */
vt := rt.UnpackType(_vt)
if val := vars.GetProgram(vt); val != nil {
return nil, nil
} else if _, err := vars.ComputeProgram(vt, makeEncoderX86, v == 1); err == nil {
return compiler.rec, nil
} else {
return nil, err
}
}

View file

@ -0,0 +1,24 @@
//go:build !amd64
// +build !amd64
/*
* 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 encoder
func init() {
ForceUseVM()
}

View file

@ -1,167 +0,0 @@
/*
* 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 encoder
import (
`encoding`
`encoding/json`
`unsafe`
`github.com/bytedance/sonic/internal/jit`
`github.com/bytedance/sonic/internal/native`
`github.com/bytedance/sonic/internal/native/types`
`github.com/bytedance/sonic/internal/rt`
)
/** Encoder Primitives **/
func encodeNil(rb *[]byte) error {
*rb = append(*rb, 'n', 'u', 'l', 'l')
return nil
}
func encodeString(buf *[]byte, val string) error {
var sidx int
var pbuf *rt.GoSlice
var pstr *rt.GoString
/* opening quote */
*buf = append(*buf, '"')
pbuf = (*rt.GoSlice)(unsafe.Pointer(buf))
pstr = (*rt.GoString)(unsafe.Pointer(&val))
/* encode with native library */
for sidx < pstr.Len {
sn := pstr.Len - sidx
dn := pbuf.Cap - pbuf.Len
sp := padd(pstr.Ptr, sidx)
dp := padd(pbuf.Ptr, pbuf.Len)
nb := native.Quote(sp, sn, dp, &dn, 0)
/* check for errors */
if pbuf.Len += dn; nb >= 0 {
break
}
/* not enough space, grow the slice and try again */
sidx += ^nb
*pbuf = growslice(rt.UnpackType(byteType), *pbuf, pbuf.Cap * 2)
}
/* closing quote */
*buf = append(*buf, '"')
return nil
}
func encodeTypedPointer(buf *[]byte, vt *rt.GoType, vp *unsafe.Pointer, sb *_Stack, fv uint64) error {
if vt == nil {
return encodeNil(buf)
} else if fn, err := findOrCompile(vt, (fv&(1<<bitPointerValue)) != 0); err != nil {
return err
} else if vt.Indirect() {
rt.MoreStack(_FP_size + native.MaxFrameSize)
err := fn(buf, *vp, sb, fv)
return err
} else {
rt.MoreStack(_FP_size + native.MaxFrameSize)
err := fn(buf, unsafe.Pointer(vp), sb, fv)
return err
}
}
func encodeJsonMarshaler(buf *[]byte, val json.Marshaler, opt Options) error {
if ret, err := val.MarshalJSON(); err != nil {
return err
} else {
if opt & CompactMarshaler != 0 {
return compact(buf, ret)
}
if opt & NoValidateJSONMarshaler == 0 {
if ok, s := Valid(ret); !ok {
return error_marshaler(ret, s)
}
}
*buf = append(*buf, ret...)
return nil
}
}
func encodeTextMarshaler(buf *[]byte, val encoding.TextMarshaler, opt Options) error {
if ret, err := val.MarshalText(); err != nil {
return err
} else {
if opt & NoQuoteTextMarshaler != 0 {
*buf = append(*buf, ret...)
return nil
}
return encodeString(buf, rt.Mem2Str(ret) )
}
}
func htmlEscape(dst []byte, src []byte) []byte {
var sidx int
dst = append(dst, src[:0]...) // avoid check nil dst
sbuf := (*rt.GoSlice)(unsafe.Pointer(&src))
dbuf := (*rt.GoSlice)(unsafe.Pointer(&dst))
/* grow dst if it is shorter */
if cap(dst) - len(dst) < len(src) + types.BufPaddingSize {
cap := len(src) * 3 / 2 + types.BufPaddingSize
*dbuf = growslice(typeByte, *dbuf, cap)
}
for sidx < sbuf.Len {
sp := padd(sbuf.Ptr, sidx)
dp := padd(dbuf.Ptr, dbuf.Len)
sn := sbuf.Len - sidx
dn := dbuf.Cap - dbuf.Len
nb := native.HTMLEscape(sp, sn, dp, &dn)
/* check for errors */
if dbuf.Len += dn; nb >= 0 {
break
}
/* not enough space, grow the slice and try again */
sidx += ^nb
*dbuf = growslice(typeByte, *dbuf, dbuf.Cap * 2)
}
return dst
}
var (
argPtrs = []bool { true, true, true, false }
localPtrs = []bool{}
)
var (
_F_assertI2I = jit.Func(rt.AssertI2I2)
)
func asText(v unsafe.Pointer) (string, error) {
text := rt.AssertI2I2(_T_encoding_TextMarshaler, *(*rt.GoIface)(v))
r, e := (*(*encoding.TextMarshaler)(unsafe.Pointer(&text))).MarshalText()
return rt.Mem2Str(r), e
}
func asJson(v unsafe.Pointer) (string, error) {
text := rt.AssertI2I2(_T_json_Marshaler, *(*rt.GoIface)(v))
r, e := (*(*json.Marshaler)(unsafe.Pointer(&text))).MarshalJSON()
return rt.Mem2Str(r), e
}

View file

@ -17,8 +17,10 @@
package encoder
import (
`encoding/json`
`io`
"encoding/json"
"io"
"github.com/bytedance/sonic/internal/encoder/vars"
)
// StreamEncoder uses io.Writer as input.
@ -36,21 +38,20 @@ func NewStreamEncoder(w io.Writer) *StreamEncoder {
// Encode encodes interface{} as JSON to io.Writer
func (enc *StreamEncoder) Encode(val interface{}) (err error) {
buf := newBytes()
out := buf
out := vars.NewBytes()
/* encode into the buffer */
err = EncodeInto(&out, val, enc.Opts)
err = EncodeInto(out, val, enc.Opts)
if err != nil {
goto free_bytes
}
if enc.indent != "" || enc.prefix != "" {
/* indent the JSON */
buf := newBuffer()
err = json.Indent(buf, out, enc.prefix, enc.indent)
buf := vars.NewBuffer()
err = json.Indent(buf, *out, enc.prefix, enc.indent)
if err != nil {
freeBuffer(buf)
vars.FreeBuffer(buf)
goto free_bytes
}
@ -62,16 +63,17 @@ func (enc *StreamEncoder) Encode(val interface{}) (err error) {
/* copy into io.Writer */
_, err = io.Copy(enc.w, buf)
if err != nil {
freeBuffer(buf)
vars.FreeBuffer(buf)
goto free_bytes
}
} else {
/* copy into io.Writer */
var n int
for len(out) > 0 {
n, err = enc.w.Write(out)
out = out[n:]
buf := *out
for len(buf) > 0 {
n, err = enc.w.Write(buf)
buf = buf[n:]
if err != nil {
goto free_bytes
}
@ -84,6 +86,6 @@ func (enc *StreamEncoder) Encode(val interface{}) (err error) {
}
free_bytes:
freeBytes(buf)
vars.FreeBytes(out)
return err
}

View file

@ -1,61 +0,0 @@
// +build go1.16,!go1.17
/*
* 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 encoder
import (
`unsafe`
_ `github.com/cloudwego/base64x`
`github.com/bytedance/sonic/internal/rt`
)
//go:linkname _subr__b64encode github.com/cloudwego/base64x._subr__b64encode
var _subr__b64encode uintptr
//go:noescape
//go:linkname memmove runtime.memmove
//goland:noinspection GoUnusedParameter
func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)
//go:linkname growslice runtime.growslice
//goland:noinspection GoUnusedParameter
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
//go:linkname mapiternext runtime.mapiternext
//goland:noinspection GoUnusedParameter
func mapiternext(it *rt.GoMapIterator)
//go:linkname mapiterinit runtime.mapiterinit
//goland:noinspection GoUnusedParameter
func mapiterinit(t *rt.GoMapType, m *rt.GoMap, it *rt.GoMapIterator)
//go:linkname isValidNumber encoding/json.isValidNumber
//goland:noinspection GoUnusedParameter
func isValidNumber(s string) bool
//go:noescape
//go:linkname memclrNoHeapPointers runtime.memclrNoHeapPointers
//goland:noinspection GoUnusedParameter
func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
var _runtime_writeBarrier uintptr = rt.GcwbAddr()
//go:linkname gcWriteBarrierAX runtime.gcWriteBarrier
func gcWriteBarrierAX()

View file

@ -1,62 +0,0 @@
// +build go1.17,!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 encoder
import (
`unsafe`
_ `github.com/cloudwego/base64x`
`github.com/bytedance/sonic/internal/rt`
)
//go:linkname _subr__b64encode github.com/cloudwego/base64x._subr__b64encode
var _subr__b64encode uintptr
//go:noescape
//go:linkname memmove runtime.memmove
//goland:noinspection GoUnusedParameter
func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)
//go:linkname growslice runtime.growslice
//goland:noinspection GoUnusedParameter
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
//go:linkname mapiternext runtime.mapiternext
//goland:noinspection GoUnusedParameter
func mapiternext(it *rt.GoMapIterator)
//go:linkname mapiterinit runtime.mapiterinit
//goland:noinspection GoUnusedParameter
func mapiterinit(t *rt.GoMapType, m *rt.GoMap, it *rt.GoMapIterator)
//go:linkname isValidNumber encoding/json.isValidNumber
//goland:noinspection GoUnusedParameter
func isValidNumber(s string) bool
//go:noescape
//go:linkname memclrNoHeapPointers runtime.memclrNoHeapPointers
//goland:noinspection GoUnusedParameter
func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
//go:linkname _runtime_writeBarrier runtime.writeBarrier
var _runtime_writeBarrier uintptr
//go:linkname gcWriteBarrierAX runtime.gcWriteBarrier
func gcWriteBarrierAX()

View file

@ -1,62 +0,0 @@
// +build go1.20,!go1.21
/*
* 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 encoder
import (
`unsafe`
_ `github.com/cloudwego/base64x`
`github.com/bytedance/sonic/internal/rt`
)
//go:linkname _subr__b64encode github.com/cloudwego/base64x._subr__b64encode
var _subr__b64encode uintptr
//go:noescape
//go:linkname memmove runtime.memmove
//goland:noinspection GoUnusedParameter
func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)
//go:linkname growslice reflect.growslice
//goland:noinspection GoUnusedParameter
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
//go:linkname mapiternext runtime.mapiternext
//goland:noinspection GoUnusedParameter
func mapiternext(it *rt.GoMapIterator)
//go:linkname mapiterinit runtime.mapiterinit
//goland:noinspection GoUnusedParameter
func mapiterinit(t *rt.GoMapType, m *rt.GoMap, it *rt.GoMapIterator)
//go:linkname isValidNumber encoding/json.isValidNumber
//goland:noinspection GoUnusedParameter
func isValidNumber(s string) bool
//go:noescape
//go:linkname memclrNoHeapPointers runtime.memclrNoHeapPointers
//goland:noinspection GoUnusedParameter
func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
//go:linkname _runtime_writeBarrier runtime.writeBarrier
var _runtime_writeBarrier uintptr
//go:linkname gcWriteBarrierAX runtime.gcWriteBarrier
func gcWriteBarrierAX()

View file

@ -1,62 +0,0 @@
// +build go1.21
/*
* 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 encoder
import (
`unsafe`
_ `github.com/cloudwego/base64x`
`github.com/bytedance/sonic/internal/rt`
)
//go:linkname _subr__b64encode github.com/cloudwego/base64x._subr__b64encode
var _subr__b64encode uintptr
//go:noescape
//go:linkname memmove runtime.memmove
//goland:noinspection GoUnusedParameter
func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)
//go:linkname growslice reflect.growslice
//goland:noinspection GoUnusedParameter
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
//go:linkname mapiternext runtime.mapiternext
//goland:noinspection GoUnusedParameter
func mapiternext(it *rt.GoMapIterator)
//go:linkname mapiterinit runtime.mapiterinit
//goland:noinspection GoUnusedParameter
func mapiterinit(t *rt.GoMapType, m *rt.GoMap, it *rt.GoMapIterator)
//go:linkname isValidNumber encoding/json.isValidNumber
//goland:noinspection GoUnusedParameter
func isValidNumber(s string) bool
//go:noescape
//go:linkname memclrNoHeapPointers runtime.memclrNoHeapPointers
//goland:noinspection GoUnusedParameter
func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
//go:linkname _runtime_writeBarrier runtime.writeBarrier
var _runtime_writeBarrier uintptr
//go:linkname gcWriteBarrier2 runtime.gcWriteBarrier2
func gcWriteBarrier2()

View file

@ -1,52 +0,0 @@
/*
* 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 encoder
import (
`encoding/json`
`unsafe`
`github.com/bytedance/sonic/loader`
)
//go:nosplit
func padd(p unsafe.Pointer, v int) unsafe.Pointer {
return unsafe.Pointer(uintptr(p) + uintptr(v))
}
//go:nosplit
func ptoenc(p loader.Function) _Encoder {
return *(*_Encoder)(unsafe.Pointer(&p))
}
func compact(p *[]byte, v []byte) error {
buf := newBuffer()
err := json.Compact(buf, v)
/* check for errors */
if err != nil {
return err
}
/* add to result */
v = buf.Bytes()
*p = append(*p, v...)
/* return the buffer into pool */
freeBuffer(buf)
return nil
}

View file

@ -0,0 +1,48 @@
/*
* 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 vars
import (
"unsafe"
"github.com/bytedance/sonic/internal/rt"
)
type Encoder func(
rb *[]byte,
vp unsafe.Pointer,
sb *Stack,
fv uint64,
) error
func FindOrCompile(vt *rt.GoType, pv bool, compiler func(*rt.GoType, ... interface{}) (interface{}, error)) (interface{}, error) {
if val := programCache.Get(vt); val != nil {
return val, nil
} else if ret, err := programCache.Compute(vt, compiler, pv); err == nil {
return ret, nil
} else {
return nil, err
}
}
func GetProgram(vt *rt.GoType) (interface{}) {
return programCache.Get(vt)
}
func ComputeProgram(vt *rt.GoType, compute func(*rt.GoType, ... interface{}) (interface{}, error), pv bool) (interface{}, error) {
return programCache.Compute(vt, compute, pv)
}

View file

@ -0,0 +1,42 @@
/**
* Copyright 2024 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 vars
import (
"os"
"unsafe"
)
const (
MaxStack = 4096 // 4k states
StackSize = unsafe.Sizeof(Stack{})
StateSize = int64(unsafe.Sizeof(State{}))
StackLimit = MaxStack * StateSize
)
const (
MAX_ILBUF = 100000 // cutoff at 100k of IL instructions
MAX_FIELDS = 50 // cutoff at 50 fields struct
)
var (
DebugSyncGC = os.Getenv("SONIC_SYNC_GC") != ""
DebugAsyncGC = os.Getenv("SONIC_NO_ASYNC_GC") == ""
DebugCheckPtr = os.Getenv("SONIC_CHECK_POINTER") != ""
)
var UseVM = os.Getenv("SONIC_ENCODER_USE_VM") != ""

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package encoder
package vars
import (
`encoding/json`
@ -26,39 +26,39 @@ import (
`github.com/bytedance/sonic/internal/rt`
)
var _ERR_too_deep = &json.UnsupportedValueError {
var ERR_too_deep = &json.UnsupportedValueError {
Str : "Value nesting too deep",
Value : reflect.ValueOf("..."),
}
var _ERR_nan_or_infinite = &json.UnsupportedValueError {
var ERR_nan_or_infinite = &json.UnsupportedValueError {
Str : "NaN or ±Infinite",
Value : reflect.ValueOf("NaN or ±Infinite"),
}
func error_type(vtype reflect.Type) error {
func Error_type(vtype reflect.Type) error {
return &json.UnsupportedTypeError{Type: vtype}
}
func error_number(number json.Number) error {
func Error_number(number json.Number) error {
return &json.UnsupportedValueError {
Str : "invalid number literal: " + strconv.Quote(string(number)),
Value : reflect.ValueOf(number),
}
}
func error_marshaler(ret []byte, pos int) error {
func Error_marshaler(ret []byte, pos int) error {
return fmt.Errorf("invalid Marshaler output json syntax at %d: %q", pos, ret)
}
const (
panicNilPointerOfNonEmptyString int = 1 + iota
PanicNilPointerOfNonEmptyString int = 1 + iota
)
func goPanic(code int, val unsafe.Pointer) {
func GoPanic(code int, val unsafe.Pointer) {
switch(code){
case panicNilPointerOfNonEmptyString:
panic(fmt.Sprintf("val: %#v has nil pointer while its length is not zero!", (*rt.GoString)(val)))
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)))
default:
panic("encoder error!")
}

View file

@ -0,0 +1,146 @@
/**
* Copyright 2024 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 vars
import (
"bytes"
"sync"
"unsafe"
"github.com/bytedance/sonic/internal/caching"
"github.com/bytedance/sonic/internal/rt"
"github.com/bytedance/sonic/option"
)
type State struct {
x int
f uint64
p unsafe.Pointer
q unsafe.Pointer
}
type Stack struct {
sp uintptr
sb [MaxStack]State
}
var (
bytesPool = sync.Pool{}
stackPool = sync.Pool{
New: func() interface{} {
return &Stack{}
},
}
bufferPool = sync.Pool{}
programCache = caching.CreateProgramCache()
)
func NewBytes() *[]byte {
if ret := bytesPool.Get(); ret != nil {
return ret.(*[]byte)
} else {
ret := make([]byte, 0, option.DefaultEncoderBufferSize)
return &ret
}
}
func NewStack() *Stack {
ret := stackPool.Get().(*Stack)
ret.sp = 0
return ret
}
func ResetStack(p *Stack) {
rt.MemclrNoHeapPointers(unsafe.Pointer(p), StackSize)
}
func (s *Stack) Top() *State {
return (*State)(rt.Add(unsafe.Pointer(&s.sb[0]), s.sp))
}
func (s *Stack) Cur() *State {
return (*State)(rt.Add(unsafe.Pointer(&s.sb[0]), s.sp - uintptr(StateSize)))
}
const _MaxStackSP = uintptr(MaxStack * StateSize)
func (s *Stack) Push(v State) bool {
if uintptr(s.sp) >= _MaxStackSP {
return false
}
st := s.Top()
*st = v
s.sp += uintptr(StateSize)
return true
}
func (s *Stack) Pop() State {
s.sp -= uintptr(StateSize)
st := s.Top()
ret := *st
*st = State{}
return ret
}
func (s *Stack) Load() (int, uint64, unsafe.Pointer, unsafe.Pointer) {
st := s.Cur()
return st.x, st.f, st.p, st.q
}
func (s *Stack) Save(x int, f uint64, p unsafe.Pointer, q unsafe.Pointer) bool {
return s.Push(State{x: x, f:f, p: p, q: q})
}
func (s *Stack) Drop() (int, uint64, unsafe.Pointer, unsafe.Pointer) {
st := s.Pop()
return st.x, st.f, st.p, st.q
}
func NewBuffer() *bytes.Buffer {
if ret := bufferPool.Get(); ret != nil {
return ret.(*bytes.Buffer)
} else {
return bytes.NewBuffer(make([]byte, 0, option.DefaultEncoderBufferSize))
}
}
func FreeBytes(p *[]byte) {
if rt.CanSizeResue(cap(*p)) {
(*p) = (*p)[:0]
bytesPool.Put(p)
}
}
func FreeStack(p *Stack) {
p.sp = 0
stackPool.Put(p)
}
func FreeBuffer(p *bytes.Buffer) {
if rt.CanSizeResue(cap(p.Bytes())) {
p.Reset()
bufferPool.Put(p)
}
}
var (
ArgPtrs = []bool{true, true, true, false}
LocalPtrs = []bool{}
ArgPtrs_generic = []bool{true}
LocalPtrs_generic = []bool{}
)

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package encoder
package vars
import (
`encoding`
@ -23,19 +23,19 @@ import (
)
var (
byteType = reflect.TypeOf(byte(0))
jsonNumberType = reflect.TypeOf(json.Number(""))
jsonUnsupportedValueType = reflect.TypeOf(new(json.UnsupportedValueError))
ByteType = reflect.TypeOf(byte(0))
JsonNumberType = reflect.TypeOf(json.Number(""))
JsonUnsupportedValueType = reflect.TypeOf(new(json.UnsupportedValueError))
)
var (
errorType = reflect.TypeOf((*error)(nil)).Elem()
jsonMarshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
encodingTextMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
ErrorType = reflect.TypeOf((*error)(nil)).Elem()
JsonMarshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
EncodingTextMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
)
func isSimpleByte(vt reflect.Type) bool {
if vt.Kind() != byteType.Kind() {
func IsSimpleByte(vt reflect.Type) bool {
if vt.Kind() != ByteType.Kind() {
return false
} else {
return !isEitherMarshaler(vt) && !isEitherMarshaler(reflect.PtrTo(vt))
@ -43,5 +43,5 @@ func isSimpleByte(vt reflect.Type) bool {
}
func isEitherMarshaler(vt reflect.Type) bool {
return vt.Implements(jsonMarshalerType) || vt.Implements(encodingTextMarshalerType)
return vt.Implements(JsonMarshalerType) || vt.Implements(EncodingTextMarshalerType)
}

View file

@ -0,0 +1,45 @@
/**
* Copyright 2024 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 vm
import (
"unsafe"
_ "unsafe"
"github.com/bytedance/sonic/internal/encoder/alg"
"github.com/bytedance/sonic/internal/encoder/ir"
"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)
} else if pp, err := vars.FindOrCompile(vt, (fv&(1<<alg.BitPointerValue)) != 0, compiler); err != nil {
return err
} else if vt.Indirect() {
return Execute(buf, *vp, sb, fv, pp.(*ir.Program))
} else {
return Execute(buf, unsafe.Pointer(vp), sb, fv, pp.(*ir.Program))
}
}
var compiler func(*rt.GoType, ... interface{}) (interface{}, error)
func SetCompiler(c func(*rt.GoType, ... interface{}) (interface{}, error)) {
compiler = c
}

View file

@ -0,0 +1,374 @@
// 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
//
// 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 vm
import (
"encoding"
"encoding/json"
"fmt"
"math"
"reflect"
"unsafe"
"github.com/bytedance/sonic/internal/encoder/alg"
"github.com/bytedance/sonic/internal/encoder/ir"
"github.com/bytedance/sonic/internal/encoder/vars"
"github.com/bytedance/sonic/internal/rt"
"github.com/bytedance/sonic/internal/base64"
)
const (
_S_cond = iota
_S_init
)
var (
_T_json_Marshaler = rt.UnpackType(vars.JsonMarshalerType)
_T_encoding_TextMarshaler = rt.UnpackType(vars.EncodingTextMarshalerType)
)
func print_instr(buf []byte, pc int, op ir.Op, ins *ir.Instr, p unsafe.Pointer) {
if len(buf) > 20 {
fmt.Println(string(buf[len(buf)-20:]))
} else {
fmt.Println(string(buf))
}
fmt.Printf("pc %04d, op %v, ins %#v, ptr: %x\n", pc, op, ins.Disassemble(), p)
}
func Execute(b *[]byte, p unsafe.Pointer, s *vars.Stack, flags uint64, prog *ir.Program) (error) {
pl := len(*prog)
if pl <= 0 {
return nil
}
var buf = *b
var x int
var q unsafe.Pointer
var f uint64
var pro = &(*prog)[0]
for pc := 0; pc < pl; {
ins := (*ir.Instr)(rt.Add(unsafe.Pointer(pro), ir.OpSize*uintptr(pc)))
pc++
op := ins.Op()
switch op {
case ir.OP_goto:
pc = ins.Vi()
continue
case ir.OP_byte:
v := ins.Byte()
buf = append(buf, v)
case ir.OP_text:
v := ins.Vs()
buf = append(buf, v...)
case ir.OP_deref:
p = *(*unsafe.Pointer)(p)
case ir.OP_index:
p = rt.Add(p, uintptr(ins.I64()))
case ir.OP_load:
// NOTICE: load CANNOT change f!
x, _, p, q = s.Load()
case ir.OP_save:
if !s.Save(x, f, p, q) {
return vars.ERR_too_deep
}
case ir.OP_drop:
x, f, p, q = s.Drop()
case ir.OP_drop_2:
s.Drop()
x, f, p, q = s.Drop()
case ir.OP_recurse:
vt, pv := ins.Vp2()
f := flags
if pv {
f |= (1 << alg.BitPointerValue)
}
*b = buf
if vt.Indirect() {
if err := EncodeTypedPointer(b, vt, (*unsafe.Pointer)(rt.NoEscape(unsafe.Pointer(&p))), s, f); err != nil {
return err
}
} else {
vp := (*unsafe.Pointer)(p)
if err := EncodeTypedPointer(b, vt, vp, s, f); err != nil {
return err
}
}
buf = *b
case ir.OP_is_nil:
if is_nil(p) {
pc = ins.Vi()
continue
}
case ir.OP_is_nil_p1:
if (*rt.GoEface)(p).Value == nil {
pc = ins.Vi()
continue
}
case ir.OP_null:
buf = append(buf, 'n', 'u', 'l', 'l')
case ir.OP_str:
v := *(*string)(p)
buf = alg.Quote(buf, v, false)
case ir.OP_bool:
if *(*bool)(p) {
buf = append(buf, 't', 'r', 'u', 'e')
} else {
buf = append(buf, 'f', 'a', 'l', 's', 'e')
}
case ir.OP_i8:
v := *(*int8)(p)
buf = alg.I64toa(buf, int64(v))
case ir.OP_i16:
v := *(*int16)(p)
buf = alg.I64toa(buf, int64(v))
case ir.OP_i32:
v := *(*int32)(p)
buf = alg.I64toa(buf, int64(v))
case ir.OP_i64:
v := *(*int64)(p)
buf = alg.I64toa(buf, int64(v))
case ir.OP_u8:
v := *(*uint8)(p)
buf = alg.U64toa(buf, uint64(v))
case ir.OP_u16:
v := *(*uint16)(p)
buf = alg.U64toa(buf, uint64(v))
case ir.OP_u32:
v := *(*uint32)(p)
buf = alg.U64toa(buf, uint64(v))
case ir.OP_u64:
v := *(*uint64)(p)
buf = alg.U64toa(buf, uint64(v))
case ir.OP_f32:
v := *(*float32)(p)
if math.IsNaN(float64(v)) || math.IsInf(float64(v), 0) {
if flags&(1<<alg.BitEncodeNullForInfOrNan) != 0 {
buf = append(buf, 'n', 'u', 'l', 'l')
continue
}
return vars.ERR_nan_or_infinite
}
buf = alg.F32toa(buf, v)
case ir.OP_f64:
v := *(*float64)(p)
if math.IsNaN(v) || math.IsInf(v, 0) {
if flags&(1<<alg.BitEncodeNullForInfOrNan) != 0 {
buf = append(buf, 'n', 'u', 'l', 'l')
continue
}
return vars.ERR_nan_or_infinite
}
buf = alg.F64toa(buf, v)
case ir.OP_bin:
v := *(*[]byte)(p)
buf = base64.EncodeBase64(buf, v)
case ir.OP_quote:
v := *(*string)(p)
buf = alg.Quote(buf, v, true)
case ir.OP_number:
v := *(*json.Number)(p)
if v == "" {
buf = append(buf, '0')
} else if !rt.IsValidNumber(string(v)) {
return vars.Error_number(v)
} else {
buf = append(buf, v...)
}
case ir.OP_eface:
*b = buf
if err := EncodeTypedPointer(b, *(**rt.GoType)(p), (*unsafe.Pointer)(rt.Add(p, 8)), s, flags); err != nil {
return err
}
buf = *b
case ir.OP_iface:
*b = buf
if err := EncodeTypedPointer(b, (*(**rt.GoItab)(p)).Vt, (*unsafe.Pointer)(rt.Add(p, 8)), s, flags); err != nil {
return err
}
buf = *b
case ir.OP_is_zero_map:
v := *(**rt.GoMap)(p)
if v == nil || v.Count == 0 {
pc = ins.Vi()
continue
}
case ir.OP_map_iter:
v := *(**rt.GoMap)(p)
vt := ins.Vr()
it, err := alg.IteratorStart(rt.MapType(vt), v, flags)
if err != nil {
return err
}
q = unsafe.Pointer(it)
case ir.OP_map_stop:
it := (*alg.MapIterator)(q)
alg.IteratorStop(it)
q = nil
case ir.OP_map_value_next:
it := (*alg.MapIterator)(q)
p = it.It.V
alg.IteratorNext(it)
case ir.OP_map_check_key:
it := (*alg.MapIterator)(q)
if it.It.K == nil {
pc = ins.Vi()
continue
}
p = it.It.K
case ir.OP_marshal_text:
vt, itab := ins.Vtab()
var it rt.GoIface
switch vt.Kind() {
case reflect.Interface :
if is_nil(p) {
buf = append(buf, 'n', 'u', 'l', 'l')
continue
}
it = rt.AssertI2I(_T_encoding_TextMarshaler, *(*rt.GoIface)(p))
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 {
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 {
return err
}
case ir.OP_map_write_key:
if has_opts(flags, alg.BitSortMapKeys) {
v := *(*string)(p)
buf = alg.Quote(buf, v, false)
pc = ins.Vi()
continue
}
case ir.OP_slice_len:
v := (*rt.GoSlice)(p)
x = v.Len
p = v.Ptr
//TODO: why?
f |= 1<<_S_init
case ir.OP_slice_next:
if x == 0 {
pc = ins.Vi()
continue
}
x--
if has_opts(f, _S_init) {
f &= ^uint64(1 << _S_init)
} else {
p = rt.Add(p, uintptr(ins.Vlen()))
}
case ir.OP_cond_set:
f |= 1<<_S_cond
case ir.OP_cond_testc:
if has_opts(f, _S_cond) {
f &= ^uint64(1 << _S_cond)
pc = ins.Vi()
continue
}
case ir.OP_is_zero_1:
if *(*uint8)(p) == 0 {
pc = ins.Vi()
continue
}
case ir.OP_is_zero_2:
if *(*uint16)(p) == 0 {
pc = ins.Vi()
continue
}
case ir.OP_is_zero_4:
if *(*uint32)(p) == 0 {
pc = ins.Vi()
continue
}
case ir.OP_is_zero_8:
if *(*uint64)(p) == 0 {
pc = ins.Vi()
continue
}
case ir.OP_empty_arr:
if has_opts(flags, alg.BitNoNullSliceOrMap) {
buf = append(buf, '[', ']')
} else {
buf = append(buf, 'n', 'u', 'l', 'l')
}
case ir.OP_empty_obj:
if has_opts(flags, alg.BitNoNullSliceOrMap) {
buf = append(buf, '{', '}')
} else {
buf = append(buf, 'n', 'u', 'l', 'l')
}
case ir.OP_marshal:
vt, itab := ins.Vtab()
var it rt.GoIface
switch vt.Kind() {
case reflect.Interface :
if is_nil(p) {
buf = append(buf, 'n', 'u', 'l', 'l')
continue
}
it = rt.AssertI2I(_T_json_Marshaler, *(*rt.GoIface)(p))
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 {
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 {
return err
}
default:
panic(fmt.Sprintf("not implement %s at %d", ins.Op().String(), pc))
}
}
*b = buf
return nil
}
// func to_buf(w unsafe.Pointer, l int, c int) []byte {
// return rt.BytesFrom(unsafe.Pointer(uintptr(w)-uintptr(l)), l, c)
// }
// func from_buf(buf []byte) (unsafe.Pointer, int, int) {
// return rt.IndexByte(buf, len(buf)), len(buf), cap(buf)
// }
func has_opts(opts uint64, bit int) bool {
return opts & (1<<bit) != 0
}
func is_nil(p unsafe.Pointer) bool {
return *(*unsafe.Pointer)(p) == nil
}
func convT2I(ptr unsafe.Pointer, deref bool, itab *rt.GoItab) (rt.GoIface) {
if deref {
ptr = *(*unsafe.Pointer)(ptr)
}
return rt.GoIface{
Itab: itab,
Value: ptr,
}
}

View file

@ -1,3 +1,4 @@
//go:build go1.17 && !go1.21
// +build go1.17,!go1.21
// Copyright 2023 CloudWeGo Authors
@ -14,24 +15,25 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package encoder
package x86
import (
`strconv`
`unsafe`
"strconv"
"unsafe"
`github.com/bytedance/sonic/internal/jit`
`github.com/twitchyliquid64/golang-asm/obj`
`github.com/twitchyliquid64/golang-asm/obj/x86`
"github.com/bytedance/sonic/internal/jit"
"github.com/bytedance/sonic/internal/rt"
"github.com/twitchyliquid64/golang-asm/obj"
"github.com/twitchyliquid64/golang-asm/obj/x86"
)
var (
_V_writeBarrier = jit.Imm(int64(uintptr(unsafe.Pointer(&_runtime_writeBarrier))))
_V_writeBarrier = jit.Imm(int64(uintptr(unsafe.Pointer(&rt.RuntimeWriteBarrier))))
_F_gcWriteBarrierAX = jit.Func(gcWriteBarrierAX)
_F_gcWriteBarrierAX = jit.Func(rt.GcWriteBarrierAX)
)
func (self *_Assembler) WritePtr(i int, ptr obj.Addr, rec obj.Addr) {
func (self *Assembler) WritePtr(i int, ptr obj.Addr, rec obj.Addr) {
if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX {
panic("rec contains AX!")
}

View file

@ -1,4 +1,5 @@
// +build go1.21,!go1.23
//go:build go1.21 && !go1.24
// +build go1.21,!go1.24
// Copyright 2023 CloudWeGo Authors
//
@ -14,24 +15,25 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package encoder
package x86
import (
`strconv`
`unsafe`
"strconv"
"unsafe"
`github.com/bytedance/sonic/internal/jit`
`github.com/twitchyliquid64/golang-asm/obj`
`github.com/twitchyliquid64/golang-asm/obj/x86`
"github.com/bytedance/sonic/internal/jit"
"github.com/bytedance/sonic/internal/rt"
"github.com/twitchyliquid64/golang-asm/obj"
"github.com/twitchyliquid64/golang-asm/obj/x86"
)
var (
_V_writeBarrier = jit.Imm(int64(uintptr(unsafe.Pointer(&_runtime_writeBarrier))))
_V_writeBarrier = jit.Imm(int64(uintptr(unsafe.Pointer(&rt.RuntimeWriteBarrier))))
_F_gcWriteBarrier2 = jit.Func(gcWriteBarrier2)
_F_gcWriteBarrier2 = jit.Func(rt.GcWriteBarrier2)
)
func (self *_Assembler) WritePtr(i int, ptr obj.Addr, old obj.Addr) {
func (self *Assembler) WritePtr(i int, ptr obj.Addr, old obj.Addr) {
if old.Reg == x86.REG_AX || old.Index == x86.REG_AX {
panic("rec contains AX!")
}

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
// +build go1.16,!go1.17
// +build go1.17,!go1.17
/*
* Copyright 2021 ByteDance Inc.
@ -16,7 +16,7 @@
* limitations under the License.
*/
package encoder
package x86
import (
`os`

View file

@ -0,0 +1,201 @@
//go:build go1.17 && !go1.24
// +build go1.17,!go1.24
/*
* 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 x86
import (
"fmt"
"runtime"
"strings"
"unsafe"
"github.com/bytedance/sonic/internal/encoder/ir"
"github.com/bytedance/sonic/internal/encoder/vars"
"github.com/bytedance/sonic/internal/jit"
"github.com/twitchyliquid64/golang-asm/obj"
)
const _FP_debug = 128
var (
_Instr_End = ir.NewInsOp(ir.OP_is_nil)
_F_gc = jit.Func(gc)
_F_println = jit.Func(println_wrapper)
_F_print = jit.Func(print)
)
func (self *Assembler) dsave(r ...obj.Addr) {
for i, v := range r {
if i > _FP_debug/8-1 {
panic("too many registers to save")
} else {
self.Emit("MOVQ", v, jit.Ptr(_SP, _FP_fargs+_FP_saves+_FP_locals+int64(i)*8))
}
}
}
func (self *Assembler) dload(r ...obj.Addr) {
for i, v := range r {
if i > _FP_debug/8-1 {
panic("too many registers to load")
} else {
self.Emit("MOVQ", jit.Ptr(_SP, _FP_fargs+_FP_saves+_FP_locals+int64(i)*8), v)
}
}
}
func println_wrapper(i int, op1 int, op2 int) {
println(i, " Intrs ", op1, ir.OpNames[op1], "next: ", op2, ir.OpNames[op2])
}
func print(i int) {
println(i)
}
func gc() {
if !vars.DebugSyncGC {
return
}
runtime.GC()
// debug.FreeOSMemory()
}
func (self *Assembler) dcall(fn obj.Addr) {
self.Emit("MOVQ", fn, _R10) // MOVQ ${fn}, R10
self.Rjmp("CALL", _R10) // CALL R10
}
func (self *Assembler) debug_gc() {
if !vars.DebugSyncGC {
return
}
self.dsave(_REG_debug...)
self.dcall(_F_gc)
self.dload(_REG_debug...)
}
func (self *Assembler) debug_instr(i int, v *ir.Instr) {
if vars.DebugSyncGC {
if i+1 == len(self.p) {
self.print_gc(i, v, &_Instr_End)
} else {
next := &(self.p[i+1])
self.print_gc(i, v, next)
name := ir.OpNames[next.Op()]
if strings.Contains(name, "save") {
return
}
}
// self.debug_gc()
}
}
//go:noescape
//go:linkname checkptrBase runtime.checkptrBase
func checkptrBase(p unsafe.Pointer) uintptr
//go:noescape
//go:linkname findObject runtime.findObject
func findObject(p, refBase, refOff uintptr) (base uintptr, s unsafe.Pointer, objIndex uintptr)
var (
_F_checkptr = jit.Func(checkptr)
_F_printptr = jit.Func(printptr)
)
var (
_R10 = jit.Reg("R10")
)
var _REG_debug = []obj.Addr{
jit.Reg("AX"),
jit.Reg("BX"),
jit.Reg("CX"),
jit.Reg("DX"),
jit.Reg("DI"),
jit.Reg("SI"),
jit.Reg("BP"),
jit.Reg("SP"),
jit.Reg("R8"),
jit.Reg("R9"),
jit.Reg("R10"),
jit.Reg("R11"),
jit.Reg("R12"),
jit.Reg("R13"),
jit.Reg("R14"),
jit.Reg("R15"),
}
func checkptr(ptr uintptr) {
if ptr == 0 {
return
}
fmt.Printf("pointer: %x\n", ptr)
f := checkptrBase(unsafe.Pointer(uintptr(ptr)))
if f == 0 {
fmt.Printf("! unknown-based pointer: %x\n", ptr)
} else if f == 1 {
fmt.Printf("! stack pointer: %x\n", ptr)
} else {
fmt.Printf("base: %x\n", f)
}
findobj(ptr)
}
func findobj(ptr uintptr) {
base, s, objIndex := findObject(ptr, 0, 0)
if s != nil && base == 0 {
fmt.Printf("! invalid pointer: %x\n", ptr)
}
fmt.Printf("objIndex: %d\n", objIndex)
}
func (self *Assembler) check_ptr(ptr obj.Addr, lea bool) {
if !vars.DebugCheckPtr {
return
}
self.dsave(_REG_debug...)
if lea {
self.Emit("LEAQ", ptr, _R10)
} else {
self.Emit("MOVQ", ptr, _R10)
}
self.Emit("MOVQ", _R10, jit.Ptr(_SP, 0))
self.dcall(_F_checkptr)
self.dload(_REG_debug...)
}
func printptr(i int, ptr uintptr) {
fmt.Printf("[%d] ptr: %x\n", i, ptr)
}
func (self *Assembler) print_ptr(i int, ptr obj.Addr, lea bool) {
self.dsave(_REG_debug...)
if lea {
self.Emit("LEAQ", ptr, _R10)
} else {
self.Emit("MOVQ", ptr, _R10)
}
self.Emit("MOVQ", jit.Imm(int64(i)), _AX)
self.Emit("MOVQ", _R10, _BX)
self.dcall(_F_printptr)
self.dload(_REG_debug...)
}

View file

@ -0,0 +1,54 @@
/**
* Copyright 2024 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 x86
import (
"unsafe"
_ "unsafe"
"github.com/bytedance/sonic/internal/encoder/alg"
"github.com/bytedance/sonic/internal/encoder/vars"
"github.com/bytedance/sonic/internal/rt"
"github.com/bytedance/sonic/loader"
_ "github.com/cloudwego/base64x"
)
//go:linkname _subr__b64encode github.com/cloudwego/base64x._subr__b64encode
var _subr__b64encode uintptr
var compiler func(*rt.GoType, ... interface{}) (interface{}, error)
func SetCompiler(c func(*rt.GoType, ... interface{}) (interface{}, error)) {
compiler = c
}
func ptoenc(p loader.Function) vars.Encoder {
return *(*vars.Encoder)(unsafe.Pointer(&p))
}
func EncodeTypedPointer(buf *[]byte, vt *rt.GoType, vp *unsafe.Pointer, sb *vars.Stack, fv uint64) error {
if vt == nil {
return alg.EncodeNil(buf)
} else if fn, err := vars.FindOrCompile(vt, (fv&(1<<alg.BitPointerValue)) != 0, compiler); err != nil {
return err
} else if vt.Indirect() {
return fn.(vars.Encoder)(buf, *vp, sb, fv)
} else {
return fn.(vars.Encoder)(buf, unsafe.Pointer(vp), sb, fv)
}
}

View file

@ -0,0 +1,24 @@
package envs
import (
"os"
)
var UseOptDec = os.Getenv("SONIC_USE_OPTDEC") == "1"
var UseFastMap = os.Getenv("SONIC_USE_FASTMAP") == "1"
func EnableOptDec() {
UseOptDec = true
}
func DisableOptDec() {
UseOptDec = false
}
func EnableFastMap() {
UseFastMap = true
}
func DisableFastMap() {
UseFastMap = false
}

View file

@ -37,7 +37,7 @@ func Type(t reflect.Type) obj.Addr {
}
func Itab(i *rt.GoType, t reflect.Type) obj.Addr {
return Imm(int64(uintptr(unsafe.Pointer(rt.Getitab(rt.IfaceType(i), rt.UnpackType(t), false)))))
return Imm(int64(uintptr(unsafe.Pointer(rt.GetItab(rt.IfaceType(i), rt.UnpackType(t), false)))))
}
func Gitab(i *rt.GoItab) obj.Addr {

View file

@ -1,44 +0,0 @@
// +build !noasm !appengine
// Code generated by asm2asm, DO NOT EDIT.
package avx
import (
`github.com/bytedance/sonic/loader`
)
const (
_entry__f32toa = 32
)
const (
_stack__f32toa = 48
)
const (
_size__f32toa = 3392
)
var (
_pcsp__f32toa = [][2]uint32{
{1, 0},
{4, 8},
{6, 16},
{8, 24},
{10, 32},
{12, 40},
{3350, 48},
{3351, 40},
{3353, 32},
{3355, 24},
{3357, 16},
{3359, 8},
{3363, 0},
{3385, 48},
}
)
var _cfunc_f32toa = []loader.CFunc{
{"_f32toa_entry", 0, _entry__f32toa, 0, nil},
{"_f32toa", _entry__f32toa, _size__f32toa, _stack__f32toa, _pcsp__f32toa},
}

View file

@ -1,964 +0,0 @@
// +build amd64
// Code generated by asm2asm, DO NOT EDIT.
package avx
var _text_f32toa = []byte{
// .p2align 5, 0x00
// LCPI0_0
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // QUAD $0x3030303030303030; QUAD $0x3030303030303030 // .space 16, '0000000000000000'
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, //0x00000010 QUAD $0x3030303030303030; QUAD $0x3030303030303030 // .space 16, '0000000000000000'
//0x00000020 .p2align 4, 0x90
//0x00000020 _f32toa
0x55, //0x00000020 pushq %rbp
0x48, 0x89, 0xe5, //0x00000021 movq %rsp, %rbp
0x41, 0x57, //0x00000024 pushq %r15
0x41, 0x56, //0x00000026 pushq %r14
0x41, 0x55, //0x00000028 pushq %r13
0x41, 0x54, //0x0000002a pushq %r12
0x53, //0x0000002c pushq %rbx
0xc5, 0xf9, 0x7e, 0xc0, //0x0000002d vmovd %xmm0, %eax
0x89, 0xc1, //0x00000031 movl %eax, %ecx
0xc1, 0xe9, 0x17, //0x00000033 shrl $23, %ecx
0x0f, 0xb6, 0xd9, //0x00000036 movzbl %cl, %ebx
0x81, 0xfb, 0xff, 0x00, 0x00, 0x00, //0x00000039 cmpl $255, %ebx
0x0f, 0x84, 0xff, 0x0c, 0x00, 0x00, //0x0000003f je LBB0_139
0xc6, 0x07, 0x2d, //0x00000045 movb $45, (%rdi)
0x41, 0x89, 0xc1, //0x00000048 movl %eax, %r9d
0x41, 0xc1, 0xe9, 0x1f, //0x0000004b shrl $31, %r9d
0x4e, 0x8d, 0x04, 0x0f, //0x0000004f leaq (%rdi,%r9), %r8
0xa9, 0xff, 0xff, 0xff, 0x7f, //0x00000053 testl $2147483647, %eax
0x0f, 0x84, 0xc6, 0x01, 0x00, 0x00, //0x00000058 je LBB0_14
0x25, 0xff, 0xff, 0x7f, 0x00, //0x0000005e andl $8388607, %eax
0x85, 0xdb, //0x00000063 testl %ebx, %ebx
0x0f, 0x84, 0xe1, 0x0c, 0x00, 0x00, //0x00000065 je LBB0_140
0x8d, 0xb0, 0x00, 0x00, 0x80, 0x00, //0x0000006b leal $8388608(%rax), %esi
0x44, 0x8d, 0xbb, 0x6a, 0xff, 0xff, 0xff, //0x00000071 leal $-150(%rbx), %r15d
0x8d, 0x4b, 0x81, //0x00000078 leal $-127(%rbx), %ecx
0x83, 0xf9, 0x17, //0x0000007b cmpl $23, %ecx
0x0f, 0x87, 0x1b, 0x00, 0x00, 0x00, //0x0000007e ja LBB0_5
0xb9, 0x96, 0x00, 0x00, 0x00, //0x00000084 movl $150, %ecx
0x29, 0xd9, //0x00000089 subl %ebx, %ecx
0x48, 0xc7, 0xc2, 0xff, 0xff, 0xff, 0xff, //0x0000008b movq $-1, %rdx
0x48, 0xd3, 0xe2, //0x00000092 shlq %cl, %rdx
0xf7, 0xd2, //0x00000095 notl %edx
0x85, 0xf2, //0x00000097 testl %esi, %edx
0x0f, 0x84, 0x12, 0x04, 0x00, 0x00, //0x00000099 je LBB0_32
//0x0000009f LBB0_5
0x41, 0x89, 0xf6, //0x0000009f movl %esi, %r14d
0x41, 0x83, 0xe6, 0x01, //0x000000a2 andl $1, %r14d
0x85, 0xc0, //0x000000a6 testl %eax, %eax
0x0f, 0x94, 0xc0, //0x000000a8 sete %al
0x83, 0xfb, 0x01, //0x000000ab cmpl $1, %ebx
0x0f, 0x97, 0xc1, //0x000000ae seta %cl
0x20, 0xc1, //0x000000b1 andb %al, %cl
0x0f, 0xb6, 0xc9, //0x000000b3 movzbl %cl, %ecx
0x41, 0x89, 0xf2, //0x000000b6 movl %esi, %r10d
0x41, 0xc1, 0xe2, 0x02, //0x000000b9 shll $2, %r10d
0x8d, 0x44, 0xb1, 0xfe, //0x000000bd leal $-2(%rcx,%rsi,4), %eax
0x45, 0x69, 0xdf, 0x13, 0x44, 0x13, 0x00, //0x000000c1 imull $1262611, %r15d, %r11d
0x31, 0xd2, //0x000000c8 xorl %edx, %edx
0x84, 0xc9, //0x000000ca testb %cl, %cl
0xb9, 0xff, 0xfe, 0x07, 0x00, //0x000000cc movl $524031, %ecx
0x0f, 0x44, 0xca, //0x000000d1 cmovel %edx, %ecx
0x41, 0x29, 0xcb, //0x000000d4 subl %ecx, %r11d
0x41, 0xc1, 0xfb, 0x16, //0x000000d7 sarl $22, %r11d
0x41, 0x69, 0xcb, 0xb1, 0x6c, 0xe5, 0xff, //0x000000db imull $-1741647, %r11d, %ecx
0xc1, 0xe9, 0x13, //0x000000e2 shrl $19, %ecx
0x44, 0x01, 0xf9, //0x000000e5 addl %r15d, %ecx
0xba, 0x1f, 0x00, 0x00, 0x00, //0x000000e8 movl $31, %edx
0x44, 0x29, 0xda, //0x000000ed subl %r11d, %edx
0x48, 0x63, 0xd2, //0x000000f0 movslq %edx, %rdx
0x48, 0x8d, 0x1d, 0x36, 0x0d, 0x00, 0x00, //0x000000f3 leaq $3382(%rip), %rbx /* _pow10_ceil_sig_f32.g+0(%rip) */
0xfe, 0xc1, //0x000000fa incb %cl
0xd3, 0xe0, //0x000000fc shll %cl, %eax
0x4c, 0x8b, 0x24, 0xd3, //0x000000fe movq (%rbx,%rdx,8), %r12
0x49, 0xf7, 0xe4, //0x00000102 mulq %r12
0x48, 0xc1, 0xe8, 0x20, //0x00000105 shrq $32, %rax
0x31, 0xdb, //0x00000109 xorl %ebx, %ebx
0x83, 0xf8, 0x01, //0x0000010b cmpl $1, %eax
0x0f, 0x97, 0xc3, //0x0000010e seta %bl
0x41, 0xd3, 0xe2, //0x00000111 shll %cl, %r10d
0x09, 0xd3, //0x00000114 orl %edx, %ebx
0x4c, 0x89, 0xd0, //0x00000116 movq %r10, %rax
0x49, 0xf7, 0xe4, //0x00000119 mulq %r12
0x49, 0x89, 0xd2, //0x0000011c movq %rdx, %r10
0x48, 0xc1, 0xe8, 0x20, //0x0000011f shrq $32, %rax
0x45, 0x31, 0xff, //0x00000123 xorl %r15d, %r15d
0x83, 0xf8, 0x01, //0x00000126 cmpl $1, %eax
0x41, 0x0f, 0x97, 0xc7, //0x00000129 seta %r15b
0x8d, 0x04, 0xb5, 0x02, 0x00, 0x00, 0x00, //0x0000012d leal $2(,%rsi,4), %eax
0xd3, 0xe0, //0x00000134 shll %cl, %eax
0x45, 0x09, 0xd7, //0x00000136 orl %r10d, %r15d
0x49, 0xf7, 0xe4, //0x00000139 mulq %r12
0x48, 0xc1, 0xe8, 0x20, //0x0000013c shrq $32, %rax
0x31, 0xc9, //0x00000140 xorl %ecx, %ecx
0x83, 0xf8, 0x01, //0x00000142 cmpl $1, %eax
0x0f, 0x97, 0xc1, //0x00000145 seta %cl
0x09, 0xd1, //0x00000148 orl %edx, %ecx
0x44, 0x01, 0xf3, //0x0000014a addl %r14d, %ebx
0x44, 0x29, 0xf1, //0x0000014d subl %r14d, %ecx
0x41, 0x83, 0xff, 0x28, //0x00000150 cmpl $40, %r15d
0x0f, 0x82, 0x9a, 0x00, 0x00, 0x00, //0x00000154 jb LBB0_12
0x44, 0x89, 0xd2, //0x0000015a movl %r10d, %edx
0xb8, 0xcd, 0xcc, 0xcc, 0xcc, //0x0000015d movl $3435973837, %eax
0x48, 0x0f, 0xaf, 0xc2, //0x00000162 imulq %rdx, %rax
0x48, 0xc1, 0xe8, 0x25, //0x00000166 shrq $37, %rax
0x41, 0x89, 0xde, //0x0000016a movl %ebx, %r14d
0x48, 0x8d, 0x34, 0xc5, 0x00, 0x00, 0x00, 0x00, //0x0000016d leaq (,%rax,8), %rsi
0x48, 0x8d, 0x14, 0xb6, //0x00000175 leaq (%rsi,%rsi,4), %rdx
0x4c, 0x39, 0xf2, //0x00000179 cmpq %r14, %rdx
0x41, 0x0f, 0x93, 0xc4, //0x0000017c setae %r12b
0x4c, 0x8d, 0x74, 0xb6, 0x28, //0x00000180 leaq $40(%rsi,%rsi,4), %r14
0x89, 0xce, //0x00000185 movl %ecx, %esi
0x49, 0x39, 0xf6, //0x00000187 cmpq %rsi, %r14
0x0f, 0x96, 0xc2, //0x0000018a setbe %dl
0x41, 0x38, 0xd4, //0x0000018d cmpb %dl, %r12b
0x0f, 0x84, 0x5e, 0x00, 0x00, 0x00, //0x00000190 je LBB0_12
0x45, 0x31, 0xed, //0x00000196 xorl %r13d, %r13d
0x49, 0x39, 0xf6, //0x00000199 cmpq %rsi, %r14
0x41, 0x0f, 0x96, 0xc5, //0x0000019c setbe %r13b
0x41, 0x01, 0xc5, //0x000001a0 addl %eax, %r13d
0x41, 0xff, 0xc3, //0x000001a3 incl %r11d
0x41, 0x81, 0xfd, 0xa0, 0x86, 0x01, 0x00, //0x000001a6 cmpl $100000, %r13d
0x0f, 0x83, 0xb0, 0x00, 0x00, 0x00, //0x000001ad jae LBB0_18
//0x000001b3 LBB0_8
0xb8, 0x01, 0x00, 0x00, 0x00, //0x000001b3 movl $1, %eax
0x41, 0x83, 0xfd, 0x0a, //0x000001b8 cmpl $10, %r13d
0x0f, 0x82, 0xd4, 0x00, 0x00, 0x00, //0x000001bc jb LBB0_22
0xb8, 0x02, 0x00, 0x00, 0x00, //0x000001c2 movl $2, %eax
0x41, 0x83, 0xfd, 0x64, //0x000001c7 cmpl $100, %r13d
0x0f, 0x82, 0xc5, 0x00, 0x00, 0x00, //0x000001cb jb LBB0_22
0xb8, 0x03, 0x00, 0x00, 0x00, //0x000001d1 movl $3, %eax
0x41, 0x81, 0xfd, 0xe8, 0x03, 0x00, 0x00, //0x000001d6 cmpl $1000, %r13d
0x0f, 0x82, 0xb3, 0x00, 0x00, 0x00, //0x000001dd jb LBB0_22
0x41, 0x81, 0xfd, 0x10, 0x27, 0x00, 0x00, //0x000001e3 cmpl $10000, %r13d
0xb8, 0x05, 0x00, 0x00, 0x00, //0x000001ea movl $5, %eax
0xe9, 0x9f, 0x00, 0x00, 0x00, //0x000001ef jmp LBB0_21
//0x000001f4 LBB0_12
0x4d, 0x89, 0xd6, //0x000001f4 movq %r10, %r14
0x49, 0xc1, 0xee, 0x02, //0x000001f7 shrq $2, %r14
0x44, 0x89, 0xd6, //0x000001fb movl %r10d, %esi
0x83, 0xe6, 0xfc, //0x000001fe andl $-4, %esi
0x39, 0xf3, //0x00000201 cmpl %esi, %ebx
0x0f, 0x96, 0xc2, //0x00000203 setbe %dl
0x8d, 0x5e, 0x04, //0x00000206 leal $4(%rsi), %ebx
0x39, 0xcb, //0x00000209 cmpl %ecx, %ebx
0x0f, 0x96, 0xc0, //0x0000020b setbe %al
0x38, 0xc2, //0x0000020e cmpb %al, %dl
0x0f, 0x84, 0x1d, 0x00, 0x00, 0x00, //0x00000210 je LBB0_15
0x45, 0x31, 0xed, //0x00000216 xorl %r13d, %r13d
0x39, 0xcb, //0x00000219 cmpl %ecx, %ebx
0x41, 0x0f, 0x96, 0xc5, //0x0000021b setbe %r13b
0xe9, 0x2f, 0x00, 0x00, 0x00, //0x0000021f jmp LBB0_17
//0x00000224 LBB0_14
0x41, 0xc6, 0x00, 0x30, //0x00000224 movb $48, (%r8)
0x41, 0x29, 0xf8, //0x00000228 subl %edi, %r8d
0x41, 0xff, 0xc0, //0x0000022b incl %r8d
0xe9, 0x00, 0x0b, 0x00, 0x00, //0x0000022e jmp LBB0_138
//0x00000233 LBB0_15
0x83, 0xce, 0x02, //0x00000233 orl $2, %esi
0x41, 0xbd, 0x01, 0x00, 0x00, 0x00, //0x00000236 movl $1, %r13d
0x41, 0x39, 0xf7, //0x0000023c cmpl %esi, %r15d
0x0f, 0x87, 0x0e, 0x00, 0x00, 0x00, //0x0000023f ja LBB0_17
0x0f, 0x94, 0xc0, //0x00000245 sete %al
0x41, 0xc0, 0xea, 0x02, //0x00000248 shrb $2, %r10b
0x41, 0x20, 0xc2, //0x0000024c andb %al, %r10b
0x45, 0x0f, 0xb6, 0xea, //0x0000024f movzbl %r10b, %r13d
//0x00000253 LBB0_17
0x45, 0x01, 0xf5, //0x00000253 addl %r14d, %r13d
0x41, 0x81, 0xfd, 0xa0, 0x86, 0x01, 0x00, //0x00000256 cmpl $100000, %r13d
0x0f, 0x82, 0x50, 0xff, 0xff, 0xff, //0x0000025d jb LBB0_8
//0x00000263 LBB0_18
0xb8, 0x06, 0x00, 0x00, 0x00, //0x00000263 movl $6, %eax
0x41, 0x81, 0xfd, 0x40, 0x42, 0x0f, 0x00, //0x00000268 cmpl $1000000, %r13d
0x0f, 0x82, 0x21, 0x00, 0x00, 0x00, //0x0000026f jb LBB0_22
0xb8, 0x07, 0x00, 0x00, 0x00, //0x00000275 movl $7, %eax
0x41, 0x81, 0xfd, 0x80, 0x96, 0x98, 0x00, //0x0000027a cmpl $10000000, %r13d
0x0f, 0x82, 0x0f, 0x00, 0x00, 0x00, //0x00000281 jb LBB0_22
0x41, 0x81, 0xfd, 0x00, 0xe1, 0xf5, 0x05, //0x00000287 cmpl $100000000, %r13d
0xb8, 0x09, 0x00, 0x00, 0x00, //0x0000028e movl $9, %eax
//0x00000293 LBB0_21
0x83, 0xd8, 0x00, //0x00000293 sbbl $0, %eax
//0x00000296 LBB0_22
0x46, 0x8d, 0x3c, 0x18, //0x00000296 leal (%rax,%r11), %r15d
0x42, 0x8d, 0x4c, 0x18, 0x05, //0x0000029a leal $5(%rax,%r11), %ecx
0x83, 0xf9, 0x1b, //0x0000029f cmpl $27, %ecx
0x0f, 0x82, 0x77, 0x00, 0x00, 0x00, //0x000002a2 jb LBB0_26
0x89, 0xc0, //0x000002a8 movl %eax, %eax
0x49, 0x8d, 0x5c, 0x00, 0x01, //0x000002aa leaq $1(%r8,%rax), %rbx
0x41, 0x81, 0xfd, 0x10, 0x27, 0x00, 0x00, //0x000002af cmpl $10000, %r13d
0x0f, 0x82, 0xd9, 0x00, 0x00, 0x00, //0x000002b6 jb LBB0_30
0x44, 0x89, 0xe8, //0x000002bc movl %r13d, %eax
0x41, 0xbb, 0x59, 0x17, 0xb7, 0xd1, //0x000002bf movl $3518437209, %r11d
0x4c, 0x0f, 0xaf, 0xd8, //0x000002c5 imulq %rax, %r11
0x49, 0xc1, 0xeb, 0x2d, //0x000002c9 shrq $45, %r11
0x41, 0x69, 0xc3, 0xf0, 0xd8, 0xff, 0xff, //0x000002cd imull $-10000, %r11d, %eax
0x44, 0x01, 0xe8, //0x000002d4 addl %r13d, %eax
0x0f, 0x84, 0xb3, 0x04, 0x00, 0x00, //0x000002d7 je LBB0_62
0x89, 0xc1, //0x000002dd movl %eax, %ecx
0x48, 0x69, 0xc9, 0x1f, 0x85, 0xeb, 0x51, //0x000002df imulq $1374389535, %rcx, %rcx
0x48, 0xc1, 0xe9, 0x25, //0x000002e6 shrq $37, %rcx
0x6b, 0xd1, 0x64, //0x000002ea imull $100, %ecx, %edx
0x29, 0xd0, //0x000002ed subl %edx, %eax
0x48, 0x8d, 0x15, 0x6a, 0x0a, 0x00, 0x00, //0x000002ef leaq $2666(%rip), %rdx /* _Digits+0(%rip) */
0x0f, 0xb7, 0x04, 0x42, //0x000002f6 movzwl (%rdx,%rax,2), %eax
0x66, 0x89, 0x43, 0xfe, //0x000002fa movw %ax, $-2(%rbx)
0x0f, 0xb7, 0x04, 0x4a, //0x000002fe movzwl (%rdx,%rcx,2), %eax
0x66, 0x89, 0x43, 0xfc, //0x00000302 movw %ax, $-4(%rbx)
0x45, 0x31, 0xc9, //0x00000306 xorl %r9d, %r9d
0x48, 0x8d, 0x4b, 0xfc, //0x00000309 leaq $-4(%rbx), %rcx
0x41, 0x83, 0xfb, 0x64, //0x0000030d cmpl $100, %r11d
0x0f, 0x83, 0x91, 0x00, 0x00, 0x00, //0x00000311 jae LBB0_64
//0x00000317 LBB0_31
0x44, 0x89, 0xda, //0x00000317 movl %r11d, %edx
0xe9, 0xd4, 0x00, 0x00, 0x00, //0x0000031a jmp LBB0_66
//0x0000031f LBB0_26
0x41, 0x89, 0xc4, //0x0000031f movl %eax, %r12d
0x45, 0x85, 0xdb, //0x00000322 testl %r11d, %r11d
0x0f, 0x88, 0x1d, 0x02, 0x00, 0x00, //0x00000325 js LBB0_38
0x4b, 0x8d, 0x34, 0x20, //0x0000032b leaq (%r8,%r12), %rsi
0x41, 0x81, 0xfd, 0x10, 0x27, 0x00, 0x00, //0x0000032f cmpl $10000, %r13d
0x0f, 0x82, 0xa7, 0x02, 0x00, 0x00, //0x00000336 jb LBB0_43
0x44, 0x89, 0xe8, //0x0000033c movl %r13d, %eax
0xb9, 0x59, 0x17, 0xb7, 0xd1, //0x0000033f movl $3518437209, %ecx
0x48, 0x0f, 0xaf, 0xc8, //0x00000344 imulq %rax, %rcx
0x48, 0xc1, 0xe9, 0x2d, //0x00000348 shrq $45, %rcx
0x69, 0xc1, 0xf0, 0xd8, 0xff, 0xff, //0x0000034c imull $-10000, %ecx, %eax
0x44, 0x01, 0xe8, //0x00000352 addl %r13d, %eax
0x48, 0x69, 0xd0, 0x1f, 0x85, 0xeb, 0x51, //0x00000355 imulq $1374389535, %rax, %rdx
0x48, 0xc1, 0xea, 0x25, //0x0000035c shrq $37, %rdx
0x6b, 0xda, 0x64, //0x00000360 imull $100, %edx, %ebx
0x29, 0xd8, //0x00000363 subl %ebx, %eax
0x48, 0x8d, 0x1d, 0xf4, 0x09, 0x00, 0x00, //0x00000365 leaq $2548(%rip), %rbx /* _Digits+0(%rip) */
0x0f, 0xb7, 0x04, 0x43, //0x0000036c movzwl (%rbx,%rax,2), %eax
0x66, 0x89, 0x46, 0xfe, //0x00000370 movw %ax, $-2(%rsi)
0x48, 0x8d, 0x46, 0xfc, //0x00000374 leaq $-4(%rsi), %rax
0x0f, 0xb7, 0x14, 0x53, //0x00000378 movzwl (%rbx,%rdx,2), %edx
0x66, 0x89, 0x56, 0xfc, //0x0000037c movw %dx, $-4(%rsi)
0x41, 0x89, 0xcd, //0x00000380 movl %ecx, %r13d
0x41, 0x83, 0xfd, 0x64, //0x00000383 cmpl $100, %r13d
0x0f, 0x83, 0x63, 0x02, 0x00, 0x00, //0x00000387 jae LBB0_44
//0x0000038d LBB0_29
0x44, 0x89, 0xe9, //0x0000038d movl %r13d, %ecx
0xe9, 0x9e, 0x02, 0x00, 0x00, //0x00000390 jmp LBB0_46
//0x00000395 LBB0_30
0x45, 0x31, 0xc9, //0x00000395 xorl %r9d, %r9d
0x48, 0x89, 0xd9, //0x00000398 movq %rbx, %rcx
0x45, 0x89, 0xeb, //0x0000039b movl %r13d, %r11d
0x41, 0x83, 0xfb, 0x64, //0x0000039e cmpl $100, %r11d
0x0f, 0x82, 0x6f, 0xff, 0xff, 0xff, //0x000003a2 jb LBB0_31
//0x000003a8 LBB0_64
0x48, 0xff, 0xc9, //0x000003a8 decq %rcx
0x4c, 0x8d, 0x15, 0xae, 0x09, 0x00, 0x00, //0x000003ab leaq $2478(%rip), %r10 /* _Digits+0(%rip) */
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, //0x000003b2 .p2align 4, 0x90
//0x000003c0 LBB0_65
0x44, 0x89, 0xda, //0x000003c0 movl %r11d, %edx
0x48, 0x69, 0xd2, 0x1f, 0x85, 0xeb, 0x51, //0x000003c3 imulq $1374389535, %rdx, %rdx
0x48, 0xc1, 0xea, 0x25, //0x000003ca shrq $37, %rdx
0x6b, 0xc2, 0x64, //0x000003ce imull $100, %edx, %eax
0x44, 0x89, 0xde, //0x000003d1 movl %r11d, %esi
0x29, 0xc6, //0x000003d4 subl %eax, %esi
0x41, 0x0f, 0xb7, 0x04, 0x72, //0x000003d6 movzwl (%r10,%rsi,2), %eax
0x66, 0x89, 0x41, 0xff, //0x000003db movw %ax, $-1(%rcx)
0x48, 0x83, 0xc1, 0xfe, //0x000003df addq $-2, %rcx
0x41, 0x81, 0xfb, 0x0f, 0x27, 0x00, 0x00, //0x000003e3 cmpl $9999, %r11d
0x41, 0x89, 0xd3, //0x000003ea movl %edx, %r11d
0x0f, 0x87, 0xcd, 0xff, 0xff, 0xff, //0x000003ed ja LBB0_65
//0x000003f3 LBB0_66
0x49, 0x8d, 0x70, 0x01, //0x000003f3 leaq $1(%r8), %rsi
0x83, 0xfa, 0x0a, //0x000003f7 cmpl $10, %edx
0x0f, 0x82, 0x1d, 0x00, 0x00, 0x00, //0x000003fa jb LBB0_68
0x89, 0xd0, //0x00000400 movl %edx, %eax
0x48, 0x8d, 0x0d, 0x57, 0x09, 0x00, 0x00, //0x00000402 leaq $2391(%rip), %rcx /* _Digits+0(%rip) */
0x8a, 0x14, 0x41, //0x00000409 movb (%rcx,%rax,2), %dl
0x8a, 0x44, 0x41, 0x01, //0x0000040c movb $1(%rcx,%rax,2), %al
0x41, 0x88, 0x50, 0x01, //0x00000410 movb %dl, $1(%r8)
0x41, 0x88, 0x40, 0x02, //0x00000414 movb %al, $2(%r8)
0xe9, 0x05, 0x00, 0x00, 0x00, //0x00000418 jmp LBB0_69
//0x0000041d LBB0_68
0x80, 0xc2, 0x30, //0x0000041d addb $48, %dl
0x88, 0x16, //0x00000420 movb %dl, (%rsi)
//0x00000422 LBB0_69
0x4c, 0x29, 0xcb, //0x00000422 subq %r9, %rbx
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, //0x00000425 .p2align 4, 0x90
//0x00000430 LBB0_70
0x80, 0x7b, 0xff, 0x30, //0x00000430 cmpb $48, $-1(%rbx)
0x48, 0x8d, 0x5b, 0xff, //0x00000434 leaq $-1(%rbx), %rbx
0x0f, 0x84, 0xf2, 0xff, 0xff, 0xff, //0x00000438 je LBB0_70
0x41, 0x88, 0x10, //0x0000043e movb %dl, (%r8)
0x48, 0x8d, 0x43, 0x01, //0x00000441 leaq $1(%rbx), %rax
0x48, 0x89, 0xc1, //0x00000445 movq %rax, %rcx
0x48, 0x29, 0xf1, //0x00000448 subq %rsi, %rcx
0x48, 0x83, 0xf9, 0x02, //0x0000044b cmpq $2, %rcx
0x0f, 0x8c, 0x06, 0x00, 0x00, 0x00, //0x0000044f jl LBB0_73
0xc6, 0x06, 0x2e, //0x00000455 movb $46, (%rsi)
0x48, 0x89, 0xc3, //0x00000458 movq %rax, %rbx
//0x0000045b LBB0_73
0xc6, 0x03, 0x65, //0x0000045b movb $101, (%rbx)
0x45, 0x85, 0xff, //0x0000045e testl %r15d, %r15d
0x0f, 0x8e, 0x41, 0x01, 0x00, 0x00, //0x00000461 jle LBB0_76
0x41, 0xff, 0xcf, //0x00000467 decl %r15d
0xc6, 0x43, 0x01, 0x2b, //0x0000046a movb $43, $1(%rbx)
0x44, 0x89, 0xf8, //0x0000046e movl %r15d, %eax
0x83, 0xf8, 0x64, //0x00000471 cmpl $100, %eax
0x0f, 0x8c, 0x43, 0x01, 0x00, 0x00, //0x00000474 jl LBB0_77
//0x0000047a LBB0_75
0x89, 0xc1, //0x0000047a movl %eax, %ecx
0xba, 0xcd, 0xcc, 0xcc, 0xcc, //0x0000047c movl $3435973837, %edx
0x48, 0x0f, 0xaf, 0xd1, //0x00000481 imulq %rcx, %rdx
0x48, 0xc1, 0xea, 0x23, //0x00000485 shrq $35, %rdx
0x8d, 0x0c, 0x12, //0x00000489 leal (%rdx,%rdx), %ecx
0x8d, 0x0c, 0x89, //0x0000048c leal (%rcx,%rcx,4), %ecx
0x29, 0xc8, //0x0000048f subl %ecx, %eax
0x48, 0x8d, 0x0d, 0xc8, 0x08, 0x00, 0x00, //0x00000491 leaq $2248(%rip), %rcx /* _Digits+0(%rip) */
0x0f, 0xb7, 0x0c, 0x51, //0x00000498 movzwl (%rcx,%rdx,2), %ecx
0x66, 0x89, 0x4b, 0x02, //0x0000049c movw %cx, $2(%rbx)
0x0c, 0x30, //0x000004a0 orb $48, %al
0x88, 0x43, 0x04, //0x000004a2 movb %al, $4(%rbx)
0x48, 0x83, 0xc3, 0x05, //0x000004a5 addq $5, %rbx
0x49, 0x89, 0xd8, //0x000004a9 movq %rbx, %r8
0xe9, 0x7f, 0x08, 0x00, 0x00, //0x000004ac jmp LBB0_137
//0x000004b1 LBB0_32
0xd3, 0xee, //0x000004b1 shrl %cl, %esi
0x81, 0xfe, 0xa0, 0x86, 0x01, 0x00, //0x000004b3 cmpl $100000, %esi
0x0f, 0x82, 0x1a, 0x02, 0x00, 0x00, //0x000004b9 jb LBB0_52
0xb8, 0x06, 0x00, 0x00, 0x00, //0x000004bf movl $6, %eax
0x81, 0xfe, 0x40, 0x42, 0x0f, 0x00, //0x000004c4 cmpl $1000000, %esi
0x0f, 0x82, 0x20, 0x00, 0x00, 0x00, //0x000004ca jb LBB0_36
0xb8, 0x07, 0x00, 0x00, 0x00, //0x000004d0 movl $7, %eax
0x81, 0xfe, 0x80, 0x96, 0x98, 0x00, //0x000004d5 cmpl $10000000, %esi
0x0f, 0x82, 0x0f, 0x00, 0x00, 0x00, //0x000004db jb LBB0_36
0x81, 0xfe, 0x00, 0xe1, 0xf5, 0x05, //0x000004e1 cmpl $100000000, %esi
0xb8, 0x09, 0x00, 0x00, 0x00, //0x000004e7 movl $9, %eax
0x48, 0x83, 0xd8, 0x00, //0x000004ec sbbq $0, %rax
//0x000004f0 LBB0_36
0x4c, 0x01, 0xc0, //0x000004f0 addq %r8, %rax
//0x000004f3 LBB0_37
0x89, 0xf1, //0x000004f3 movl %esi, %ecx
0xba, 0x59, 0x17, 0xb7, 0xd1, //0x000004f5 movl $3518437209, %edx
0x48, 0x0f, 0xaf, 0xd1, //0x000004fa imulq %rcx, %rdx
0x48, 0xc1, 0xea, 0x2d, //0x000004fe shrq $45, %rdx
0x69, 0xca, 0xf0, 0xd8, 0xff, 0xff, //0x00000502 imull $-10000, %edx, %ecx
0x01, 0xf1, //0x00000508 addl %esi, %ecx
0x48, 0x69, 0xf1, 0x1f, 0x85, 0xeb, 0x51, //0x0000050a imulq $1374389535, %rcx, %rsi
0x48, 0xc1, 0xee, 0x25, //0x00000511 shrq $37, %rsi
0x6b, 0xde, 0x64, //0x00000515 imull $100, %esi, %ebx
0x29, 0xd9, //0x00000518 subl %ebx, %ecx
0x48, 0x8d, 0x1d, 0x3f, 0x08, 0x00, 0x00, //0x0000051a leaq $2111(%rip), %rbx /* _Digits+0(%rip) */
0x0f, 0xb7, 0x0c, 0x4b, //0x00000521 movzwl (%rbx,%rcx,2), %ecx
0x66, 0x89, 0x48, 0xfe, //0x00000525 movw %cx, $-2(%rax)
0x0f, 0xb7, 0x0c, 0x73, //0x00000529 movzwl (%rbx,%rsi,2), %ecx
0x66, 0x89, 0x48, 0xfc, //0x0000052d movw %cx, $-4(%rax)
0x49, 0x89, 0xc1, //0x00000531 movq %rax, %r9
0x48, 0x83, 0xc0, 0xfc, //0x00000534 addq $-4, %rax
0x89, 0xd6, //0x00000538 movl %edx, %esi
0x83, 0xfe, 0x64, //0x0000053a cmpl $100, %esi
0x0f, 0x83, 0xd5, 0x01, 0x00, 0x00, //0x0000053d jae LBB0_56
0xe9, 0x17, 0x02, 0x00, 0x00, //0x00000543 jmp LBB0_58
//0x00000548 LBB0_38
0x45, 0x85, 0xff, //0x00000548 testl %r15d, %r15d
0x0f, 0x8f, 0x90, 0x04, 0x00, 0x00, //0x0000054b jg LBB0_98
0x66, 0x41, 0xc7, 0x00, 0x30, 0x2e, //0x00000551 movw $11824, (%r8)
0x49, 0x83, 0xc0, 0x02, //0x00000557 addq $2, %r8
0x45, 0x85, 0xff, //0x0000055b testl %r15d, %r15d
0x0f, 0x89, 0x7d, 0x04, 0x00, 0x00, //0x0000055e jns LBB0_98
0x31, 0xf6, //0x00000564 xorl %esi, %esi
0x41, 0x83, 0xff, 0x80, //0x00000566 cmpl $-128, %r15d
0x0f, 0x87, 0x5a, 0x04, 0x00, 0x00, //0x0000056a ja LBB0_96
0x45, 0x89, 0xfa, //0x00000570 movl %r15d, %r10d
0x41, 0xf7, 0xd2, //0x00000573 notl %r10d
0x49, 0xff, 0xc2, //0x00000576 incq %r10
0x4c, 0x89, 0xd6, //0x00000579 movq %r10, %rsi
0x48, 0x83, 0xe6, 0x80, //0x0000057c andq $-128, %rsi
0x48, 0x8d, 0x46, 0x80, //0x00000580 leaq $-128(%rsi), %rax
0x48, 0x89, 0xc1, //0x00000584 movq %rax, %rcx
0x48, 0xc1, 0xe9, 0x07, //0x00000587 shrq $7, %rcx
0x48, 0xff, 0xc1, //0x0000058b incq %rcx
0x41, 0x89, 0xcb, //0x0000058e movl %ecx, %r11d
0x41, 0x83, 0xe3, 0x03, //0x00000591 andl $3, %r11d
0x48, 0x3d, 0x80, 0x01, 0x00, 0x00, //0x00000595 cmpq $384, %rax
0x0f, 0x83, 0x38, 0x03, 0x00, 0x00, //0x0000059b jae LBB0_90
0x31, 0xdb, //0x000005a1 xorl %ebx, %ebx
0xe9, 0xda, 0x03, 0x00, 0x00, //0x000005a3 jmp LBB0_92
//0x000005a8 LBB0_76
0xc6, 0x43, 0x01, 0x2d, //0x000005a8 movb $45, $1(%rbx)
0xb8, 0x01, 0x00, 0x00, 0x00, //0x000005ac movl $1, %eax
0x44, 0x29, 0xf8, //0x000005b1 subl %r15d, %eax
0x83, 0xf8, 0x64, //0x000005b4 cmpl $100, %eax
0x0f, 0x8d, 0xbd, 0xfe, 0xff, 0xff, //0x000005b7 jge LBB0_75
//0x000005bd LBB0_77
0x83, 0xf8, 0x0a, //0x000005bd cmpl $10, %eax
0x0f, 0x8c, 0x02, 0x01, 0x00, 0x00, //0x000005c0 jl LBB0_79
0x48, 0x98, //0x000005c6 cltq
0x48, 0x8d, 0x0d, 0x91, 0x07, 0x00, 0x00, //0x000005c8 leaq $1937(%rip), %rcx /* _Digits+0(%rip) */
0x0f, 0xb7, 0x04, 0x41, //0x000005cf movzwl (%rcx,%rax,2), %eax
0x66, 0x89, 0x43, 0x02, //0x000005d3 movw %ax, $2(%rbx)
0x48, 0x83, 0xc3, 0x04, //0x000005d7 addq $4, %rbx
0x49, 0x89, 0xd8, //0x000005db movq %rbx, %r8
0xe9, 0x4d, 0x07, 0x00, 0x00, //0x000005de jmp LBB0_137
//0x000005e3 LBB0_43
0x48, 0x89, 0xf0, //0x000005e3 movq %rsi, %rax
0x41, 0x83, 0xfd, 0x64, //0x000005e6 cmpl $100, %r13d
0x0f, 0x82, 0x9d, 0xfd, 0xff, 0xff, //0x000005ea jb LBB0_29
//0x000005f0 LBB0_44
0x48, 0xff, 0xc8, //0x000005f0 decq %rax
0x4c, 0x8d, 0x15, 0x66, 0x07, 0x00, 0x00, //0x000005f3 leaq $1894(%rip), %r10 /* _Digits+0(%rip) */
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, //0x000005fa .p2align 4, 0x90
//0x00000600 LBB0_45
0x44, 0x89, 0xe9, //0x00000600 movl %r13d, %ecx
0x48, 0x69, 0xc9, 0x1f, 0x85, 0xeb, 0x51, //0x00000603 imulq $1374389535, %rcx, %rcx
0x48, 0xc1, 0xe9, 0x25, //0x0000060a shrq $37, %rcx
0x6b, 0xd9, 0x64, //0x0000060e imull $100, %ecx, %ebx
0x44, 0x89, 0xea, //0x00000611 movl %r13d, %edx
0x29, 0xda, //0x00000614 subl %ebx, %edx
0x41, 0x0f, 0xb7, 0x14, 0x52, //0x00000616 movzwl (%r10,%rdx,2), %edx
0x66, 0x89, 0x50, 0xff, //0x0000061b movw %dx, $-1(%rax)
0x48, 0x83, 0xc0, 0xfe, //0x0000061f addq $-2, %rax
0x41, 0x81, 0xfd, 0x0f, 0x27, 0x00, 0x00, //0x00000623 cmpl $9999, %r13d
0x41, 0x89, 0xcd, //0x0000062a movl %ecx, %r13d
0x0f, 0x87, 0xcd, 0xff, 0xff, 0xff, //0x0000062d ja LBB0_45
//0x00000633 LBB0_46
0x49, 0x63, 0xc7, //0x00000633 movslq %r15d, %rax
0x83, 0xf9, 0x0a, //0x00000636 cmpl $10, %ecx
0x0f, 0x82, 0x22, 0x00, 0x00, 0x00, //0x00000639 jb LBB0_48
0x89, 0xc9, //0x0000063f movl %ecx, %ecx
0x48, 0x8d, 0x15, 0x18, 0x07, 0x00, 0x00, //0x00000641 leaq $1816(%rip), %rdx /* _Digits+0(%rip) */
0x0f, 0xb7, 0x0c, 0x4a, //0x00000648 movzwl (%rdx,%rcx,2), %ecx
0x66, 0x41, 0x89, 0x08, //0x0000064c movw %cx, (%r8)
0x49, 0x01, 0xc0, //0x00000650 addq %rax, %r8
0x49, 0x39, 0xc4, //0x00000653 cmpq %rax, %r12
0x0f, 0x8c, 0x17, 0x00, 0x00, 0x00, //0x00000656 jl LBB0_49
0xe9, 0xcf, 0x06, 0x00, 0x00, //0x0000065c jmp LBB0_137
//0x00000661 LBB0_48
0x80, 0xc1, 0x30, //0x00000661 addb $48, %cl
0x41, 0x88, 0x08, //0x00000664 movb %cl, (%r8)
0x49, 0x01, 0xc0, //0x00000667 addq %rax, %r8
0x49, 0x39, 0xc4, //0x0000066a cmpq %rax, %r12
0x0f, 0x8d, 0xbd, 0x06, 0x00, 0x00, //0x0000066d jge LBB0_137
//0x00000673 LBB0_49
0x4b, 0x8d, 0x04, 0x21, //0x00000673 leaq (%r9,%r12), %rax
0x4c, 0x8d, 0x5c, 0x07, 0x01, //0x00000677 leaq $1(%rdi,%rax), %r11
0x4d, 0x39, 0xc3, //0x0000067c cmpq %r8, %r11
0x4d, 0x0f, 0x46, 0xd8, //0x0000067f cmovbeq %r8, %r11
0x4a, 0x8d, 0x0c, 0x0f, //0x00000683 leaq (%rdi,%r9), %rcx
0x4c, 0x01, 0xe1, //0x00000687 addq %r12, %rcx
0x49, 0x29, 0xcb, //0x0000068a subq %rcx, %r11
0x49, 0x81, 0xfb, 0x80, 0x00, 0x00, 0x00, //0x0000068d cmpq $128, %r11
0x0f, 0x82, 0x06, 0x02, 0x00, 0x00, //0x00000694 jb LBB0_87
0x4d, 0x89, 0xda, //0x0000069a movq %r11, %r10
0x49, 0x83, 0xe2, 0x80, //0x0000069d andq $-128, %r10
0x49, 0x8d, 0x4a, 0x80, //0x000006a1 leaq $-128(%r10), %rcx
0x48, 0x89, 0xcb, //0x000006a5 movq %rcx, %rbx
0x48, 0xc1, 0xeb, 0x07, //0x000006a8 shrq $7, %rbx
0x48, 0xff, 0xc3, //0x000006ac incq %rbx
0x89, 0xda, //0x000006af movl %ebx, %edx
0x83, 0xe2, 0x03, //0x000006b1 andl $3, %edx
0x48, 0x81, 0xf9, 0x80, 0x01, 0x00, 0x00, //0x000006b4 cmpq $384, %rcx
0x0f, 0x83, 0xe8, 0x00, 0x00, 0x00, //0x000006bb jae LBB0_80
0x31, 0xc0, //0x000006c1 xorl %eax, %eax
0xe9, 0x88, 0x01, 0x00, 0x00, //0x000006c3 jmp LBB0_82
//0x000006c8 LBB0_79
0x04, 0x30, //0x000006c8 addb $48, %al
0x88, 0x43, 0x02, //0x000006ca movb %al, $2(%rbx)
0x48, 0x83, 0xc3, 0x03, //0x000006cd addq $3, %rbx
0x49, 0x89, 0xd8, //0x000006d1 movq %rbx, %r8
0xe9, 0x57, 0x06, 0x00, 0x00, //0x000006d4 jmp LBB0_137
//0x000006d9 LBB0_52
0x41, 0xb9, 0x01, 0x00, 0x00, 0x00, //0x000006d9 movl $1, %r9d
0x83, 0xfe, 0x0a, //0x000006df cmpl $10, %esi
0x0f, 0x82, 0x21, 0x00, 0x00, 0x00, //0x000006e2 jb LBB0_55
0x41, 0xb9, 0x02, 0x00, 0x00, 0x00, //0x000006e8 movl $2, %r9d
0x83, 0xfe, 0x64, //0x000006ee cmpl $100, %esi
0x0f, 0x82, 0x12, 0x00, 0x00, 0x00, //0x000006f1 jb LBB0_55
0x41, 0xb9, 0x03, 0x00, 0x00, 0x00, //0x000006f7 movl $3, %r9d
0x81, 0xfe, 0xe8, 0x03, 0x00, 0x00, //0x000006fd cmpl $1000, %esi
0x0f, 0x83, 0xab, 0x01, 0x00, 0x00, //0x00000703 jae LBB0_88
//0x00000709 LBB0_55
0x4d, 0x01, 0xc1, //0x00000709 addq %r8, %r9
0x4c, 0x89, 0xc8, //0x0000070c movq %r9, %rax
0x83, 0xfe, 0x64, //0x0000070f cmpl $100, %esi
0x0f, 0x82, 0x47, 0x00, 0x00, 0x00, //0x00000712 jb LBB0_58
//0x00000718 LBB0_56
0x48, 0xff, 0xc8, //0x00000718 decq %rax
0x4c, 0x8d, 0x15, 0x3e, 0x06, 0x00, 0x00, //0x0000071b leaq $1598(%rip), %r10 /* _Digits+0(%rip) */
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, //0x00000722 .p2align 4, 0x90
//0x00000730 LBB0_57
0x89, 0xf3, //0x00000730 movl %esi, %ebx
0x89, 0xf6, //0x00000732 movl %esi, %esi
0x48, 0x69, 0xf6, 0x1f, 0x85, 0xeb, 0x51, //0x00000734 imulq $1374389535, %rsi, %rsi
0x48, 0xc1, 0xee, 0x25, //0x0000073b shrq $37, %rsi
0x6b, 0xce, 0x64, //0x0000073f imull $100, %esi, %ecx
0x89, 0xda, //0x00000742 movl %ebx, %edx
0x29, 0xca, //0x00000744 subl %ecx, %edx
0x41, 0x0f, 0xb7, 0x0c, 0x52, //0x00000746 movzwl (%r10,%rdx,2), %ecx
0x66, 0x89, 0x48, 0xff, //0x0000074b movw %cx, $-1(%rax)
0x48, 0x83, 0xc0, 0xfe, //0x0000074f addq $-2, %rax
0x81, 0xfb, 0x0f, 0x27, 0x00, 0x00, //0x00000753 cmpl $9999, %ebx
0x0f, 0x87, 0xd1, 0xff, 0xff, 0xff, //0x00000759 ja LBB0_57
//0x0000075f LBB0_58
0x83, 0xfe, 0x0a, //0x0000075f cmpl $10, %esi
0x0f, 0x82, 0x16, 0x00, 0x00, 0x00, //0x00000762 jb LBB0_60
0x89, 0xf0, //0x00000768 movl %esi, %eax
0x48, 0x8d, 0x0d, 0xef, 0x05, 0x00, 0x00, //0x0000076a leaq $1519(%rip), %rcx /* _Digits+0(%rip) */
0x0f, 0xb7, 0x04, 0x41, //0x00000771 movzwl (%rcx,%rax,2), %eax
0x66, 0x41, 0x89, 0x00, //0x00000775 movw %ax, (%r8)
0xe9, 0x07, 0x00, 0x00, 0x00, //0x00000779 jmp LBB0_61
//0x0000077e LBB0_60
0x40, 0x80, 0xc6, 0x30, //0x0000077e addb $48, %sil
0x41, 0x88, 0x30, //0x00000782 movb %sil, (%r8)
//0x00000785 LBB0_61
0x41, 0x29, 0xf9, //0x00000785 subl %edi, %r9d
0x45, 0x89, 0xc8, //0x00000788 movl %r9d, %r8d
0xe9, 0xa3, 0x05, 0x00, 0x00, //0x0000078b jmp LBB0_138
//0x00000790 LBB0_62
0x41, 0xb9, 0x04, 0x00, 0x00, 0x00, //0x00000790 movl $4, %r9d
0x48, 0x8d, 0x4b, 0xfc, //0x00000796 leaq $-4(%rbx), %rcx
0x41, 0x83, 0xfb, 0x64, //0x0000079a cmpl $100, %r11d
0x0f, 0x82, 0x73, 0xfb, 0xff, 0xff, //0x0000079e jb LBB0_31
0xe9, 0xff, 0xfb, 0xff, 0xff, //0x000007a4 jmp LBB0_64
//0x000007a9 LBB0_80
0x48, 0x29, 0xd3, //0x000007a9 subq %rdx, %rbx
0x48, 0x8d, 0x8c, 0x07, 0xe0, 0x01, 0x00, 0x00, //0x000007ac leaq $480(%rdi,%rax), %rcx
0x31, 0xc0, //0x000007b4 xorl %eax, %eax
0xc5, 0xfe, 0x6f, 0x05, 0x42, 0xf8, 0xff, 0xff, //0x000007b6 vmovdqu $-1982(%rip), %ymm0 /* LCPI0_0+0(%rip) */
0x90, 0x90, //0x000007be .p2align 4, 0x90
//0x000007c0 LBB0_81
0xc5, 0xfe, 0x7f, 0x84, 0x01, 0x20, 0xfe, 0xff, 0xff, //0x000007c0 vmovdqu %ymm0, $-480(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x01, 0x40, 0xfe, 0xff, 0xff, //0x000007c9 vmovdqu %ymm0, $-448(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x01, 0x60, 0xfe, 0xff, 0xff, //0x000007d2 vmovdqu %ymm0, $-416(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x01, 0x80, 0xfe, 0xff, 0xff, //0x000007db vmovdqu %ymm0, $-384(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x01, 0xa0, 0xfe, 0xff, 0xff, //0x000007e4 vmovdqu %ymm0, $-352(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x01, 0xc0, 0xfe, 0xff, 0xff, //0x000007ed vmovdqu %ymm0, $-320(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x01, 0xe0, 0xfe, 0xff, 0xff, //0x000007f6 vmovdqu %ymm0, $-288(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x01, 0x00, 0xff, 0xff, 0xff, //0x000007ff vmovdqu %ymm0, $-256(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x01, 0x20, 0xff, 0xff, 0xff, //0x00000808 vmovdqu %ymm0, $-224(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x01, 0x40, 0xff, 0xff, 0xff, //0x00000811 vmovdqu %ymm0, $-192(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x01, 0x60, 0xff, 0xff, 0xff, //0x0000081a vmovdqu %ymm0, $-160(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x44, 0x01, 0x80, //0x00000823 vmovdqu %ymm0, $-128(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x44, 0x01, 0xa0, //0x00000829 vmovdqu %ymm0, $-96(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x44, 0x01, 0xc0, //0x0000082f vmovdqu %ymm0, $-64(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x44, 0x01, 0xe0, //0x00000835 vmovdqu %ymm0, $-32(%rcx,%rax)
0xc5, 0xfe, 0x7f, 0x04, 0x01, //0x0000083b vmovdqu %ymm0, (%rcx,%rax)
0x48, 0x05, 0x00, 0x02, 0x00, 0x00, //0x00000840 addq $512, %rax
0x48, 0x83, 0xc3, 0xfc, //0x00000846 addq $-4, %rbx
0x0f, 0x85, 0x70, 0xff, 0xff, 0xff, //0x0000084a jne LBB0_81
//0x00000850 LBB0_82
0x48, 0x85, 0xd2, //0x00000850 testq %rdx, %rdx
0x0f, 0x84, 0x37, 0x00, 0x00, 0x00, //0x00000853 je LBB0_85
0x4c, 0x01, 0xc8, //0x00000859 addq %r9, %rax
0x4c, 0x01, 0xe0, //0x0000085c addq %r12, %rax
0x48, 0x8d, 0x44, 0x07, 0x60, //0x0000085f leaq $96(%rdi,%rax), %rax
0x48, 0xf7, 0xda, //0x00000864 negq %rdx
0xc5, 0xfe, 0x6f, 0x05, 0x91, 0xf7, 0xff, 0xff, //0x00000867 vmovdqu $-2159(%rip), %ymm0 /* LCPI0_0+0(%rip) */
0x90, //0x0000086f .p2align 4, 0x90
//0x00000870 LBB0_84
0xc5, 0xfe, 0x7f, 0x40, 0xa0, //0x00000870 vmovdqu %ymm0, $-96(%rax)
0xc5, 0xfe, 0x7f, 0x40, 0xc0, //0x00000875 vmovdqu %ymm0, $-64(%rax)
0xc5, 0xfe, 0x7f, 0x40, 0xe0, //0x0000087a vmovdqu %ymm0, $-32(%rax)
0xc5, 0xfe, 0x7f, 0x00, //0x0000087f vmovdqu %ymm0, (%rax)
0x48, 0x83, 0xe8, 0x80, //0x00000883 subq $-128, %rax
0x48, 0xff, 0xc2, //0x00000887 incq %rdx
0x0f, 0x85, 0xe0, 0xff, 0xff, 0xff, //0x0000088a jne LBB0_84
//0x00000890 LBB0_85
0x4d, 0x39, 0xda, //0x00000890 cmpq %r11, %r10
0x0f, 0x84, 0x97, 0x04, 0x00, 0x00, //0x00000893 je LBB0_137
0x4c, 0x01, 0xd6, //0x00000899 addq %r10, %rsi
0x90, 0x90, 0x90, 0x90, //0x0000089c .p2align 4, 0x90
//0x000008a0 LBB0_87
0xc6, 0x06, 0x30, //0x000008a0 movb $48, (%rsi)
0x48, 0xff, 0xc6, //0x000008a3 incq %rsi
0x4c, 0x39, 0xc6, //0x000008a6 cmpq %r8, %rsi
0x0f, 0x82, 0xf1, 0xff, 0xff, 0xff, //0x000008a9 jb LBB0_87
0xe9, 0x7c, 0x04, 0x00, 0x00, //0x000008af jmp LBB0_137
//0x000008b4 LBB0_88
0x81, 0xfe, 0x10, 0x27, 0x00, 0x00, //0x000008b4 cmpl $10000, %esi
0x4c, 0x89, 0xc0, //0x000008ba movq %r8, %rax
0x48, 0x83, 0xd8, 0x00, //0x000008bd sbbq $0, %rax
0x48, 0x83, 0xc0, 0x05, //0x000008c1 addq $5, %rax
0x81, 0xfe, 0x10, 0x27, 0x00, 0x00, //0x000008c5 cmpl $10000, %esi
0x0f, 0x83, 0x22, 0xfc, 0xff, 0xff, //0x000008cb jae LBB0_37
0x49, 0x89, 0xc1, //0x000008d1 movq %rax, %r9
0xe9, 0x3f, 0xfe, 0xff, 0xff, //0x000008d4 jmp LBB0_56
//0x000008d9 LBB0_90
0x49, 0x8d, 0x84, 0x39, 0xe2, 0x01, 0x00, 0x00, //0x000008d9 leaq $482(%r9,%rdi), %rax
0x4d, 0x89, 0xde, //0x000008e1 movq %r11, %r14
0x49, 0x29, 0xce, //0x000008e4 subq %rcx, %r14
0x31, 0xdb, //0x000008e7 xorl %ebx, %ebx
0xc5, 0xfe, 0x6f, 0x05, 0x0f, 0xf7, 0xff, 0xff, //0x000008e9 vmovdqu $-2289(%rip), %ymm0 /* LCPI0_0+0(%rip) */
//0x000008f1 LBB0_91
0xc5, 0xfe, 0x7f, 0x84, 0x18, 0x20, 0xfe, 0xff, 0xff, //0x000008f1 vmovdqu %ymm0, $-480(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x84, 0x18, 0x40, 0xfe, 0xff, 0xff, //0x000008fa vmovdqu %ymm0, $-448(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x84, 0x18, 0x60, 0xfe, 0xff, 0xff, //0x00000903 vmovdqu %ymm0, $-416(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x84, 0x18, 0x80, 0xfe, 0xff, 0xff, //0x0000090c vmovdqu %ymm0, $-384(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x84, 0x18, 0xa0, 0xfe, 0xff, 0xff, //0x00000915 vmovdqu %ymm0, $-352(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x84, 0x18, 0xc0, 0xfe, 0xff, 0xff, //0x0000091e vmovdqu %ymm0, $-320(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x84, 0x18, 0xe0, 0xfe, 0xff, 0xff, //0x00000927 vmovdqu %ymm0, $-288(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x84, 0x18, 0x00, 0xff, 0xff, 0xff, //0x00000930 vmovdqu %ymm0, $-256(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x84, 0x18, 0x20, 0xff, 0xff, 0xff, //0x00000939 vmovdqu %ymm0, $-224(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x84, 0x18, 0x40, 0xff, 0xff, 0xff, //0x00000942 vmovdqu %ymm0, $-192(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x84, 0x18, 0x60, 0xff, 0xff, 0xff, //0x0000094b vmovdqu %ymm0, $-160(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x44, 0x18, 0x80, //0x00000954 vmovdqu %ymm0, $-128(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x44, 0x18, 0xa0, //0x0000095a vmovdqu %ymm0, $-96(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x44, 0x18, 0xc0, //0x00000960 vmovdqu %ymm0, $-64(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x44, 0x18, 0xe0, //0x00000966 vmovdqu %ymm0, $-32(%rax,%rbx)
0xc5, 0xfe, 0x7f, 0x04, 0x18, //0x0000096c vmovdqu %ymm0, (%rax,%rbx)
0x48, 0x81, 0xc3, 0x00, 0x02, 0x00, 0x00, //0x00000971 addq $512, %rbx
0x49, 0x83, 0xc6, 0x04, //0x00000978 addq $4, %r14
0x0f, 0x85, 0x6f, 0xff, 0xff, 0xff, //0x0000097c jne LBB0_91
//0x00000982 LBB0_92
0x4d, 0x85, 0xdb, //0x00000982 testq %r11, %r11
0x0f, 0x84, 0x33, 0x00, 0x00, 0x00, //0x00000985 je LBB0_95
0x4c, 0x01, 0xcb, //0x0000098b addq %r9, %rbx
0x48, 0x8d, 0x44, 0x1f, 0x62, //0x0000098e leaq $98(%rdi,%rbx), %rax
0x49, 0xf7, 0xdb, //0x00000993 negq %r11
0xc5, 0xfe, 0x6f, 0x05, 0x62, 0xf6, 0xff, 0xff, //0x00000996 vmovdqu $-2462(%rip), %ymm0 /* LCPI0_0+0(%rip) */
//0x0000099e LBB0_94
0xc5, 0xfe, 0x7f, 0x40, 0xa0, //0x0000099e vmovdqu %ymm0, $-96(%rax)
0xc5, 0xfe, 0x7f, 0x40, 0xc0, //0x000009a3 vmovdqu %ymm0, $-64(%rax)
0xc5, 0xfe, 0x7f, 0x40, 0xe0, //0x000009a8 vmovdqu %ymm0, $-32(%rax)
0xc5, 0xfe, 0x7f, 0x00, //0x000009ad vmovdqu %ymm0, (%rax)
0x48, 0x83, 0xe8, 0x80, //0x000009b1 subq $-128, %rax
0x49, 0xff, 0xc3, //0x000009b5 incq %r11
0x0f, 0x85, 0xe0, 0xff, 0xff, 0xff, //0x000009b8 jne LBB0_94
//0x000009be LBB0_95
0x49, 0x01, 0xf0, //0x000009be addq %rsi, %r8
0x49, 0x39, 0xf2, //0x000009c1 cmpq %rsi, %r10
0x0f, 0x84, 0x17, 0x00, 0x00, 0x00, //0x000009c4 je LBB0_98
//0x000009ca LBB0_96
0x44, 0x89, 0xf8, //0x000009ca movl %r15d, %eax
0xf7, 0xd8, //0x000009cd negl %eax
0x90, //0x000009cf .p2align 4, 0x90
//0x000009d0 LBB0_97
0x41, 0xc6, 0x00, 0x30, //0x000009d0 movb $48, (%r8)
0x49, 0xff, 0xc0, //0x000009d4 incq %r8
0xff, 0xc6, //0x000009d7 incl %esi
0x39, 0xc6, //0x000009d9 cmpl %eax, %esi
0x0f, 0x8c, 0xef, 0xff, 0xff, 0xff, //0x000009db jl LBB0_97
//0x000009e1 LBB0_98
0x4b, 0x8d, 0x04, 0x20, //0x000009e1 leaq (%r8,%r12), %rax
0x41, 0x81, 0xfd, 0x10, 0x27, 0x00, 0x00, //0x000009e5 cmpl $10000, %r13d
0x0f, 0x82, 0x63, 0x00, 0x00, 0x00, //0x000009ec jb LBB0_101
0x44, 0x89, 0xe9, //0x000009f2 movl %r13d, %ecx
0x41, 0xba, 0x59, 0x17, 0xb7, 0xd1, //0x000009f5 movl $3518437209, %r10d
0x4c, 0x0f, 0xaf, 0xd1, //0x000009fb imulq %rcx, %r10
0x49, 0xc1, 0xea, 0x2d, //0x000009ff shrq $45, %r10
0x41, 0x69, 0xca, 0xf0, 0xd8, 0xff, 0xff, //0x00000a03 imull $-10000, %r10d, %ecx
0x44, 0x01, 0xe9, //0x00000a0a addl %r13d, %ecx
0x0f, 0x84, 0x87, 0x01, 0x00, 0x00, //0x00000a0d je LBB0_103
0x89, 0xca, //0x00000a13 movl %ecx, %edx
0x48, 0x69, 0xd2, 0x1f, 0x85, 0xeb, 0x51, //0x00000a15 imulq $1374389535, %rdx, %rdx
0x48, 0xc1, 0xea, 0x25, //0x00000a1c shrq $37, %rdx
0x6b, 0xda, 0x64, //0x00000a20 imull $100, %edx, %ebx
0x29, 0xd9, //0x00000a23 subl %ebx, %ecx
0x48, 0x8d, 0x1d, 0x34, 0x03, 0x00, 0x00, //0x00000a25 leaq $820(%rip), %rbx /* _Digits+0(%rip) */
0x0f, 0xb7, 0x0c, 0x4b, //0x00000a2c movzwl (%rbx,%rcx,2), %ecx
0x66, 0x89, 0x48, 0xfe, //0x00000a30 movw %cx, $-2(%rax)
0x0f, 0xb7, 0x0c, 0x53, //0x00000a34 movzwl (%rbx,%rdx,2), %ecx
0x66, 0x89, 0x48, 0xfc, //0x00000a38 movw %cx, $-4(%rax)
0x45, 0x31, 0xc9, //0x00000a3c xorl %r9d, %r9d
0x48, 0x83, 0xc0, 0xfc, //0x00000a3f addq $-4, %rax
0x41, 0x83, 0xfa, 0x64, //0x00000a43 cmpl $100, %r10d
0x0f, 0x83, 0x18, 0x00, 0x00, 0x00, //0x00000a47 jae LBB0_105
//0x00000a4d LBB0_102
0x44, 0x89, 0xd1, //0x00000a4d movl %r10d, %ecx
0xe9, 0x4d, 0x00, 0x00, 0x00, //0x00000a50 jmp LBB0_107
//0x00000a55 LBB0_101
0x45, 0x31, 0xc9, //0x00000a55 xorl %r9d, %r9d
0x45, 0x89, 0xea, //0x00000a58 movl %r13d, %r10d
0x41, 0x83, 0xfa, 0x64, //0x00000a5b cmpl $100, %r10d
0x0f, 0x82, 0xe8, 0xff, 0xff, 0xff, //0x00000a5f jb LBB0_102
//0x00000a65 LBB0_105
0x48, 0xff, 0xc8, //0x00000a65 decq %rax
0x48, 0x8d, 0x15, 0xf1, 0x02, 0x00, 0x00, //0x00000a68 leaq $753(%rip), %rdx /* _Digits+0(%rip) */
0x90, //0x00000a6f .p2align 4, 0x90
//0x00000a70 LBB0_106
0x44, 0x89, 0xd1, //0x00000a70 movl %r10d, %ecx
0x48, 0x69, 0xc9, 0x1f, 0x85, 0xeb, 0x51, //0x00000a73 imulq $1374389535, %rcx, %rcx
0x48, 0xc1, 0xe9, 0x25, //0x00000a7a shrq $37, %rcx
0x6b, 0xd9, 0x64, //0x00000a7e imull $100, %ecx, %ebx
0x44, 0x89, 0xd6, //0x00000a81 movl %r10d, %esi
0x29, 0xde, //0x00000a84 subl %ebx, %esi
0x0f, 0xb7, 0x34, 0x72, //0x00000a86 movzwl (%rdx,%rsi,2), %esi
0x66, 0x89, 0x70, 0xff, //0x00000a8a movw %si, $-1(%rax)
0x48, 0x83, 0xc0, 0xfe, //0x00000a8e addq $-2, %rax
0x41, 0x81, 0xfa, 0x0f, 0x27, 0x00, 0x00, //0x00000a92 cmpl $9999, %r10d
0x41, 0x89, 0xca, //0x00000a99 movl %ecx, %r10d
0x0f, 0x87, 0xce, 0xff, 0xff, 0xff, //0x00000a9c ja LBB0_106
//0x00000aa2 LBB0_107
0x83, 0xf9, 0x0a, //0x00000aa2 cmpl $10, %ecx
0x0f, 0x82, 0x16, 0x00, 0x00, 0x00, //0x00000aa5 jb LBB0_109
0x89, 0xc8, //0x00000aab movl %ecx, %eax
0x48, 0x8d, 0x0d, 0xac, 0x02, 0x00, 0x00, //0x00000aad leaq $684(%rip), %rcx /* _Digits+0(%rip) */
0x0f, 0xb7, 0x04, 0x41, //0x00000ab4 movzwl (%rcx,%rax,2), %eax
0x66, 0x41, 0x89, 0x00, //0x00000ab8 movw %ax, (%r8)
0xe9, 0x06, 0x00, 0x00, 0x00, //0x00000abc jmp LBB0_110
//0x00000ac1 LBB0_109
0x80, 0xc1, 0x30, //0x00000ac1 addb $48, %cl
0x41, 0x88, 0x08, //0x00000ac4 movb %cl, (%r8)
//0x00000ac7 LBB0_110
0x4d, 0x29, 0xcc, //0x00000ac7 subq %r9, %r12
0x49, 0x8d, 0x74, 0x24, 0x01, //0x00000aca leaq $1(%r12), %rsi
0x49, 0x8d, 0x54, 0x24, 0x61, //0x00000acf leaq $97(%r12), %rdx
0x49, 0x8d, 0x44, 0x24, 0x02, //0x00000ad4 leaq $2(%r12), %rax
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, //0x00000ad9 .p2align 4, 0x90
//0x00000ae0 LBB0_111
0x48, 0xff, 0xca, //0x00000ae0 decq %rdx
0x48, 0xff, 0xce, //0x00000ae3 decq %rsi
0x48, 0xff, 0xc8, //0x00000ae6 decq %rax
0x43, 0x80, 0x7c, 0x20, 0xff, 0x30, //0x00000ae9 cmpb $48, $-1(%r8,%r12)
0x4d, 0x8d, 0x64, 0x24, 0xff, //0x00000aef leaq $-1(%r12), %r12
0x0f, 0x84, 0xe6, 0xff, 0xff, 0xff, //0x00000af4 je LBB0_111
0x4d, 0x8d, 0x0c, 0x30, //0x00000afa leaq (%r8,%rsi), %r9
0x45, 0x85, 0xff, //0x00000afe testl %r15d, %r15d
0x0f, 0x8e, 0x8b, 0x00, 0x00, 0x00, //0x00000b01 jle LBB0_116
0x44, 0x89, 0xc9, //0x00000b07 movl %r9d, %ecx
0x44, 0x29, 0xc1, //0x00000b0a subl %r8d, %ecx
0x41, 0x39, 0xcf, //0x00000b0d cmpl %ecx, %r15d
0x0f, 0x8d, 0x23, 0x00, 0x00, 0x00, //0x00000b10 jge LBB0_117
0x43, 0x8d, 0x0c, 0x07, //0x00000b16 leal (%r15,%r8), %ecx
0x41, 0x29, 0xc9, //0x00000b1a subl %ecx, %r9d
0x49, 0x8d, 0x49, 0xff, //0x00000b1d leaq $-1(%r9), %rcx
0x45, 0x89, 0xca, //0x00000b21 movl %r9d, %r10d
0x41, 0x83, 0xe2, 0x03, //0x00000b24 andl $3, %r10d
0x48, 0x83, 0xf9, 0x03, //0x00000b28 cmpq $3, %rcx
0x0f, 0x83, 0x81, 0x00, 0x00, 0x00, //0x00000b2c jae LBB0_121
0x31, 0xc9, //0x00000b32 xorl %ecx, %ecx
0xe9, 0xa3, 0x00, 0x00, 0x00, //0x00000b34 jmp LBB0_124
//0x00000b39 LBB0_117
0x0f, 0x8e, 0x53, 0x00, 0x00, 0x00, //0x00000b39 jle LBB0_116
0x45, 0x01, 0xc7, //0x00000b3f addl %r8d, %r15d
0x45, 0x89, 0xce, //0x00000b42 movl %r9d, %r14d
0x41, 0xf7, 0xd6, //0x00000b45 notl %r14d
0x45, 0x01, 0xfe, //0x00000b48 addl %r15d, %r14d
0x45, 0x31, 0xd2, //0x00000b4b xorl %r10d, %r10d
0x4d, 0x89, 0xcb, //0x00000b4e movq %r9, %r11
0x41, 0x83, 0xfe, 0x7e, //0x00000b51 cmpl $126, %r14d
0x0f, 0x86, 0xb4, 0x01, 0x00, 0x00, //0x00000b55 jbe LBB0_135
0x49, 0xff, 0xc6, //0x00000b5b incq %r14
0x4d, 0x89, 0xf2, //0x00000b5e movq %r14, %r10
0x49, 0x83, 0xe2, 0x80, //0x00000b61 andq $-128, %r10
0x4f, 0x8d, 0x1c, 0x10, //0x00000b65 leaq (%r8,%r10), %r11
0x49, 0x8d, 0x5a, 0x80, //0x00000b69 leaq $-128(%r10), %rbx
0x48, 0x89, 0xd9, //0x00000b6d movq %rbx, %rcx
0x48, 0xc1, 0xe9, 0x07, //0x00000b70 shrq $7, %rcx
0x48, 0xff, 0xc1, //0x00000b74 incq %rcx
0x41, 0x89, 0xcc, //0x00000b77 movl %ecx, %r12d
0x41, 0x83, 0xe4, 0x03, //0x00000b7a andl $3, %r12d
0x48, 0x81, 0xfb, 0x80, 0x01, 0x00, 0x00, //0x00000b7e cmpq $384, %rbx
0x0f, 0x83, 0x8f, 0x00, 0x00, 0x00, //0x00000b85 jae LBB0_129
0x31, 0xc9, //0x00000b8b xorl %ecx, %ecx
0xe9, 0x30, 0x01, 0x00, 0x00, //0x00000b8d jmp LBB0_131
//0x00000b92 LBB0_116
0x4d, 0x89, 0xc8, //0x00000b92 movq %r9, %r8
0xe9, 0x96, 0x01, 0x00, 0x00, //0x00000b95 jmp LBB0_137
//0x00000b9a LBB0_103
0x41, 0xb9, 0x04, 0x00, 0x00, 0x00, //0x00000b9a movl $4, %r9d
0x48, 0x83, 0xc0, 0xfc, //0x00000ba0 addq $-4, %rax
0x41, 0x83, 0xfa, 0x64, //0x00000ba4 cmpl $100, %r10d
0x0f, 0x82, 0x9f, 0xfe, 0xff, 0xff, //0x00000ba8 jb LBB0_102
0xe9, 0xb2, 0xfe, 0xff, 0xff, //0x00000bae jmp LBB0_105
//0x00000bb3 LBB0_121
0x4d, 0x89, 0xd3, //0x00000bb3 movq %r10, %r11
0x4d, 0x29, 0xcb, //0x00000bb6 subq %r9, %r11
0x31, 0xc9, //0x00000bb9 xorl %ecx, %ecx
0x90, 0x90, 0x90, 0x90, 0x90, //0x00000bbb .p2align 4, 0x90
//0x00000bc0 LBB0_122
0x49, 0x8d, 0x1c, 0x08, //0x00000bc0 leaq (%r8,%rcx), %rbx
0x8b, 0x54, 0x1e, 0xfc, //0x00000bc4 movl $-4(%rsi,%rbx), %edx
0x89, 0x54, 0x1e, 0xfd, //0x00000bc8 movl %edx, $-3(%rsi,%rbx)
0x48, 0x83, 0xc1, 0xfc, //0x00000bcc addq $-4, %rcx
0x49, 0x39, 0xcb, //0x00000bd0 cmpq %rcx, %r11
0x0f, 0x85, 0xe7, 0xff, 0xff, 0xff, //0x00000bd3 jne LBB0_122
0x48, 0xf7, 0xd9, //0x00000bd9 negq %rcx
//0x00000bdc LBB0_124
0x4d, 0x85, 0xd2, //0x00000bdc testq %r10, %r10
0x0f, 0x84, 0x25, 0x00, 0x00, 0x00, //0x00000bdf je LBB0_127
0x49, 0xf7, 0xda, //0x00000be5 negq %r10
0x4c, 0x89, 0xc2, //0x00000be8 movq %r8, %rdx
0x48, 0x29, 0xca, //0x00000beb subq %rcx, %rdx
0x31, 0xc9, //0x00000bee xorl %ecx, %ecx
//0x00000bf0 .p2align 4, 0x90
//0x00000bf0 LBB0_126
0x48, 0x8d, 0x34, 0x0a, //0x00000bf0 leaq (%rdx,%rcx), %rsi
0x41, 0x0f, 0xb6, 0x1c, 0x34, //0x00000bf4 movzbl (%r12,%rsi), %ebx
0x41, 0x88, 0x5c, 0x34, 0x01, //0x00000bf9 movb %bl, $1(%r12,%rsi)
0x48, 0xff, 0xc9, //0x00000bfe decq %rcx
0x49, 0x39, 0xca, //0x00000c01 cmpq %rcx, %r10
0x0f, 0x85, 0xe6, 0xff, 0xff, 0xff, //0x00000c04 jne LBB0_126
//0x00000c0a LBB0_127
0x49, 0x63, 0xcf, //0x00000c0a movslq %r15d, %rcx
0x41, 0xc6, 0x04, 0x08, 0x2e, //0x00000c0d movb $46, (%r8,%rcx)
0x49, 0x01, 0xc0, //0x00000c12 addq %rax, %r8
0xe9, 0x16, 0x01, 0x00, 0x00, //0x00000c15 jmp LBB0_137
//0x00000c1a LBB0_129
0x4c, 0x89, 0xe3, //0x00000c1a movq %r12, %rbx
0x48, 0x29, 0xcb, //0x00000c1d subq %rcx, %rbx
0x31, 0xc9, //0x00000c20 xorl %ecx, %ecx
0xc5, 0xfe, 0x6f, 0x05, 0xd6, 0xf3, 0xff, 0xff, //0x00000c22 vmovdqu $-3114(%rip), %ymm0 /* LCPI0_0+0(%rip) */
//0x00000c2a LBB0_130
0x49, 0x8d, 0x04, 0x08, //0x00000c2a leaq (%r8,%rcx), %rax
0xc5, 0xfe, 0x7f, 0x04, 0x06, //0x00000c2e vmovdqu %ymm0, (%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x44, 0x06, 0x20, //0x00000c33 vmovdqu %ymm0, $32(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x44, 0x06, 0x40, //0x00000c39 vmovdqu %ymm0, $64(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x44, 0x06, 0x60, //0x00000c3f vmovdqu %ymm0, $96(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x06, 0x80, 0x00, 0x00, 0x00, //0x00000c45 vmovdqu %ymm0, $128(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x06, 0xa0, 0x00, 0x00, 0x00, //0x00000c4e vmovdqu %ymm0, $160(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x06, 0xc0, 0x00, 0x00, 0x00, //0x00000c57 vmovdqu %ymm0, $192(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x06, 0xe0, 0x00, 0x00, 0x00, //0x00000c60 vmovdqu %ymm0, $224(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x06, 0x00, 0x01, 0x00, 0x00, //0x00000c69 vmovdqu %ymm0, $256(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x06, 0x20, 0x01, 0x00, 0x00, //0x00000c72 vmovdqu %ymm0, $288(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x06, 0x40, 0x01, 0x00, 0x00, //0x00000c7b vmovdqu %ymm0, $320(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x06, 0x60, 0x01, 0x00, 0x00, //0x00000c84 vmovdqu %ymm0, $352(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x06, 0x80, 0x01, 0x00, 0x00, //0x00000c8d vmovdqu %ymm0, $384(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x06, 0xa0, 0x01, 0x00, 0x00, //0x00000c96 vmovdqu %ymm0, $416(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x06, 0xc0, 0x01, 0x00, 0x00, //0x00000c9f vmovdqu %ymm0, $448(%rsi,%rax)
0xc5, 0xfe, 0x7f, 0x84, 0x06, 0xe0, 0x01, 0x00, 0x00, //0x00000ca8 vmovdqu %ymm0, $480(%rsi,%rax)
0x48, 0x81, 0xc1, 0x00, 0x02, 0x00, 0x00, //0x00000cb1 addq $512, %rcx
0x48, 0x83, 0xc3, 0x04, //0x00000cb8 addq $4, %rbx
0x0f, 0x85, 0x68, 0xff, 0xff, 0xff, //0x00000cbc jne LBB0_130
//0x00000cc2 LBB0_131
0x49, 0x01, 0xf3, //0x00000cc2 addq %rsi, %r11
0x4d, 0x85, 0xe4, //0x00000cc5 testq %r12, %r12
0x0f, 0x84, 0x35, 0x00, 0x00, 0x00, //0x00000cc8 je LBB0_134
0x49, 0x01, 0xc8, //0x00000cce addq %rcx, %r8
0x49, 0x01, 0xd0, //0x00000cd1 addq %rdx, %r8
0x49, 0xf7, 0xdc, //0x00000cd4 negq %r12
0xc5, 0xfe, 0x6f, 0x05, 0x21, 0xf3, 0xff, 0xff, //0x00000cd7 vmovdqu $-3295(%rip), %ymm0 /* LCPI0_0+0(%rip) */
//0x00000cdf LBB0_133
0xc4, 0xc1, 0x7e, 0x7f, 0x40, 0xa0, //0x00000cdf vmovdqu %ymm0, $-96(%r8)
0xc4, 0xc1, 0x7e, 0x7f, 0x40, 0xc0, //0x00000ce5 vmovdqu %ymm0, $-64(%r8)
0xc4, 0xc1, 0x7e, 0x7f, 0x40, 0xe0, //0x00000ceb vmovdqu %ymm0, $-32(%r8)
0xc4, 0xc1, 0x7e, 0x7f, 0x00, //0x00000cf1 vmovdqu %ymm0, (%r8)
0x49, 0x83, 0xe8, 0x80, //0x00000cf6 subq $-128, %r8
0x49, 0xff, 0xc4, //0x00000cfa incq %r12
0x0f, 0x85, 0xdc, 0xff, 0xff, 0xff, //0x00000cfd jne LBB0_133
//0x00000d03 LBB0_134
0x4d, 0x89, 0xd8, //0x00000d03 movq %r11, %r8
0x4d, 0x39, 0xd6, //0x00000d06 cmpq %r10, %r14
0x0f, 0x84, 0x21, 0x00, 0x00, 0x00, //0x00000d09 je LBB0_137
//0x00000d0f LBB0_135
0x45, 0x29, 0xd7, //0x00000d0f subl %r10d, %r15d
0x45, 0x29, 0xcf, //0x00000d12 subl %r9d, %r15d
0x4d, 0x89, 0xd8, //0x00000d15 movq %r11, %r8
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, //0x00000d18 .p2align 4, 0x90
//0x00000d20 LBB0_136
0x41, 0xc6, 0x00, 0x30, //0x00000d20 movb $48, (%r8)
0x49, 0xff, 0xc0, //0x00000d24 incq %r8
0x41, 0xff, 0xcf, //0x00000d27 decl %r15d
0x0f, 0x85, 0xf0, 0xff, 0xff, 0xff, //0x00000d2a jne LBB0_136
//0x00000d30 LBB0_137
0x41, 0x29, 0xf8, //0x00000d30 subl %edi, %r8d
//0x00000d33 LBB0_138
0x44, 0x89, 0xc0, //0x00000d33 movl %r8d, %eax
0x5b, //0x00000d36 popq %rbx
0x41, 0x5c, //0x00000d37 popq %r12
0x41, 0x5d, //0x00000d39 popq %r13
0x41, 0x5e, //0x00000d3b popq %r14
0x41, 0x5f, //0x00000d3d popq %r15
0x5d, //0x00000d3f popq %rbp
0xc5, 0xf8, 0x77, //0x00000d40 vzeroupper
0xc3, //0x00000d43 retq
//0x00000d44 LBB0_139
0x45, 0x31, 0xc0, //0x00000d44 xorl %r8d, %r8d
0xe9, 0xe7, 0xff, 0xff, 0xff, //0x00000d47 jmp LBB0_138
//0x00000d4c LBB0_140
0x41, 0xbf, 0x6b, 0xff, 0xff, 0xff, //0x00000d4c movl $-149, %r15d
0x89, 0xc6, //0x00000d52 movl %eax, %esi
0xe9, 0x46, 0xf3, 0xff, 0xff, //0x00000d54 jmp LBB0_5
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000d59 .p2align 4, 0x00
//0x00000d60 _Digits
0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, //0x00000d60 QUAD $0x3330323031303030; QUAD $0x3730363035303430 // .ascii 16, '0001020304050607'
0x30, 0x38, 0x30, 0x39, 0x31, 0x30, 0x31, 0x31, 0x31, 0x32, 0x31, 0x33, 0x31, 0x34, 0x31, 0x35, //0x00000d70 QUAD $0x3131303139303830; QUAD $0x3531343133313231 // .ascii 16, '0809101112131415'
0x31, 0x36, 0x31, 0x37, 0x31, 0x38, 0x31, 0x39, 0x32, 0x30, 0x32, 0x31, 0x32, 0x32, 0x32, 0x33, //0x00000d80 QUAD $0x3931383137313631; QUAD $0x3332323231323032 // .ascii 16, '1617181920212223'
0x32, 0x34, 0x32, 0x35, 0x32, 0x36, 0x32, 0x37, 0x32, 0x38, 0x32, 0x39, 0x33, 0x30, 0x33, 0x31, //0x00000d90 QUAD $0x3732363235323432; QUAD $0x3133303339323832 // .ascii 16, '2425262728293031'
0x33, 0x32, 0x33, 0x33, 0x33, 0x34, 0x33, 0x35, 0x33, 0x36, 0x33, 0x37, 0x33, 0x38, 0x33, 0x39, //0x00000da0 QUAD $0x3533343333333233; QUAD $0x3933383337333633 // .ascii 16, '3233343536373839'
0x34, 0x30, 0x34, 0x31, 0x34, 0x32, 0x34, 0x33, 0x34, 0x34, 0x34, 0x35, 0x34, 0x36, 0x34, 0x37, //0x00000db0 QUAD $0x3334323431343034; QUAD $0x3734363435343434 // .ascii 16, '4041424344454647'
0x34, 0x38, 0x34, 0x39, 0x35, 0x30, 0x35, 0x31, 0x35, 0x32, 0x35, 0x33, 0x35, 0x34, 0x35, 0x35, //0x00000dc0 QUAD $0x3135303539343834; QUAD $0x3535343533353235 // .ascii 16, '4849505152535455'
0x35, 0x36, 0x35, 0x37, 0x35, 0x38, 0x35, 0x39, 0x36, 0x30, 0x36, 0x31, 0x36, 0x32, 0x36, 0x33, //0x00000dd0 QUAD $0x3935383537353635; QUAD $0x3336323631363036 // .ascii 16, '5657585960616263'
0x36, 0x34, 0x36, 0x35, 0x36, 0x36, 0x36, 0x37, 0x36, 0x38, 0x36, 0x39, 0x37, 0x30, 0x37, 0x31, //0x00000de0 QUAD $0x3736363635363436; QUAD $0x3137303739363836 // .ascii 16, '6465666768697071'
0x37, 0x32, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35, 0x37, 0x36, 0x37, 0x37, 0x37, 0x38, 0x37, 0x39, //0x00000df0 QUAD $0x3537343733373237; QUAD $0x3937383737373637 // .ascii 16, '7273747576777879'
0x38, 0x30, 0x38, 0x31, 0x38, 0x32, 0x38, 0x33, 0x38, 0x34, 0x38, 0x35, 0x38, 0x36, 0x38, 0x37, //0x00000e00 QUAD $0x3338323831383038; QUAD $0x3738363835383438 // .ascii 16, '8081828384858687'
0x38, 0x38, 0x38, 0x39, 0x39, 0x30, 0x39, 0x31, 0x39, 0x32, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35, //0x00000e10 QUAD $0x3139303939383838; QUAD $0x3539343933393239 // .ascii 16, '8889909192939495'
0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39, //0x00000e20 QUAD $0x3939383937393639 // .ascii 8, '96979899'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000e28 .p2align 4, 0x00
//0x00000e30 _pow10_ceil_sig_f32.g
0xf5, 0xfc, 0x43, 0x4b, 0x2c, 0xb3, 0xce, 0x81, //0x00000e30 .quad -9093133594791772939
0x32, 0xfc, 0x14, 0x5e, 0xf7, 0x5f, 0x42, 0xa2, //0x00000e38 .quad -6754730975062328270
0x3f, 0x3b, 0x9a, 0x35, 0xf5, 0xf7, 0xd2, 0xca, //0x00000e40 .quad -3831727700400522433
0x0e, 0xca, 0x00, 0x83, 0xf2, 0xb5, 0x87, 0xfd, //0x00000e48 .quad -177973607073265138
0x49, 0x7e, 0xe0, 0x91, 0xb7, 0xd1, 0x74, 0x9e, //0x00000e50 .quad -7028762532061872567
0xdb, 0x9d, 0x58, 0x76, 0x25, 0x06, 0x12, 0xc6, //0x00000e58 .quad -4174267146649952805
0x52, 0xc5, 0xee, 0xd3, 0xae, 0x87, 0x96, 0xf7, //0x00000e60 .quad -606147914885053102
0x53, 0x3b, 0x75, 0x44, 0xcd, 0x14, 0xbe, 0x9a, //0x00000e68 .quad -7296371474444240045
0x28, 0x8a, 0x92, 0x95, 0x00, 0x9a, 0x6d, 0xc1, //0x00000e70 .quad -4508778324627912152
0xb2, 0x2c, 0xf7, 0xba, 0x80, 0x00, 0xc9, 0xf1, //0x00000e78 .quad -1024286887357502286
0xef, 0x7b, 0xda, 0x74, 0x50, 0xa0, 0x1d, 0x97, //0x00000e80 .quad -7557708332239520785
0xeb, 0x1a, 0x11, 0x92, 0x64, 0x08, 0xe5, 0xbc, //0x00000e88 .quad -4835449396872013077
0xa6, 0x61, 0x95, 0xb6, 0x7d, 0x4a, 0x1e, 0xec, //0x00000e90 .quad -1432625727662628442
0x08, 0x5d, 0x1d, 0x92, 0x8e, 0xee, 0x92, 0x93, //0x00000e98 .quad -7812920107430224632
0x4a, 0xb4, 0xa4, 0x36, 0x32, 0xaa, 0x77, 0xb8, //0x00000ea0 .quad -5154464115860392886
0x5c, 0xe1, 0x4d, 0xc4, 0xbe, 0x94, 0x95, 0xe6, //0x00000ea8 .quad -1831394126398103204
0xda, 0xac, 0xb0, 0x3a, 0xf7, 0x7c, 0x1d, 0x90, //0x00000eb0 .quad -8062150356639896358
0x10, 0xd8, 0x5c, 0x09, 0x35, 0xdc, 0x24, 0xb4, //0x00000eb8 .quad -5466001927372482544
0x14, 0x0e, 0xb4, 0x4b, 0x42, 0x13, 0x2e, 0xe1, //0x00000ec0 .quad -2220816390788215276
0xcc, 0x88, 0x50, 0x6f, 0x09, 0xcc, 0xbc, 0x8c, //0x00000ec8 .quad -8305539271883716404
0xff, 0xaa, 0x24, 0xcb, 0x0b, 0xff, 0xeb, 0xaf, //0x00000ed0 .quad -5770238071427257601
0xbf, 0xd5, 0xed, 0xbd, 0xce, 0xfe, 0xe6, 0xdb, //0x00000ed8 .quad -2601111570856684097
0x98, 0xa5, 0xb4, 0x36, 0x41, 0x5f, 0x70, 0x89, //0x00000ee0 .quad -8543223759426509416
0xfd, 0xce, 0x61, 0x84, 0x11, 0x77, 0xcc, 0xab, //0x00000ee8 .quad -6067343680855748867
0xbd, 0x42, 0x7a, 0xe5, 0xd5, 0x94, 0xbf, 0xd6, //0x00000ef0 .quad -2972493582642298179
0xb6, 0x69, 0x6c, 0xaf, 0x05, 0xbd, 0x37, 0x86, //0x00000ef8 .quad -8775337516792518218
0x24, 0x84, 0x47, 0x1b, 0x47, 0xac, 0xc5, 0xa7, //0x00000f00 .quad -6357485877563259868
0x2c, 0x65, 0x19, 0xe2, 0x58, 0x17, 0xb7, 0xd1, //0x00000f08 .quad -3335171328526686932
0x3c, 0xdf, 0x4f, 0x8d, 0x97, 0x6e, 0x12, 0x83, //0x00000f10 .quad -9002011107970261188
0x0b, 0xd7, 0xa3, 0x70, 0x3d, 0x0a, 0xd7, 0xa3, //0x00000f18 .quad -6640827866535438581
0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, //0x00000f20 .quad -3689348814741910323
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, //0x00000f28 .quad -9223372036854775808
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, //0x00000f30 .quad -6917529027641081856
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, //0x00000f38 .quad -4035225266123964416
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, //0x00000f40 .quad -432345564227567616
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x9c, //0x00000f48 .quad -7187745005283311616
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xc3, //0x00000f50 .quad -4372995238176751616
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xf4, //0x00000f58 .quad -854558029293551616
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x96, 0x98, //0x00000f60 .quad -7451627795949551616
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xbc, 0xbe, //0x00000f68 .quad -4702848726509551616
0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6b, 0xee, //0x00000f70 .quad -1266874889709551616
0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x02, 0x95, //0x00000f78 .quad -7709325833709551616
0x00, 0x00, 0x00, 0x00, 0x40, 0xb7, 0x43, 0xba, //0x00000f80 .quad -5024971273709551616
0x00, 0x00, 0x00, 0x00, 0x10, 0xa5, 0xd4, 0xe8, //0x00000f88 .quad -1669528073709551616
0x00, 0x00, 0x00, 0x00, 0x2a, 0xe7, 0x84, 0x91, //0x00000f90 .quad -7960984073709551616
0x00, 0x00, 0x00, 0x80, 0xf4, 0x20, 0xe6, 0xb5, //0x00000f98 .quad -5339544073709551616
0x00, 0x00, 0x00, 0xa0, 0x31, 0xa9, 0x5f, 0xe3, //0x00000fa0 .quad -2062744073709551616
0x00, 0x00, 0x00, 0x04, 0xbf, 0xc9, 0x1b, 0x8e, //0x00000fa8 .quad -8206744073709551616
0x00, 0x00, 0x00, 0xc5, 0x2e, 0xbc, 0xa2, 0xb1, //0x00000fb0 .quad -5646744073709551616
0x00, 0x00, 0x40, 0x76, 0x3a, 0x6b, 0x0b, 0xde, //0x00000fb8 .quad -2446744073709551616
0x00, 0x00, 0xe8, 0x89, 0x04, 0x23, 0xc7, 0x8a, //0x00000fc0 .quad -8446744073709551616
0x00, 0x00, 0x62, 0xac, 0xc5, 0xeb, 0x78, 0xad, //0x00000fc8 .quad -5946744073709551616
0x00, 0x80, 0x7a, 0x17, 0xb7, 0x26, 0xd7, 0xd8, //0x00000fd0 .quad -2821744073709551616
0x00, 0x90, 0xac, 0x6e, 0x32, 0x78, 0x86, 0x87, //0x00000fd8 .quad -8681119073709551616
0x00, 0xb4, 0x57, 0x0a, 0x3f, 0x16, 0x68, 0xa9, //0x00000fe0 .quad -6239712823709551616
0x00, 0xa1, 0xed, 0xcc, 0xce, 0x1b, 0xc2, 0xd3, //0x00000fe8 .quad -3187955011209551616
0xa0, 0x84, 0x14, 0x40, 0x61, 0x51, 0x59, 0x84, //0x00000ff0 .quad -8910000909647051616
0xc8, 0xa5, 0x19, 0x90, 0xb9, 0xa5, 0x6f, 0xa5, //0x00000ff8 .quad -6525815118631426616
0x3a, 0x0f, 0x20, 0xf4, 0x27, 0x8f, 0xcb, 0xce, //0x00001000 .quad -3545582879861895366
0x85, 0x09, 0x94, 0xf8, 0x78, 0x39, 0x3f, 0x81, //0x00001008 .quad -9133518327554766459
0xe6, 0x0b, 0xb9, 0x36, 0xd7, 0x07, 0x8f, 0xa1, //0x00001010 .quad -6805211891016070170
0xdf, 0x4e, 0x67, 0x04, 0xcd, 0xc9, 0xf2, 0xc9, //0x00001018 .quad -3894828845342699809
0x97, 0x22, 0x81, 0x45, 0x40, 0x7c, 0x6f, 0xfc, //0x00001020 .quad -256850038250986857
0x9e, 0xb5, 0x70, 0x2b, 0xa8, 0xad, 0xc5, 0x9d, //0x00001028 .quad -7078060301547948642
0x06, 0xe3, 0x4c, 0x36, 0x12, 0x19, 0x37, 0xc5, //0x00001030 .quad -4235889358507547898
0xc7, 0x1b, 0xe0, 0xc3, 0x56, 0xdf, 0x84, 0xf6, //0x00001038 .quad -683175679707046969
0x5d, 0x11, 0x6c, 0x3a, 0x96, 0x0b, 0x13, 0x9a, //0x00001040 .quad -7344513827457986211
0xb4, 0x15, 0x07, 0xc9, 0x7b, 0xce, 0x97, 0xc0, //0x00001048 .quad -4568956265895094860
0x21, 0xdb, 0x48, 0xbb, 0x1a, 0xc2, 0xbd, 0xf0, //0x00001050 .quad -1099509313941480671
0xf5, 0x88, 0x0d, 0xb5, 0x50, 0x99, 0x76, 0x96, //0x00001058 .quad -7604722348854507275
0x32, 0xeb, 0x50, 0xe2, 0xa4, 0x3f, 0x14, 0xbc, //0x00001060 .quad -4894216917640746190
0xfe, 0x25, 0xe5, 0x1a, 0x8e, 0x4f, 0x19, 0xeb, //0x00001068 .quad -1506085128623544834
0xbf, 0x37, 0xcf, 0xd0, 0xb8, 0xd1, 0xef, 0x92, //0x00001070 .quad -7858832233030797377
0xae, 0x05, 0x03, 0x05, 0x27, 0xc6, 0xab, 0xb7, //0x00001078 .quad -5211854272861108818
0x1a, 0xc7, 0x43, 0xc6, 0xb0, 0xb7, 0x96, 0xe5, //0x00001080 .quad -1903131822648998118
0x70, 0x5c, 0xea, 0x7b, 0xce, 0x32, 0x7e, 0x8f, //0x00001088 .quad -8106986416796705680
0x8c, 0xf3, 0xe4, 0x1a, 0x82, 0xbf, 0x5d, 0xb3, //0x00001090 .quad -5522047002568494196
}

View file

@ -1,46 +0,0 @@
// +build !noasm !appengine
// Code generated by asm2asm, DO NOT EDIT.
package avx
import (
`github.com/bytedance/sonic/loader`
)
const (
_entry__f64toa = 32
)
const (
_stack__f64toa = 56
)
const (
_size__f64toa = 4704
)
var (
_pcsp__f64toa = [][2]uint32{
{1, 0},
{4, 8},
{6, 16},
{8, 24},
{10, 32},
{12, 40},
{13, 48},
{4614, 56},
{4618, 48},
{4619, 40},
{4621, 32},
{4623, 24},
{4625, 16},
{4627, 8},
{4631, 0},
{4694, 56},
}
)
var _cfunc_f64toa = []loader.CFunc{
{"_f64toa_entry", 0, _entry__f64toa, 0, nil},
{"_f64toa", _entry__f64toa, _size__f64toa, _stack__f64toa, _pcsp__f64toa},
}

File diff suppressed because it is too large Load diff

View file

@ -1,37 +0,0 @@
// Code generated by Makefile, DO NOT EDIT.
// Code generated by Makefile, DO NOT EDIT.
/*
* 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 avx
import (
`unsafe`
`github.com/bytedance/sonic/internal/native/types`
`github.com/bytedance/sonic/internal/rt`
)
var F_get_by_path func(s unsafe.Pointer, p unsafe.Pointer, path unsafe.Pointer, m unsafe.Pointer) (ret int)
var S_get_by_path uintptr
//go:nosplit
func get_by_path(s *string, p *int, path *[]interface{}, m *types.StateMachine) (ret int) {
return F_get_by_path(rt.NoEscape(unsafe.Pointer(s)), rt.NoEscape(unsafe.Pointer(p)), rt.NoEscape(unsafe.Pointer(path)), rt.NoEscape(unsafe.Pointer(m)))
}

View file

@ -1,45 +0,0 @@
// +build !noasm !appengine
// Code generated by asm2asm, DO NOT EDIT.
package avx
import (
`github.com/bytedance/sonic/loader`
)
const (
_entry__get_by_path = 224
)
const (
_stack__get_by_path = 272
)
const (
_size__get_by_path = 20184
)
var (
_pcsp__get_by_path = [][2]uint32{
{1, 0},
{4, 8},
{6, 16},
{8, 24},
{10, 32},
{12, 40},
{13, 48},
{17077, 272},
{17078, 264},
{17080, 256},
{17082, 248},
{17084, 240},
{17086, 232},
{17090, 224},
{20184, 272},
}
)
var _cfunc_get_by_path = []loader.CFunc{
{"_get_by_path_entry", 0, _entry__get_by_path, 0, nil},
{"_get_by_path", _entry__get_by_path, _size__get_by_path, _stack__get_by_path, _pcsp__get_by_path},
}

File diff suppressed because it is too large Load diff

View file

@ -1,45 +0,0 @@
// +build !noasm !appengine
// Code generated by asm2asm, DO NOT EDIT.
package avx
import (
`github.com/bytedance/sonic/loader`
)
const (
_entry__html_escape = 64
)
const (
_stack__html_escape = 72
)
const (
_size__html_escape = 1248
)
var (
_pcsp__html_escape = [][2]uint32{
{1, 0},
{4, 8},
{6, 16},
{8, 24},
{10, 32},
{12, 40},
{13, 48},
{1224, 72},
{1228, 48},
{1229, 40},
{1231, 32},
{1233, 24},
{1235, 16},
{1237, 8},
{1239, 0},
}
)
var _cfunc_html_escape = []loader.CFunc{
{"_html_escape_entry", 0, _entry__html_escape, 0, nil},
{"_html_escape", _entry__html_escape, _size__html_escape, _stack__html_escape, _pcsp__html_escape},
}

View file

@ -1,620 +0,0 @@
// +build amd64
// Code generated by asm2asm, DO NOT EDIT.
package avx
var _text_html_escape = []byte{
// .p2align 4, 0x00
// LCPI0_0
0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, // QUAD $0x2626262626262626; QUAD $0x2626262626262626 // .space 16, '&&&&&&&&&&&&&&&&'
//0x00000010 LCPI0_1
0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, //0x00000010 QUAD $0xe2e2e2e2e2e2e2e2; QUAD $0xe2e2e2e2e2e2e2e2 // .space 16, '\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2'
//0x00000020 LCPI0_2
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, //0x00000020 QUAD $0x0202020202020202; QUAD $0x0202020202020202 // .space 16, '\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02'
//0x00000030 LCPI0_3
0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, //0x00000030 QUAD $0x3e3e3e3e3e3e3e3e; QUAD $0x3e3e3e3e3e3e3e3e // .space 16, '>>>>>>>>>>>>>>>>'
//0x00000040 .p2align 4, 0x90
//0x00000040 _html_escape
0x55, //0x00000040 pushq %rbp
0x48, 0x89, 0xe5, //0x00000041 movq %rsp, %rbp
0x41, 0x57, //0x00000044 pushq %r15
0x41, 0x56, //0x00000046 pushq %r14
0x41, 0x55, //0x00000048 pushq %r13
0x41, 0x54, //0x0000004a pushq %r12
0x53, //0x0000004c pushq %rbx
0x48, 0x83, 0xec, 0x18, //0x0000004d subq $24, %rsp
0x48, 0x89, 0x4d, 0xc0, //0x00000051 movq %rcx, $-64(%rbp)
0x49, 0x89, 0xd2, //0x00000055 movq %rdx, %r10
0x48, 0x89, 0x55, 0xc8, //0x00000058 movq %rdx, $-56(%rbp)
0x48, 0x89, 0x7d, 0xd0, //0x0000005c movq %rdi, $-48(%rbp)
0x48, 0x89, 0xf8, //0x00000060 movq %rdi, %rax
0x48, 0x85, 0xf6, //0x00000063 testq %rsi, %rsi
0x0f, 0x8e, 0x73, 0x04, 0x00, 0x00, //0x00000066 jle LBB0_59
0x48, 0x8b, 0x45, 0xc0, //0x0000006c movq $-64(%rbp), %rax
0x4c, 0x8b, 0x08, //0x00000070 movq (%rax), %r9
0xc5, 0xfa, 0x6f, 0x05, 0x85, 0xff, 0xff, 0xff, //0x00000073 vmovdqu $-123(%rip), %xmm0 /* LCPI0_0+0(%rip) */
0xc5, 0xfa, 0x6f, 0x0d, 0x8d, 0xff, 0xff, 0xff, //0x0000007b vmovdqu $-115(%rip), %xmm1 /* LCPI0_1+0(%rip) */
0xc5, 0xfa, 0x6f, 0x15, 0x95, 0xff, 0xff, 0xff, //0x00000083 vmovdqu $-107(%rip), %xmm2 /* LCPI0_2+0(%rip) */
0xc5, 0xfa, 0x6f, 0x1d, 0x9d, 0xff, 0xff, 0xff, //0x0000008b vmovdqu $-99(%rip), %xmm3 /* LCPI0_3+0(%rip) */
0x49, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x50, //0x00000093 movabsq $5764607797912141824, %r14
0x4c, 0x8d, 0x1d, 0x7c, 0x04, 0x00, 0x00, //0x0000009d leaq $1148(%rip), %r11 /* __HtmlQuoteTab+0(%rip) */
0x4c, 0x8b, 0x7d, 0xd0, //0x000000a4 movq $-48(%rbp), %r15
0x4c, 0x8b, 0x55, 0xc8, //0x000000a8 movq $-56(%rbp), %r10
0x90, 0x90, 0x90, 0x90, //0x000000ac .p2align 4, 0x90
//0x000000b0 LBB0_2
0x4d, 0x85, 0xc9, //0x000000b0 testq %r9, %r9
0x0f, 0x8e, 0x45, 0x04, 0x00, 0x00, //0x000000b3 jle LBB0_61
0x48, 0x83, 0xfe, 0x0f, //0x000000b9 cmpq $15, %rsi
0x0f, 0x9f, 0xc3, //0x000000bd setg %bl
0x4d, 0x89, 0xcc, //0x000000c0 movq %r9, %r12
0x4d, 0x89, 0xd0, //0x000000c3 movq %r10, %r8
0x48, 0x89, 0xf0, //0x000000c6 movq %rsi, %rax
0x4d, 0x89, 0xfd, //0x000000c9 movq %r15, %r13
0x49, 0x83, 0xf9, 0x10, //0x000000cc cmpq $16, %r9
0x0f, 0x8c, 0x7a, 0x00, 0x00, 0x00, //0x000000d0 jl LBB0_9
0x48, 0x83, 0xfe, 0x10, //0x000000d6 cmpq $16, %rsi
0x0f, 0x8c, 0x70, 0x00, 0x00, 0x00, //0x000000da jl LBB0_9
0x4d, 0x89, 0xfd, //0x000000e0 movq %r15, %r13
0x48, 0x89, 0xf0, //0x000000e3 movq %rsi, %rax
0x4d, 0x89, 0xd0, //0x000000e6 movq %r10, %r8
0x4c, 0x89, 0xc9, //0x000000e9 movq %r9, %rcx
0x90, 0x90, 0x90, 0x90, //0x000000ec .p2align 4, 0x90
//0x000000f0 LBB0_6
0xc4, 0xc1, 0x7a, 0x6f, 0x65, 0x00, //0x000000f0 vmovdqu (%r13), %xmm4
0xc5, 0xd9, 0x74, 0xe8, //0x000000f6 vpcmpeqb %xmm0, %xmm4, %xmm5
0xc5, 0xd9, 0x74, 0xf1, //0x000000fa vpcmpeqb %xmm1, %xmm4, %xmm6
0xc5, 0xc9, 0xeb, 0xed, //0x000000fe vpor %xmm5, %xmm6, %xmm5
0xc5, 0xd9, 0xeb, 0xf2, //0x00000102 vpor %xmm2, %xmm4, %xmm6
0xc5, 0xc9, 0x74, 0xf3, //0x00000106 vpcmpeqb %xmm3, %xmm6, %xmm6
0xc5, 0xd1, 0xeb, 0xee, //0x0000010a vpor %xmm6, %xmm5, %xmm5
0xc4, 0xc1, 0x7a, 0x7f, 0x20, //0x0000010e vmovdqu %xmm4, (%r8)
0xc5, 0xf9, 0xd7, 0xd5, //0x00000113 vpmovmskb %xmm5, %edx
0x66, 0x85, 0xd2, //0x00000117 testw %dx, %dx
0x0f, 0x85, 0x30, 0x01, 0x00, 0x00, //0x0000011a jne LBB0_21
0x49, 0x83, 0xc5, 0x10, //0x00000120 addq $16, %r13
0x49, 0x83, 0xc0, 0x10, //0x00000124 addq $16, %r8
0x4c, 0x8d, 0x61, 0xf0, //0x00000128 leaq $-16(%rcx), %r12
0x48, 0x83, 0xf8, 0x1f, //0x0000012c cmpq $31, %rax
0x0f, 0x9f, 0xc3, //0x00000130 setg %bl
0x48, 0x83, 0xf8, 0x20, //0x00000133 cmpq $32, %rax
0x48, 0x8d, 0x40, 0xf0, //0x00000137 leaq $-16(%rax), %rax
0x0f, 0x8c, 0x0f, 0x00, 0x00, 0x00, //0x0000013b jl LBB0_9
0x48, 0x83, 0xf9, 0x1f, //0x00000141 cmpq $31, %rcx
0x4c, 0x89, 0xe1, //0x00000145 movq %r12, %rcx
0x0f, 0x8f, 0xa2, 0xff, 0xff, 0xff, //0x00000148 jg LBB0_6
0x90, 0x90, //0x0000014e .p2align 4, 0x90
//0x00000150 LBB0_9
0x84, 0xdb, //0x00000150 testb %bl, %bl
0x0f, 0x84, 0x68, 0x00, 0x00, 0x00, //0x00000152 je LBB0_13
0x4c, 0x89, 0xf2, //0x00000158 movq %r14, %rdx
0xc4, 0xc1, 0x7a, 0x6f, 0x65, 0x00, //0x0000015b vmovdqu (%r13), %xmm4
0xc5, 0xd9, 0x74, 0xe8, //0x00000161 vpcmpeqb %xmm0, %xmm4, %xmm5
0xc5, 0xd9, 0x74, 0xf1, //0x00000165 vpcmpeqb %xmm1, %xmm4, %xmm6
0xc5, 0xc9, 0xeb, 0xed, //0x00000169 vpor %xmm5, %xmm6, %xmm5
0xc5, 0xd9, 0xeb, 0xf2, //0x0000016d vpor %xmm2, %xmm4, %xmm6
0xc5, 0xc9, 0x74, 0xf3, //0x00000171 vpcmpeqb %xmm3, %xmm6, %xmm6
0xc5, 0xd1, 0xeb, 0xee, //0x00000175 vpor %xmm6, %xmm5, %xmm5
0xc5, 0xf9, 0xd7, 0xc5, //0x00000179 vpmovmskb %xmm5, %eax
0x0d, 0x00, 0x00, 0x01, 0x00, //0x0000017d orl $65536, %eax
0x44, 0x0f, 0xbc, 0xf0, //0x00000182 bsfl %eax, %r14d
0xc4, 0xe1, 0xf9, 0x7e, 0xe0, //0x00000186 vmovq %xmm4, %rax
0x4d, 0x39, 0xf4, //0x0000018b cmpq %r14, %r12
0x0f, 0x8d, 0xd7, 0x00, 0x00, 0x00, //0x0000018e jge LBB0_22
0x49, 0x83, 0xfc, 0x08, //0x00000194 cmpq $8, %r12
0x0f, 0x82, 0x09, 0x01, 0x00, 0x00, //0x00000198 jb LBB0_25
0x49, 0x89, 0x00, //0x0000019e movq %rax, (%r8)
0x4d, 0x8d, 0x75, 0x08, //0x000001a1 leaq $8(%r13), %r14
0x49, 0x83, 0xc0, 0x08, //0x000001a5 addq $8, %r8
0x49, 0x8d, 0x44, 0x24, 0xf8, //0x000001a9 leaq $-8(%r12), %rax
0x48, 0x83, 0xf8, 0x04, //0x000001ae cmpq $4, %rax
0x0f, 0x8d, 0xff, 0x00, 0x00, 0x00, //0x000001b2 jge LBB0_26
0xe9, 0x0c, 0x01, 0x00, 0x00, //0x000001b8 jmp LBB0_27
0x90, 0x90, 0x90, //0x000001bd .p2align 4, 0x90
//0x000001c0 LBB0_13
0x4d, 0x85, 0xe4, //0x000001c0 testq %r12, %r12
0x0f, 0x8e, 0x67, 0x00, 0x00, 0x00, //0x000001c3 jle LBB0_20
0x48, 0x85, 0xc0, //0x000001c9 testq %rax, %rax
0x0f, 0x8e, 0x5e, 0x00, 0x00, 0x00, //0x000001cc jle LBB0_20
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, //0x000001d2 .p2align 4, 0x90
//0x000001e0 LBB0_15
0x41, 0x0f, 0xb6, 0x4d, 0x00, //0x000001e0 movzbl (%r13), %ecx
0x48, 0x83, 0xf9, 0x3e, //0x000001e5 cmpq $62, %rcx
0x0f, 0x87, 0x0a, 0x00, 0x00, 0x00, //0x000001e9 ja LBB0_17
0x49, 0x0f, 0xa3, 0xce, //0x000001ef btq %rcx, %r14
0x0f, 0x82, 0x9a, 0x00, 0x00, 0x00, //0x000001f3 jb LBB0_24
//0x000001f9 LBB0_17
0x80, 0xf9, 0xe2, //0x000001f9 cmpb $-30, %cl
0x0f, 0x84, 0x91, 0x00, 0x00, 0x00, //0x000001fc je LBB0_24
0x49, 0xff, 0xc5, //0x00000202 incq %r13
0x41, 0x88, 0x08, //0x00000205 movb %cl, (%r8)
0x48, 0x83, 0xf8, 0x02, //0x00000208 cmpq $2, %rax
0x48, 0x8d, 0x40, 0xff, //0x0000020c leaq $-1(%rax), %rax
0x0f, 0x8c, 0x1a, 0x00, 0x00, 0x00, //0x00000210 jl LBB0_20
0x49, 0xff, 0xc0, //0x00000216 incq %r8
0x49, 0x83, 0xfc, 0x01, //0x00000219 cmpq $1, %r12
0x4d, 0x8d, 0x64, 0x24, 0xff, //0x0000021d leaq $-1(%r12), %r12
0x0f, 0x8f, 0xb8, 0xff, 0xff, 0xff, //0x00000222 jg LBB0_15
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, //0x00000228 .p2align 4, 0x90
//0x00000230 LBB0_20
0x4d, 0x29, 0xfd, //0x00000230 subq %r15, %r13
0x48, 0xf7, 0xd8, //0x00000233 negq %rax
0x4d, 0x19, 0xe4, //0x00000236 sbbq %r12, %r12
0x4d, 0x31, 0xec, //0x00000239 xorq %r13, %r12
0x4d, 0x85, 0xe4, //0x0000023c testq %r12, %r12
0x0f, 0x89, 0x5b, 0x01, 0x00, 0x00, //0x0000023f jns LBB0_37
0xe9, 0x72, 0x02, 0x00, 0x00, //0x00000245 jmp LBB0_57
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, //0x0000024a .p2align 4, 0x90
//0x00000250 LBB0_21
0x0f, 0xb7, 0xc2, //0x00000250 movzwl %dx, %eax
0x4d, 0x29, 0xfd, //0x00000253 subq %r15, %r13
0x44, 0x0f, 0xbc, 0xe0, //0x00000256 bsfl %eax, %r12d
0x4d, 0x01, 0xec, //0x0000025a addq %r13, %r12
0x4d, 0x85, 0xe4, //0x0000025d testq %r12, %r12
0x0f, 0x89, 0x3a, 0x01, 0x00, 0x00, //0x00000260 jns LBB0_37
0xe9, 0x51, 0x02, 0x00, 0x00, //0x00000266 jmp LBB0_57
//0x0000026b LBB0_22
0x41, 0x83, 0xfe, 0x08, //0x0000026b cmpl $8, %r14d
0x0f, 0x82, 0xa9, 0x00, 0x00, 0x00, //0x0000026f jb LBB0_31
0x49, 0x89, 0x00, //0x00000275 movq %rax, (%r8)
0x4d, 0x8d, 0x65, 0x08, //0x00000278 leaq $8(%r13), %r12
0x49, 0x83, 0xc0, 0x08, //0x0000027c addq $8, %r8
0x49, 0x8d, 0x46, 0xf8, //0x00000280 leaq $-8(%r14), %rax
0x48, 0x83, 0xf8, 0x04, //0x00000284 cmpq $4, %rax
0x0f, 0x8d, 0xa0, 0x00, 0x00, 0x00, //0x00000288 jge LBB0_32
0xe9, 0xae, 0x00, 0x00, 0x00, //0x0000028e jmp LBB0_33
//0x00000293 LBB0_24
0x4d, 0x29, 0xfd, //0x00000293 subq %r15, %r13
0x4d, 0x89, 0xec, //0x00000296 movq %r13, %r12
0x4d, 0x85, 0xe4, //0x00000299 testq %r12, %r12
0x0f, 0x89, 0xfe, 0x00, 0x00, 0x00, //0x0000029c jns LBB0_37
0xe9, 0x15, 0x02, 0x00, 0x00, //0x000002a2 jmp LBB0_57
//0x000002a7 LBB0_25
0x4d, 0x89, 0xee, //0x000002a7 movq %r13, %r14
0x4c, 0x89, 0xe0, //0x000002aa movq %r12, %rax
0x48, 0x83, 0xf8, 0x04, //0x000002ad cmpq $4, %rax
0x0f, 0x8c, 0x12, 0x00, 0x00, 0x00, //0x000002b1 jl LBB0_27
//0x000002b7 LBB0_26
0x41, 0x8b, 0x0e, //0x000002b7 movl (%r14), %ecx
0x41, 0x89, 0x08, //0x000002ba movl %ecx, (%r8)
0x49, 0x83, 0xc6, 0x04, //0x000002bd addq $4, %r14
0x49, 0x83, 0xc0, 0x04, //0x000002c1 addq $4, %r8
0x48, 0x83, 0xc0, 0xfc, //0x000002c5 addq $-4, %rax
//0x000002c9 LBB0_27
0x48, 0x83, 0xf8, 0x02, //0x000002c9 cmpq $2, %rax
0x0f, 0x82, 0x22, 0x00, 0x00, 0x00, //0x000002cd jb LBB0_28
0x41, 0x0f, 0xb7, 0x0e, //0x000002d3 movzwl (%r14), %ecx
0x66, 0x41, 0x89, 0x08, //0x000002d7 movw %cx, (%r8)
0x49, 0x83, 0xc6, 0x02, //0x000002db addq $2, %r14
0x49, 0x83, 0xc0, 0x02, //0x000002df addq $2, %r8
0x48, 0x83, 0xc0, 0xfe, //0x000002e3 addq $-2, %rax
0x48, 0x85, 0xc0, //0x000002e7 testq %rax, %rax
0x0f, 0x85, 0x0e, 0x00, 0x00, 0x00, //0x000002ea jne LBB0_29
0xe9, 0x0f, 0x00, 0x00, 0x00, //0x000002f0 jmp LBB0_30
//0x000002f5 LBB0_28
0x48, 0x85, 0xc0, //0x000002f5 testq %rax, %rax
0x0f, 0x84, 0x06, 0x00, 0x00, 0x00, //0x000002f8 je LBB0_30
//0x000002fe LBB0_29
0x41, 0x8a, 0x06, //0x000002fe movb (%r14), %al
0x41, 0x88, 0x00, //0x00000301 movb %al, (%r8)
//0x00000304 LBB0_30
0x4d, 0x29, 0xfc, //0x00000304 subq %r15, %r12
0x4d, 0x01, 0xec, //0x00000307 addq %r13, %r12
0x49, 0xf7, 0xd4, //0x0000030a notq %r12
0x49, 0x89, 0xd6, //0x0000030d movq %rdx, %r14
0x4d, 0x85, 0xe4, //0x00000310 testq %r12, %r12
0x0f, 0x89, 0x87, 0x00, 0x00, 0x00, //0x00000313 jns LBB0_37
0xe9, 0x9e, 0x01, 0x00, 0x00, //0x00000319 jmp LBB0_57
//0x0000031e LBB0_31
0x4d, 0x89, 0xec, //0x0000031e movq %r13, %r12
0x4c, 0x89, 0xf0, //0x00000321 movq %r14, %rax
0x48, 0x83, 0xf8, 0x04, //0x00000324 cmpq $4, %rax
0x0f, 0x8c, 0x13, 0x00, 0x00, 0x00, //0x00000328 jl LBB0_33
//0x0000032e LBB0_32
0x41, 0x8b, 0x0c, 0x24, //0x0000032e movl (%r12), %ecx
0x41, 0x89, 0x08, //0x00000332 movl %ecx, (%r8)
0x49, 0x83, 0xc4, 0x04, //0x00000335 addq $4, %r12
0x49, 0x83, 0xc0, 0x04, //0x00000339 addq $4, %r8
0x48, 0x83, 0xc0, 0xfc, //0x0000033d addq $-4, %rax
//0x00000341 LBB0_33
0x48, 0x83, 0xf8, 0x02, //0x00000341 cmpq $2, %rax
0x0f, 0x82, 0x23, 0x00, 0x00, 0x00, //0x00000345 jb LBB0_34
0x41, 0x0f, 0xb7, 0x0c, 0x24, //0x0000034b movzwl (%r12), %ecx
0x66, 0x41, 0x89, 0x08, //0x00000350 movw %cx, (%r8)
0x49, 0x83, 0xc4, 0x02, //0x00000354 addq $2, %r12
0x49, 0x83, 0xc0, 0x02, //0x00000358 addq $2, %r8
0x48, 0x83, 0xc0, 0xfe, //0x0000035c addq $-2, %rax
0x48, 0x85, 0xc0, //0x00000360 testq %rax, %rax
0x0f, 0x85, 0x0e, 0x00, 0x00, 0x00, //0x00000363 jne LBB0_35
0xe9, 0x10, 0x00, 0x00, 0x00, //0x00000369 jmp LBB0_36
//0x0000036e LBB0_34
0x48, 0x85, 0xc0, //0x0000036e testq %rax, %rax
0x0f, 0x84, 0x07, 0x00, 0x00, 0x00, //0x00000371 je LBB0_36
//0x00000377 LBB0_35
0x41, 0x8a, 0x04, 0x24, //0x00000377 movb (%r12), %al
0x41, 0x88, 0x00, //0x0000037b movb %al, (%r8)
//0x0000037e LBB0_36
0x4d, 0x29, 0xfd, //0x0000037e subq %r15, %r13
0x4d, 0x01, 0xf5, //0x00000381 addq %r14, %r13
0x4d, 0x89, 0xec, //0x00000384 movq %r13, %r12
0x49, 0x89, 0xd6, //0x00000387 movq %rdx, %r14
0x4d, 0x85, 0xe4, //0x0000038a testq %r12, %r12
0x0f, 0x88, 0x29, 0x01, 0x00, 0x00, //0x0000038d js LBB0_57
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, //0x00000393 .p2align 4, 0x90
//0x000003a0 LBB0_37
0x4d, 0x01, 0xe7, //0x000003a0 addq %r12, %r15
0x4d, 0x01, 0xe2, //0x000003a3 addq %r12, %r10
0x4c, 0x29, 0xe6, //0x000003a6 subq %r12, %rsi
0x0f, 0x8e, 0x2d, 0x01, 0x00, 0x00, //0x000003a9 jle LBB0_58
0x4d, 0x29, 0xe1, //0x000003af subq %r12, %r9
0x41, 0x8a, 0x0f, //0x000003b2 movb (%r15), %cl
0x80, 0xf9, 0xe2, //0x000003b5 cmpb $-30, %cl
0x0f, 0x84, 0xb1, 0x00, 0x00, 0x00, //0x000003b8 je LBB0_51
0x4c, 0x89, 0xf8, //0x000003be movq %r15, %rax
//0x000003c1 LBB0_40
0x0f, 0xb6, 0xd1, //0x000003c1 movzbl %cl, %edx
0x48, 0xc1, 0xe2, 0x04, //0x000003c4 shlq $4, %rdx
0x4a, 0x8b, 0x3c, 0x1a, //0x000003c8 movq (%rdx,%r11), %rdi
0x48, 0x63, 0xdf, //0x000003cc movslq %edi, %rbx
0x49, 0x29, 0xd9, //0x000003cf subq %rbx, %r9
0x0f, 0x8c, 0x1b, 0x01, 0x00, 0x00, //0x000003d2 jl LBB0_60
0x48, 0xc1, 0xe7, 0x20, //0x000003d8 shlq $32, %rdi
0x4e, 0x8d, 0x7c, 0x1a, 0x08, //0x000003dc leaq $8(%rdx,%r11), %r15
0x48, 0xb9, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, //0x000003e1 movabsq $12884901889, %rcx
0x48, 0x39, 0xcf, //0x000003eb cmpq %rcx, %rdi
0x0f, 0x8c, 0x2c, 0x00, 0x00, 0x00, //0x000003ee jl LBB0_43
0x41, 0x8b, 0x0f, //0x000003f4 movl (%r15), %ecx
0x41, 0x89, 0x0a, //0x000003f7 movl %ecx, (%r10)
0x4e, 0x8d, 0x7c, 0x1a, 0x0c, //0x000003fa leaq $12(%rdx,%r11), %r15
0x4d, 0x8d, 0x42, 0x04, //0x000003ff leaq $4(%r10), %r8
0x48, 0x8d, 0x7b, 0xfc, //0x00000403 leaq $-4(%rbx), %rdi
0x48, 0x83, 0xff, 0x02, //0x00000407 cmpq $2, %rdi
0x0f, 0x83, 0x1f, 0x00, 0x00, 0x00, //0x0000040b jae LBB0_44
0xe9, 0x2e, 0x00, 0x00, 0x00, //0x00000411 jmp LBB0_45
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, //0x00000416 .p2align 4, 0x90
//0x00000420 LBB0_43
0x4d, 0x89, 0xd0, //0x00000420 movq %r10, %r8
0x48, 0x89, 0xdf, //0x00000423 movq %rbx, %rdi
0x48, 0x83, 0xff, 0x02, //0x00000426 cmpq $2, %rdi
0x0f, 0x82, 0x14, 0x00, 0x00, 0x00, //0x0000042a jb LBB0_45
//0x00000430 LBB0_44
0x41, 0x0f, 0xb7, 0x17, //0x00000430 movzwl (%r15), %edx
0x66, 0x41, 0x89, 0x10, //0x00000434 movw %dx, (%r8)
0x49, 0x83, 0xc7, 0x02, //0x00000438 addq $2, %r15
0x49, 0x83, 0xc0, 0x02, //0x0000043c addq $2, %r8
0x48, 0x83, 0xc7, 0xfe, //0x00000440 addq $-2, %rdi
//0x00000444 LBB0_45
0x48, 0x85, 0xff, //0x00000444 testq %rdi, %rdi
0x0f, 0x84, 0x06, 0x00, 0x00, 0x00, //0x00000447 je LBB0_47
0x41, 0x8a, 0x0f, //0x0000044d movb (%r15), %cl
0x41, 0x88, 0x08, //0x00000450 movb %cl, (%r8)
//0x00000453 LBB0_47
0x49, 0x01, 0xda, //0x00000453 addq %rbx, %r10
//0x00000456 LBB0_48
0x48, 0xff, 0xc0, //0x00000456 incq %rax
0x49, 0x89, 0xc7, //0x00000459 movq %rax, %r15
0x48, 0x83, 0xfe, 0x01, //0x0000045c cmpq $1, %rsi
0x48, 0x8d, 0x76, 0xff, //0x00000460 leaq $-1(%rsi), %rsi
0x0f, 0x8f, 0x46, 0xfc, 0xff, 0xff, //0x00000464 jg LBB0_2
0xe9, 0x70, 0x00, 0x00, 0x00, //0x0000046a jmp LBB0_59
//0x0000046f LBB0_51
0x48, 0x83, 0xfe, 0x03, //0x0000046f cmpq $3, %rsi
0x0f, 0x8c, 0x28, 0x00, 0x00, 0x00, //0x00000473 jl LBB0_55
0x41, 0x80, 0x7f, 0x01, 0x80, //0x00000479 cmpb $-128, $1(%r15)
0x0f, 0x85, 0x1d, 0x00, 0x00, 0x00, //0x0000047e jne LBB0_55
0x41, 0x8a, 0x4f, 0x02, //0x00000484 movb $2(%r15), %cl
0x89, 0xc8, //0x00000488 movl %ecx, %eax
0x24, 0xfe, //0x0000048a andb $-2, %al
0x3c, 0xa8, //0x0000048c cmpb $-88, %al
0x0f, 0x85, 0x0d, 0x00, 0x00, 0x00, //0x0000048e jne LBB0_55
0x49, 0x8d, 0x47, 0x02, //0x00000494 leaq $2(%r15), %rax
0x48, 0x83, 0xc6, 0xfe, //0x00000498 addq $-2, %rsi
0xe9, 0x20, 0xff, 0xff, 0xff, //0x0000049c jmp LBB0_40
//0x000004a1 LBB0_55
0x4d, 0x85, 0xc9, //0x000004a1 testq %r9, %r9
0x0f, 0x8e, 0x54, 0x00, 0x00, 0x00, //0x000004a4 jle LBB0_61
0x41, 0xc6, 0x02, 0xe2, //0x000004aa movb $-30, (%r10)
0x49, 0xff, 0xc2, //0x000004ae incq %r10
0x49, 0xff, 0xc9, //0x000004b1 decq %r9
0x4c, 0x89, 0xf8, //0x000004b4 movq %r15, %rax
0xe9, 0x9a, 0xff, 0xff, 0xff, //0x000004b7 jmp LBB0_48
//0x000004bc LBB0_57
0x4c, 0x2b, 0x55, 0xc8, //0x000004bc subq $-56(%rbp), %r10
0x49, 0xf7, 0xd4, //0x000004c0 notq %r12
0x4d, 0x01, 0xe2, //0x000004c3 addq %r12, %r10
0x48, 0x8b, 0x45, 0xc0, //0x000004c6 movq $-64(%rbp), %rax
0x4c, 0x89, 0x10, //0x000004ca movq %r10, (%rax)
0x4c, 0x2b, 0x7d, 0xd0, //0x000004cd subq $-48(%rbp), %r15
0x4d, 0x01, 0xe7, //0x000004d1 addq %r12, %r15
0x49, 0xf7, 0xd7, //0x000004d4 notq %r15
0xe9, 0x29, 0x00, 0x00, 0x00, //0x000004d7 jmp LBB0_62
//0x000004dc LBB0_58
0x4c, 0x89, 0xf8, //0x000004dc movq %r15, %rax
//0x000004df LBB0_59
0x4c, 0x2b, 0x55, 0xc8, //0x000004df subq $-56(%rbp), %r10
0x48, 0x8b, 0x4d, 0xc0, //0x000004e3 movq $-64(%rbp), %rcx
0x4c, 0x89, 0x11, //0x000004e7 movq %r10, (%rcx)
0x48, 0x2b, 0x45, 0xd0, //0x000004ea subq $-48(%rbp), %rax
0xe9, 0x15, 0x00, 0x00, 0x00, //0x000004ee jmp LBB0_63
//0x000004f3 LBB0_60
0x4c, 0x2b, 0x55, 0xc8, //0x000004f3 subq $-56(%rbp), %r10
0x48, 0x8b, 0x45, 0xc0, //0x000004f7 movq $-64(%rbp), %rax
0x4c, 0x89, 0x10, //0x000004fb movq %r10, (%rax)
//0x000004fe LBB0_61
0x49, 0xf7, 0xd7, //0x000004fe notq %r15
0x4c, 0x03, 0x7d, 0xd0, //0x00000501 addq $-48(%rbp), %r15
//0x00000505 LBB0_62
0x4c, 0x89, 0xf8, //0x00000505 movq %r15, %rax
//0x00000508 LBB0_63
0x48, 0x83, 0xc4, 0x18, //0x00000508 addq $24, %rsp
0x5b, //0x0000050c popq %rbx
0x41, 0x5c, //0x0000050d popq %r12
0x41, 0x5d, //0x0000050f popq %r13
0x41, 0x5e, //0x00000511 popq %r14
0x41, 0x5f, //0x00000513 popq %r15
0x5d, //0x00000515 popq %rbp
0xc3, //0x00000516 retq
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000517 .p2align 4, 0x00
//0x00000520 __HtmlQuoteTab
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000520 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000530 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000540 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000550 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000560 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000570 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000580 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000590 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000005a0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000005b0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000005c0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000005d0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000005e0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000005f0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000600 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000610 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000620 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000630 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000640 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000650 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000660 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000670 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000680 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000690 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000006a0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000006b0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000006c0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000006d0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000006e0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000006f0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000700 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000710 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000720 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000730 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000740 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000750 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000760 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000770 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000780 .quad 6
0x5c, 0x75, 0x30, 0x30, 0x32, 0x36, 0x00, 0x00, //0x00000788 QUAD $0x000036323030755c // .asciz 8, '\\u0026\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000790 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000007a0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000007b0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000007c0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000007d0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000007e0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000007f0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000800 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000810 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000820 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000830 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000840 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000850 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000860 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000870 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000880 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000890 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000008a0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000008b0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000008c0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000008d0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000008e0 .quad 6
0x5c, 0x75, 0x30, 0x30, 0x33, 0x63, 0x00, 0x00, //0x000008e8 QUAD $0x000063333030755c // .asciz 8, '\\u003c\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000008f0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000900 .quad 6
0x5c, 0x75, 0x30, 0x30, 0x33, 0x65, 0x00, 0x00, //0x00000908 QUAD $0x000065333030755c // .asciz 8, '\\u003e\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000910 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000920 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000930 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000940 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000950 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000960 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000970 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000980 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000990 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000009a0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000009b0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000009c0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000009d0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000009e0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000009f0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000a00 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000a10 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000a20 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000a30 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000a40 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000a50 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000a60 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000a70 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000a80 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000a90 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000aa0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000ab0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000ac0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000ad0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000ae0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000af0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000b00 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000b10 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000b20 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000b30 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000b40 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000b50 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000b60 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000b70 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000b80 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000b90 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000ba0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000bb0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000bc0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000bd0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000be0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000bf0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000c00 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000c10 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000c20 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000c30 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000c40 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000c50 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000c60 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000c70 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000c80 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000c90 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000ca0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000cb0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000cc0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000cd0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000ce0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000cf0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000d00 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000d10 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000d20 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000d30 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000d40 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000d50 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000d60 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000d70 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000d80 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000d90 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000da0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000db0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000dc0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000dd0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000de0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000df0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000e00 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000e10 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000e20 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000e30 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000e40 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000e50 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000e60 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000e70 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000e80 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000e90 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000ea0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000eb0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000ec0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000ed0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000ee0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000ef0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000f00 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000f10 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000f20 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000f30 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000f40 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000f50 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000f60 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000f70 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000f80 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000f90 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000fa0 .quad 6
0x5c, 0x75, 0x32, 0x30, 0x32, 0x38, 0x00, 0x00, //0x00000fa8 QUAD $0x000038323032755c // .asciz 8, '\\u2028\x00\x00'
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000fb0 .quad 6
0x5c, 0x75, 0x32, 0x30, 0x32, 0x39, 0x00, 0x00, //0x00000fb8 QUAD $0x000039323032755c // .asciz 8, '\\u2029\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000fc0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000fd0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000fe0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00000ff0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001000 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001010 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001020 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001030 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001040 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001050 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001060 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001070 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001080 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001090 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000010a0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000010b0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000010c0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000010d0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000010e0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000010f0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001100 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001110 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001120 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001130 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001140 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001150 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001160 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001170 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001180 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001190 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000011a0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000011b0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000011c0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000011d0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000011e0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000011f0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001200 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001210 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001220 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001230 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001240 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001250 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001260 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001270 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001280 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001290 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000012a0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000012b0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000012c0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000012d0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000012e0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000012f0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001300 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001310 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001320 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001330 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001340 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001350 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001360 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001370 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001380 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001390 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000013a0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000013b0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000013c0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000013d0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000013e0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000013f0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001400 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001410 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001420 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001430 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001440 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001450 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001460 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001470 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001480 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001490 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000014a0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000014b0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000014c0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000014d0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000014e0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000014f0 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001500 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x00001510 QUAD $0x0000000000000000; QUAD $0x0000000000000000 // .space 16, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
}

View file

@ -1,47 +0,0 @@
// +build !noasm !appengine
// Code generated by asm2asm, DO NOT EDIT.
package avx
import (
`github.com/bytedance/sonic/loader`
)
const (
_entry__i64toa = 64
)
const (
_stack__i64toa = 8
)
const (
_size__i64toa = 2272
)
var (
_pcsp__i64toa = [][2]uint32{
{1, 0},
{170, 8},
{171, 0},
{505, 8},
{506, 0},
{637, 8},
{638, 0},
{1101, 8},
{1102, 0},
{1238, 8},
{1239, 0},
{1540, 8},
{1541, 0},
{1901, 8},
{1902, 0},
{2268, 8},
{2270, 0},
}
)
var _cfunc_i64toa = []loader.CFunc{
{"_i64toa_entry", 0, _entry__i64toa, 0, nil},
{"_i64toa", _entry__i64toa, _size__i64toa, _stack__i64toa, _pcsp__i64toa},
}

View file

@ -1,639 +0,0 @@
// +build amd64
// Code generated by asm2asm, DO NOT EDIT.
package avx
var _text_i64toa = []byte{
// .p2align 4, 0x00
// LCPI0_0
0x59, 0x17, 0xb7, 0xd1, 0x00, 0x00, 0x00, 0x00, // .quad 3518437209
0x59, 0x17, 0xb7, 0xd1, 0x00, 0x00, 0x00, 0x00, //0x00000008 .quad 3518437209
//0x00000010 LCPI0_3
0x0a, 0x00, //0x00000010 .word 10
0x0a, 0x00, //0x00000012 .word 10
0x0a, 0x00, //0x00000014 .word 10
0x0a, 0x00, //0x00000016 .word 10
0x0a, 0x00, //0x00000018 .word 10
0x0a, 0x00, //0x0000001a .word 10
0x0a, 0x00, //0x0000001c .word 10
0x0a, 0x00, //0x0000001e .word 10
//0x00000020 LCPI0_4
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, //0x00000020 QUAD $0x3030303030303030; QUAD $0x3030303030303030 // .space 16, '0000000000000000'
//0x00000030 .p2align 3, 0x00
//0x00000030 LCPI0_1
0xc5, 0x20, 0x7b, 0x14, 0x34, 0x33, 0x00, 0x80, //0x00000030 .quad -9223315738079846203
//0x00000038 LCPI0_2
0x80, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, //0x00000038 .quad -9223336852348469120
//0x00000040 .p2align 4, 0x90
//0x00000040 _i64toa
0x55, //0x00000040 pushq %rbp
0x48, 0x89, 0xe5, //0x00000041 movq %rsp, %rbp
0x48, 0x85, 0xf6, //0x00000044 testq %rsi, %rsi
0x0f, 0x88, 0xaf, 0x00, 0x00, 0x00, //0x00000047 js LBB0_25
0x48, 0x81, 0xfe, 0x0f, 0x27, 0x00, 0x00, //0x0000004d cmpq $9999, %rsi
0x0f, 0x87, 0xf8, 0x00, 0x00, 0x00, //0x00000054 ja LBB0_9
0x0f, 0xb7, 0xc6, //0x0000005a movzwl %si, %eax
0xc1, 0xe8, 0x02, //0x0000005d shrl $2, %eax
0x69, 0xc0, 0x7b, 0x14, 0x00, 0x00, //0x00000060 imull $5243, %eax, %eax
0xc1, 0xe8, 0x11, //0x00000066 shrl $17, %eax
0x48, 0x8d, 0x14, 0x00, //0x00000069 leaq (%rax,%rax), %rdx
0x6b, 0xc0, 0x64, //0x0000006d imull $100, %eax, %eax
0x89, 0xf1, //0x00000070 movl %esi, %ecx
0x29, 0xc1, //0x00000072 subl %eax, %ecx
0x0f, 0xb7, 0xc1, //0x00000074 movzwl %cx, %eax
0x48, 0x01, 0xc0, //0x00000077 addq %rax, %rax
0x81, 0xfe, 0xe8, 0x03, 0x00, 0x00, //0x0000007a cmpl $1000, %esi
0x0f, 0x82, 0x16, 0x00, 0x00, 0x00, //0x00000080 jb LBB0_4
0x48, 0x8d, 0x0d, 0x93, 0x08, 0x00, 0x00, //0x00000086 leaq $2195(%rip), %rcx /* _Digits+0(%rip) */
0x8a, 0x0c, 0x0a, //0x0000008d movb (%rdx,%rcx), %cl
0x88, 0x0f, //0x00000090 movb %cl, (%rdi)
0xb9, 0x01, 0x00, 0x00, 0x00, //0x00000092 movl $1, %ecx
0xe9, 0x0b, 0x00, 0x00, 0x00, //0x00000097 jmp LBB0_5
//0x0000009c LBB0_4
0x31, 0xc9, //0x0000009c xorl %ecx, %ecx
0x83, 0xfe, 0x64, //0x0000009e cmpl $100, %esi
0x0f, 0x82, 0x45, 0x00, 0x00, 0x00, //0x000000a1 jb LBB0_6
//0x000000a7 LBB0_5
0x0f, 0xb7, 0xd2, //0x000000a7 movzwl %dx, %edx
0x48, 0x83, 0xca, 0x01, //0x000000aa orq $1, %rdx
0x48, 0x8d, 0x35, 0x6b, 0x08, 0x00, 0x00, //0x000000ae leaq $2155(%rip), %rsi /* _Digits+0(%rip) */
0x8a, 0x14, 0x32, //0x000000b5 movb (%rdx,%rsi), %dl
0x89, 0xce, //0x000000b8 movl %ecx, %esi
0xff, 0xc1, //0x000000ba incl %ecx
0x88, 0x14, 0x37, //0x000000bc movb %dl, (%rdi,%rsi)
//0x000000bf LBB0_7
0x48, 0x8d, 0x15, 0x5a, 0x08, 0x00, 0x00, //0x000000bf leaq $2138(%rip), %rdx /* _Digits+0(%rip) */
0x8a, 0x14, 0x10, //0x000000c6 movb (%rax,%rdx), %dl
0x89, 0xce, //0x000000c9 movl %ecx, %esi
0xff, 0xc1, //0x000000cb incl %ecx
0x88, 0x14, 0x37, //0x000000cd movb %dl, (%rdi,%rsi)
//0x000000d0 LBB0_8
0x0f, 0xb7, 0xc0, //0x000000d0 movzwl %ax, %eax
0x48, 0x83, 0xc8, 0x01, //0x000000d3 orq $1, %rax
0x48, 0x8d, 0x15, 0x42, 0x08, 0x00, 0x00, //0x000000d7 leaq $2114(%rip), %rdx /* _Digits+0(%rip) */
0x8a, 0x04, 0x10, //0x000000de movb (%rax,%rdx), %al
0x89, 0xca, //0x000000e1 movl %ecx, %edx
0xff, 0xc1, //0x000000e3 incl %ecx
0x88, 0x04, 0x17, //0x000000e5 movb %al, (%rdi,%rdx)
0x89, 0xc8, //0x000000e8 movl %ecx, %eax
0x5d, //0x000000ea popq %rbp
0xc3, //0x000000eb retq
//0x000000ec LBB0_6
0x31, 0xc9, //0x000000ec xorl %ecx, %ecx
0x83, 0xfe, 0x0a, //0x000000ee cmpl $10, %esi
0x0f, 0x83, 0xc8, 0xff, 0xff, 0xff, //0x000000f1 jae LBB0_7
0xe9, 0xd4, 0xff, 0xff, 0xff, //0x000000f7 jmp LBB0_8
//0x000000fc LBB0_25
0xc6, 0x07, 0x2d, //0x000000fc movb $45, (%rdi)
0x48, 0xf7, 0xde, //0x000000ff negq %rsi
0x48, 0x81, 0xfe, 0x0f, 0x27, 0x00, 0x00, //0x00000102 cmpq $9999, %rsi
0x0f, 0x87, 0xd3, 0x01, 0x00, 0x00, //0x00000109 ja LBB0_33
0x0f, 0xb7, 0xc6, //0x0000010f movzwl %si, %eax
0xc1, 0xe8, 0x02, //0x00000112 shrl $2, %eax
0x69, 0xc0, 0x7b, 0x14, 0x00, 0x00, //0x00000115 imull $5243, %eax, %eax
0xc1, 0xe8, 0x11, //0x0000011b shrl $17, %eax
0x48, 0x8d, 0x14, 0x00, //0x0000011e leaq (%rax,%rax), %rdx
0x6b, 0xc0, 0x64, //0x00000122 imull $100, %eax, %eax
0x89, 0xf1, //0x00000125 movl %esi, %ecx
0x29, 0xc1, //0x00000127 subl %eax, %ecx
0x0f, 0xb7, 0xc1, //0x00000129 movzwl %cx, %eax
0x48, 0x01, 0xc0, //0x0000012c addq %rax, %rax
0x81, 0xfe, 0xe8, 0x03, 0x00, 0x00, //0x0000012f cmpl $1000, %esi
0x0f, 0x82, 0xab, 0x00, 0x00, 0x00, //0x00000135 jb LBB0_28
0x48, 0x8d, 0x0d, 0xde, 0x07, 0x00, 0x00, //0x0000013b leaq $2014(%rip), %rcx /* _Digits+0(%rip) */
0x8a, 0x0c, 0x0a, //0x00000142 movb (%rdx,%rcx), %cl
0x88, 0x4f, 0x01, //0x00000145 movb %cl, $1(%rdi)
0xb9, 0x01, 0x00, 0x00, 0x00, //0x00000148 movl $1, %ecx
0xe9, 0x9f, 0x00, 0x00, 0x00, //0x0000014d jmp LBB0_29
//0x00000152 LBB0_9
0x48, 0x81, 0xfe, 0xff, 0xe0, 0xf5, 0x05, //0x00000152 cmpq $99999999, %rsi
0x0f, 0x87, 0x18, 0x02, 0x00, 0x00, //0x00000159 ja LBB0_17
0x89, 0xf0, //0x0000015f movl %esi, %eax
0xba, 0x59, 0x17, 0xb7, 0xd1, //0x00000161 movl $3518437209, %edx
0x48, 0x0f, 0xaf, 0xd0, //0x00000166 imulq %rax, %rdx
0x48, 0xc1, 0xea, 0x2d, //0x0000016a shrq $45, %rdx
0x44, 0x69, 0xc2, 0x10, 0x27, 0x00, 0x00, //0x0000016e imull $10000, %edx, %r8d
0x89, 0xf1, //0x00000175 movl %esi, %ecx
0x44, 0x29, 0xc1, //0x00000177 subl %r8d, %ecx
0x4c, 0x69, 0xd0, 0x83, 0xde, 0x1b, 0x43, //0x0000017a imulq $1125899907, %rax, %r10
0x49, 0xc1, 0xea, 0x31, //0x00000181 shrq $49, %r10
0x41, 0x83, 0xe2, 0xfe, //0x00000185 andl $-2, %r10d
0x0f, 0xb7, 0xc2, //0x00000189 movzwl %dx, %eax
0xc1, 0xe8, 0x02, //0x0000018c shrl $2, %eax
0x69, 0xc0, 0x7b, 0x14, 0x00, 0x00, //0x0000018f imull $5243, %eax, %eax
0xc1, 0xe8, 0x11, //0x00000195 shrl $17, %eax
0x6b, 0xc0, 0x64, //0x00000198 imull $100, %eax, %eax
0x29, 0xc2, //0x0000019b subl %eax, %edx
0x44, 0x0f, 0xb7, 0xca, //0x0000019d movzwl %dx, %r9d
0x4d, 0x01, 0xc9, //0x000001a1 addq %r9, %r9
0x0f, 0xb7, 0xc1, //0x000001a4 movzwl %cx, %eax
0xc1, 0xe8, 0x02, //0x000001a7 shrl $2, %eax
0x69, 0xc0, 0x7b, 0x14, 0x00, 0x00, //0x000001aa imull $5243, %eax, %eax
0xc1, 0xe8, 0x11, //0x000001b0 shrl $17, %eax
0x4c, 0x8d, 0x04, 0x00, //0x000001b3 leaq (%rax,%rax), %r8
0x6b, 0xc0, 0x64, //0x000001b7 imull $100, %eax, %eax
0x29, 0xc1, //0x000001ba subl %eax, %ecx
0x44, 0x0f, 0xb7, 0xd9, //0x000001bc movzwl %cx, %r11d
0x4d, 0x01, 0xdb, //0x000001c0 addq %r11, %r11
0x81, 0xfe, 0x80, 0x96, 0x98, 0x00, //0x000001c3 cmpl $10000000, %esi
0x0f, 0x82, 0x6c, 0x00, 0x00, 0x00, //0x000001c9 jb LBB0_12
0x48, 0x8d, 0x05, 0x4a, 0x07, 0x00, 0x00, //0x000001cf leaq $1866(%rip), %rax /* _Digits+0(%rip) */
0x41, 0x8a, 0x04, 0x02, //0x000001d6 movb (%r10,%rax), %al
0x88, 0x07, //0x000001da movb %al, (%rdi)
0xb9, 0x01, 0x00, 0x00, 0x00, //0x000001dc movl $1, %ecx
0xe9, 0x63, 0x00, 0x00, 0x00, //0x000001e1 jmp LBB0_13
//0x000001e6 LBB0_28
0x31, 0xc9, //0x000001e6 xorl %ecx, %ecx
0x83, 0xfe, 0x64, //0x000001e8 cmpl $100, %esi
0x0f, 0x82, 0xce, 0x00, 0x00, 0x00, //0x000001eb jb LBB0_30
//0x000001f1 LBB0_29
0x0f, 0xb7, 0xd2, //0x000001f1 movzwl %dx, %edx
0x48, 0x83, 0xca, 0x01, //0x000001f4 orq $1, %rdx
0x48, 0x8d, 0x35, 0x21, 0x07, 0x00, 0x00, //0x000001f8 leaq $1825(%rip), %rsi /* _Digits+0(%rip) */
0x8a, 0x14, 0x32, //0x000001ff movb (%rdx,%rsi), %dl
0x89, 0xce, //0x00000202 movl %ecx, %esi
0xff, 0xc1, //0x00000204 incl %ecx
0x88, 0x54, 0x37, 0x01, //0x00000206 movb %dl, $1(%rdi,%rsi)
//0x0000020a LBB0_31
0x48, 0x8d, 0x15, 0x0f, 0x07, 0x00, 0x00, //0x0000020a leaq $1807(%rip), %rdx /* _Digits+0(%rip) */
0x8a, 0x14, 0x10, //0x00000211 movb (%rax,%rdx), %dl
0x89, 0xce, //0x00000214 movl %ecx, %esi
0xff, 0xc1, //0x00000216 incl %ecx
0x88, 0x54, 0x37, 0x01, //0x00000218 movb %dl, $1(%rdi,%rsi)
//0x0000021c LBB0_32
0x0f, 0xb7, 0xc0, //0x0000021c movzwl %ax, %eax
0x48, 0x83, 0xc8, 0x01, //0x0000021f orq $1, %rax
0x48, 0x8d, 0x15, 0xf6, 0x06, 0x00, 0x00, //0x00000223 leaq $1782(%rip), %rdx /* _Digits+0(%rip) */
0x8a, 0x04, 0x10, //0x0000022a movb (%rax,%rdx), %al
0x89, 0xca, //0x0000022d movl %ecx, %edx
0xff, 0xc1, //0x0000022f incl %ecx
0x88, 0x44, 0x17, 0x01, //0x00000231 movb %al, $1(%rdi,%rdx)
0xff, 0xc1, //0x00000235 incl %ecx
0x89, 0xc8, //0x00000237 movl %ecx, %eax
0x5d, //0x00000239 popq %rbp
0xc3, //0x0000023a retq
//0x0000023b LBB0_12
0x31, 0xc9, //0x0000023b xorl %ecx, %ecx
0x81, 0xfe, 0x40, 0x42, 0x0f, 0x00, //0x0000023d cmpl $1000000, %esi
0x0f, 0x82, 0x86, 0x00, 0x00, 0x00, //0x00000243 jb LBB0_14
//0x00000249 LBB0_13
0x44, 0x89, 0xd0, //0x00000249 movl %r10d, %eax
0x48, 0x83, 0xc8, 0x01, //0x0000024c orq $1, %rax
0x48, 0x8d, 0x35, 0xc9, 0x06, 0x00, 0x00, //0x00000250 leaq $1737(%rip), %rsi /* _Digits+0(%rip) */
0x8a, 0x04, 0x30, //0x00000257 movb (%rax,%rsi), %al
0x89, 0xce, //0x0000025a movl %ecx, %esi
0xff, 0xc1, //0x0000025c incl %ecx
0x88, 0x04, 0x37, //0x0000025e movb %al, (%rdi,%rsi)
//0x00000261 LBB0_15
0x48, 0x8d, 0x05, 0xb8, 0x06, 0x00, 0x00, //0x00000261 leaq $1720(%rip), %rax /* _Digits+0(%rip) */
0x41, 0x8a, 0x04, 0x01, //0x00000268 movb (%r9,%rax), %al
0x89, 0xce, //0x0000026c movl %ecx, %esi
0xff, 0xc1, //0x0000026e incl %ecx
0x88, 0x04, 0x37, //0x00000270 movb %al, (%rdi,%rsi)
//0x00000273 LBB0_16
0x41, 0x0f, 0xb7, 0xc1, //0x00000273 movzwl %r9w, %eax
0x48, 0x83, 0xc8, 0x01, //0x00000277 orq $1, %rax
0x48, 0x8d, 0x35, 0x9e, 0x06, 0x00, 0x00, //0x0000027b leaq $1694(%rip), %rsi /* _Digits+0(%rip) */
0x8a, 0x04, 0x30, //0x00000282 movb (%rax,%rsi), %al
0x89, 0xca, //0x00000285 movl %ecx, %edx
0x88, 0x04, 0x3a, //0x00000287 movb %al, (%rdx,%rdi)
0x41, 0x8a, 0x04, 0x30, //0x0000028a movb (%r8,%rsi), %al
0x88, 0x44, 0x3a, 0x01, //0x0000028e movb %al, $1(%rdx,%rdi)
0x41, 0x0f, 0xb7, 0xc0, //0x00000292 movzwl %r8w, %eax
0x48, 0x83, 0xc8, 0x01, //0x00000296 orq $1, %rax
0x8a, 0x04, 0x30, //0x0000029a movb (%rax,%rsi), %al
0x88, 0x44, 0x3a, 0x02, //0x0000029d movb %al, $2(%rdx,%rdi)
0x41, 0x8a, 0x04, 0x33, //0x000002a1 movb (%r11,%rsi), %al
0x88, 0x44, 0x3a, 0x03, //0x000002a5 movb %al, $3(%rdx,%rdi)
0x41, 0x0f, 0xb7, 0xc3, //0x000002a9 movzwl %r11w, %eax
0x48, 0x83, 0xc8, 0x01, //0x000002ad orq $1, %rax
0x8a, 0x04, 0x30, //0x000002b1 movb (%rax,%rsi), %al
0x83, 0xc1, 0x05, //0x000002b4 addl $5, %ecx
0x88, 0x44, 0x3a, 0x04, //0x000002b7 movb %al, $4(%rdx,%rdi)
0x89, 0xc8, //0x000002bb movl %ecx, %eax
0x5d, //0x000002bd popq %rbp
0xc3, //0x000002be retq
//0x000002bf LBB0_30
0x31, 0xc9, //0x000002bf xorl %ecx, %ecx
0x83, 0xfe, 0x0a, //0x000002c1 cmpl $10, %esi
0x0f, 0x83, 0x40, 0xff, 0xff, 0xff, //0x000002c4 jae LBB0_31
0xe9, 0x4d, 0xff, 0xff, 0xff, //0x000002ca jmp LBB0_32
//0x000002cf LBB0_14
0x31, 0xc9, //0x000002cf xorl %ecx, %ecx
0x81, 0xfe, 0xa0, 0x86, 0x01, 0x00, //0x000002d1 cmpl $100000, %esi
0x0f, 0x83, 0x84, 0xff, 0xff, 0xff, //0x000002d7 jae LBB0_15
0xe9, 0x91, 0xff, 0xff, 0xff, //0x000002dd jmp LBB0_16
//0x000002e2 LBB0_33
0x48, 0x81, 0xfe, 0xff, 0xe0, 0xf5, 0x05, //0x000002e2 cmpq $99999999, %rsi
0x0f, 0x87, 0x3c, 0x02, 0x00, 0x00, //0x000002e9 ja LBB0_41
0x89, 0xf0, //0x000002ef movl %esi, %eax
0xba, 0x59, 0x17, 0xb7, 0xd1, //0x000002f1 movl $3518437209, %edx
0x48, 0x0f, 0xaf, 0xd0, //0x000002f6 imulq %rax, %rdx
0x48, 0xc1, 0xea, 0x2d, //0x000002fa shrq $45, %rdx
0x44, 0x69, 0xc2, 0x10, 0x27, 0x00, 0x00, //0x000002fe imull $10000, %edx, %r8d
0x89, 0xf1, //0x00000305 movl %esi, %ecx
0x44, 0x29, 0xc1, //0x00000307 subl %r8d, %ecx
0x4c, 0x69, 0xd0, 0x83, 0xde, 0x1b, 0x43, //0x0000030a imulq $1125899907, %rax, %r10
0x49, 0xc1, 0xea, 0x31, //0x00000311 shrq $49, %r10
0x41, 0x83, 0xe2, 0xfe, //0x00000315 andl $-2, %r10d
0x0f, 0xb7, 0xc2, //0x00000319 movzwl %dx, %eax
0xc1, 0xe8, 0x02, //0x0000031c shrl $2, %eax
0x69, 0xc0, 0x7b, 0x14, 0x00, 0x00, //0x0000031f imull $5243, %eax, %eax
0xc1, 0xe8, 0x11, //0x00000325 shrl $17, %eax
0x6b, 0xc0, 0x64, //0x00000328 imull $100, %eax, %eax
0x29, 0xc2, //0x0000032b subl %eax, %edx
0x44, 0x0f, 0xb7, 0xca, //0x0000032d movzwl %dx, %r9d
0x4d, 0x01, 0xc9, //0x00000331 addq %r9, %r9
0x0f, 0xb7, 0xc1, //0x00000334 movzwl %cx, %eax
0xc1, 0xe8, 0x02, //0x00000337 shrl $2, %eax
0x69, 0xc0, 0x7b, 0x14, 0x00, 0x00, //0x0000033a imull $5243, %eax, %eax
0xc1, 0xe8, 0x11, //0x00000340 shrl $17, %eax
0x4c, 0x8d, 0x04, 0x00, //0x00000343 leaq (%rax,%rax), %r8
0x6b, 0xc0, 0x64, //0x00000347 imull $100, %eax, %eax
0x29, 0xc1, //0x0000034a subl %eax, %ecx
0x44, 0x0f, 0xb7, 0xd9, //0x0000034c movzwl %cx, %r11d
0x4d, 0x01, 0xdb, //0x00000350 addq %r11, %r11
0x81, 0xfe, 0x80, 0x96, 0x98, 0x00, //0x00000353 cmpl $10000000, %esi
0x0f, 0x82, 0x30, 0x01, 0x00, 0x00, //0x00000359 jb LBB0_36
0x48, 0x8d, 0x05, 0xba, 0x05, 0x00, 0x00, //0x0000035f leaq $1466(%rip), %rax /* _Digits+0(%rip) */
0x41, 0x8a, 0x04, 0x02, //0x00000366 movb (%r10,%rax), %al
0x88, 0x47, 0x01, //0x0000036a movb %al, $1(%rdi)
0xb9, 0x01, 0x00, 0x00, 0x00, //0x0000036d movl $1, %ecx
0xe9, 0x26, 0x01, 0x00, 0x00, //0x00000372 jmp LBB0_37
//0x00000377 LBB0_17
0x48, 0xb9, 0x00, 0x00, 0xc1, 0x6f, 0xf2, 0x86, 0x23, 0x00, //0x00000377 movabsq $10000000000000000, %rcx
0x48, 0x39, 0xce, //0x00000381 cmpq %rcx, %rsi
0x0f, 0x83, 0xbc, 0x02, 0x00, 0x00, //0x00000384 jae LBB0_19
0x48, 0xb9, 0xfd, 0xce, 0x61, 0x84, 0x11, 0x77, 0xcc, 0xab, //0x0000038a movabsq $-6067343680855748867, %rcx
0x48, 0x89, 0xf0, //0x00000394 movq %rsi, %rax
0x48, 0xf7, 0xe1, //0x00000397 mulq %rcx
0x48, 0xc1, 0xea, 0x1a, //0x0000039a shrq $26, %rdx
0x69, 0xc2, 0x00, 0xe1, 0xf5, 0x05, //0x0000039e imull $100000000, %edx, %eax
0x29, 0xc6, //0x000003a4 subl %eax, %esi
0xc5, 0xf9, 0x6e, 0xc2, //0x000003a6 vmovd %edx, %xmm0
0xc5, 0xfa, 0x6f, 0x0d, 0x4e, 0xfc, 0xff, 0xff, //0x000003aa vmovdqu $-946(%rip), %xmm1 /* LCPI0_0+0(%rip) */
0xc5, 0xf9, 0xf4, 0xd1, //0x000003b2 vpmuludq %xmm1, %xmm0, %xmm2
0xc5, 0xe9, 0x73, 0xd2, 0x2d, //0x000003b6 vpsrlq $45, %xmm2, %xmm2
0xb8, 0x10, 0x27, 0x00, 0x00, //0x000003bb movl $10000, %eax
0xc4, 0xe1, 0xf9, 0x6e, 0xd8, //0x000003c0 vmovq %rax, %xmm3
0xc5, 0xe9, 0xf4, 0xe3, //0x000003c5 vpmuludq %xmm3, %xmm2, %xmm4
0xc5, 0xf9, 0xfa, 0xc4, //0x000003c9 vpsubd %xmm4, %xmm0, %xmm0
0xc5, 0xe9, 0x61, 0xc0, //0x000003cd vpunpcklwd %xmm0, %xmm2, %xmm0
0xc5, 0xf9, 0x73, 0xf0, 0x02, //0x000003d1 vpsllq $2, %xmm0, %xmm0
0xc5, 0xfb, 0x70, 0xc0, 0x50, //0x000003d6 vpshuflw $80, %xmm0, %xmm0
0xc5, 0xf9, 0x70, 0xc0, 0x50, //0x000003db vpshufd $80, %xmm0, %xmm0
0xc5, 0xfb, 0x12, 0x15, 0x48, 0xfc, 0xff, 0xff, //0x000003e0 vmovddup $-952(%rip), %xmm2 /* LCPI0_1+0(%rip) */
0xc5, 0xf9, 0xe4, 0xc2, //0x000003e8 vpmulhuw %xmm2, %xmm0, %xmm0
0xc5, 0xfb, 0x12, 0x25, 0x44, 0xfc, 0xff, 0xff, //0x000003ec vmovddup $-956(%rip), %xmm4 /* LCPI0_2+0(%rip) */
0xc5, 0xf9, 0xe4, 0xc4, //0x000003f4 vpmulhuw %xmm4, %xmm0, %xmm0
0xc5, 0xfa, 0x6f, 0x2d, 0x10, 0xfc, 0xff, 0xff, //0x000003f8 vmovdqu $-1008(%rip), %xmm5 /* LCPI0_3+0(%rip) */
0xc5, 0xf9, 0xd5, 0xf5, //0x00000400 vpmullw %xmm5, %xmm0, %xmm6
0xc5, 0xc9, 0x73, 0xf6, 0x10, //0x00000404 vpsllq $16, %xmm6, %xmm6
0xc5, 0xf9, 0xf9, 0xc6, //0x00000409 vpsubw %xmm6, %xmm0, %xmm0
0xc5, 0xf9, 0x6e, 0xf6, //0x0000040d vmovd %esi, %xmm6
0xc5, 0xc9, 0xf4, 0xc9, //0x00000411 vpmuludq %xmm1, %xmm6, %xmm1
0xc5, 0xf1, 0x73, 0xd1, 0x2d, //0x00000415 vpsrlq $45, %xmm1, %xmm1
0xc5, 0xf1, 0xf4, 0xdb, //0x0000041a vpmuludq %xmm3, %xmm1, %xmm3
0xc5, 0xc9, 0xfa, 0xdb, //0x0000041e vpsubd %xmm3, %xmm6, %xmm3
0xc5, 0xf1, 0x61, 0xcb, //0x00000422 vpunpcklwd %xmm3, %xmm1, %xmm1
0xc5, 0xf1, 0x73, 0xf1, 0x02, //0x00000426 vpsllq $2, %xmm1, %xmm1
0xc5, 0xfb, 0x70, 0xc9, 0x50, //0x0000042b vpshuflw $80, %xmm1, %xmm1
0xc5, 0xf9, 0x70, 0xc9, 0x50, //0x00000430 vpshufd $80, %xmm1, %xmm1
0xc5, 0xf1, 0xe4, 0xca, //0x00000435 vpmulhuw %xmm2, %xmm1, %xmm1
0xc5, 0xf1, 0xe4, 0xcc, //0x00000439 vpmulhuw %xmm4, %xmm1, %xmm1
0xc5, 0xf1, 0xd5, 0xd5, //0x0000043d vpmullw %xmm5, %xmm1, %xmm2
0xc5, 0xe9, 0x73, 0xf2, 0x10, //0x00000441 vpsllq $16, %xmm2, %xmm2
0xc5, 0xf1, 0xf9, 0xca, //0x00000446 vpsubw %xmm2, %xmm1, %xmm1
0xc5, 0xf9, 0x67, 0xc1, //0x0000044a vpackuswb %xmm1, %xmm0, %xmm0
0xc5, 0xf9, 0xfc, 0x0d, 0xca, 0xfb, 0xff, 0xff, //0x0000044e vpaddb $-1078(%rip), %xmm0, %xmm1 /* LCPI0_4+0(%rip) */
0xc5, 0xe9, 0xef, 0xd2, //0x00000456 vpxor %xmm2, %xmm2, %xmm2
0xc5, 0xf9, 0x74, 0xc2, //0x0000045a vpcmpeqb %xmm2, %xmm0, %xmm0
0xc5, 0xf9, 0xd7, 0xc0, //0x0000045e vpmovmskb %xmm0, %eax
0x0d, 0x00, 0x80, 0x00, 0x00, //0x00000462 orl $32768, %eax
0x35, 0xff, 0x7f, 0xff, 0xff, //0x00000467 xorl $-32769, %eax
0x0f, 0xbc, 0xc0, //0x0000046c bsfl %eax, %eax
0xb9, 0x10, 0x00, 0x00, 0x00, //0x0000046f movl $16, %ecx
0x29, 0xc1, //0x00000474 subl %eax, %ecx
0x48, 0xc1, 0xe0, 0x04, //0x00000476 shlq $4, %rax
0x48, 0x8d, 0x15, 0x6f, 0x05, 0x00, 0x00, //0x0000047a leaq $1391(%rip), %rdx /* _VecShiftShuffles+0(%rip) */
0xc4, 0xe2, 0x71, 0x00, 0x04, 0x10, //0x00000481 vpshufb (%rax,%rdx), %xmm1, %xmm0
0xc5, 0xfa, 0x7f, 0x07, //0x00000487 vmovdqu %xmm0, (%rdi)
0x89, 0xc8, //0x0000048b movl %ecx, %eax
0x5d, //0x0000048d popq %rbp
0xc3, //0x0000048e retq
//0x0000048f LBB0_36
0x31, 0xc9, //0x0000048f xorl %ecx, %ecx
0x81, 0xfe, 0x40, 0x42, 0x0f, 0x00, //0x00000491 cmpl $1000000, %esi
0x0f, 0x82, 0x7b, 0x00, 0x00, 0x00, //0x00000497 jb LBB0_38
//0x0000049d LBB0_37
0x44, 0x89, 0xd0, //0x0000049d movl %r10d, %eax
0x48, 0x83, 0xc8, 0x01, //0x000004a0 orq $1, %rax
0x48, 0x8d, 0x35, 0x75, 0x04, 0x00, 0x00, //0x000004a4 leaq $1141(%rip), %rsi /* _Digits+0(%rip) */
0x8a, 0x04, 0x30, //0x000004ab movb (%rax,%rsi), %al
0x89, 0xce, //0x000004ae movl %ecx, %esi
0xff, 0xc1, //0x000004b0 incl %ecx
0x88, 0x44, 0x37, 0x01, //0x000004b2 movb %al, $1(%rdi,%rsi)
//0x000004b6 LBB0_39
0x48, 0x8d, 0x05, 0x63, 0x04, 0x00, 0x00, //0x000004b6 leaq $1123(%rip), %rax /* _Digits+0(%rip) */
0x41, 0x8a, 0x04, 0x01, //0x000004bd movb (%r9,%rax), %al
0x89, 0xce, //0x000004c1 movl %ecx, %esi
0xff, 0xc1, //0x000004c3 incl %ecx
0x88, 0x44, 0x37, 0x01, //0x000004c5 movb %al, $1(%rdi,%rsi)
//0x000004c9 LBB0_40
0x41, 0x0f, 0xb7, 0xc1, //0x000004c9 movzwl %r9w, %eax
0x48, 0x83, 0xc8, 0x01, //0x000004cd orq $1, %rax
0x48, 0x8d, 0x35, 0x48, 0x04, 0x00, 0x00, //0x000004d1 leaq $1096(%rip), %rsi /* _Digits+0(%rip) */
0x8a, 0x04, 0x30, //0x000004d8 movb (%rax,%rsi), %al
0x89, 0xca, //0x000004db movl %ecx, %edx
0x88, 0x44, 0x17, 0x01, //0x000004dd movb %al, $1(%rdi,%rdx)
0x41, 0x8a, 0x04, 0x30, //0x000004e1 movb (%r8,%rsi), %al
0x88, 0x44, 0x17, 0x02, //0x000004e5 movb %al, $2(%rdi,%rdx)
0x41, 0x0f, 0xb7, 0xc0, //0x000004e9 movzwl %r8w, %eax
0x48, 0x83, 0xc8, 0x01, //0x000004ed orq $1, %rax
0x8a, 0x04, 0x30, //0x000004f1 movb (%rax,%rsi), %al
0x88, 0x44, 0x17, 0x03, //0x000004f4 movb %al, $3(%rdi,%rdx)
0x41, 0x8a, 0x04, 0x33, //0x000004f8 movb (%r11,%rsi), %al
0x88, 0x44, 0x17, 0x04, //0x000004fc movb %al, $4(%rdi,%rdx)
0x41, 0x0f, 0xb7, 0xc3, //0x00000500 movzwl %r11w, %eax
0x48, 0x83, 0xc8, 0x01, //0x00000504 orq $1, %rax
0x8a, 0x04, 0x30, //0x00000508 movb (%rax,%rsi), %al
0x83, 0xc1, 0x05, //0x0000050b addl $5, %ecx
0x88, 0x44, 0x17, 0x05, //0x0000050e movb %al, $5(%rdi,%rdx)
0xff, 0xc1, //0x00000512 incl %ecx
0x89, 0xc8, //0x00000514 movl %ecx, %eax
0x5d, //0x00000516 popq %rbp
0xc3, //0x00000517 retq
//0x00000518 LBB0_38
0x31, 0xc9, //0x00000518 xorl %ecx, %ecx
0x81, 0xfe, 0xa0, 0x86, 0x01, 0x00, //0x0000051a cmpl $100000, %esi
0x0f, 0x83, 0x90, 0xff, 0xff, 0xff, //0x00000520 jae LBB0_39
0xe9, 0x9e, 0xff, 0xff, 0xff, //0x00000526 jmp LBB0_40
//0x0000052b LBB0_41
0x48, 0xb9, 0x00, 0x00, 0xc1, 0x6f, 0xf2, 0x86, 0x23, 0x00, //0x0000052b movabsq $10000000000000000, %rcx
0x48, 0x39, 0xce, //0x00000535 cmpq %rcx, %rsi
0x0f, 0x83, 0x71, 0x02, 0x00, 0x00, //0x00000538 jae LBB0_43
0x48, 0xb9, 0xfd, 0xce, 0x61, 0x84, 0x11, 0x77, 0xcc, 0xab, //0x0000053e movabsq $-6067343680855748867, %rcx
0x48, 0x89, 0xf0, //0x00000548 movq %rsi, %rax
0x48, 0xf7, 0xe1, //0x0000054b mulq %rcx
0x48, 0xc1, 0xea, 0x1a, //0x0000054e shrq $26, %rdx
0x69, 0xc2, 0x00, 0xe1, 0xf5, 0x05, //0x00000552 imull $100000000, %edx, %eax
0x29, 0xc6, //0x00000558 subl %eax, %esi
0xc5, 0xf9, 0x6e, 0xc2, //0x0000055a vmovd %edx, %xmm0
0xc5, 0xfa, 0x6f, 0x0d, 0x9a, 0xfa, 0xff, 0xff, //0x0000055e vmovdqu $-1382(%rip), %xmm1 /* LCPI0_0+0(%rip) */
0xc5, 0xf9, 0xf4, 0xd1, //0x00000566 vpmuludq %xmm1, %xmm0, %xmm2
0xc5, 0xe9, 0x73, 0xd2, 0x2d, //0x0000056a vpsrlq $45, %xmm2, %xmm2
0xb8, 0x10, 0x27, 0x00, 0x00, //0x0000056f movl $10000, %eax
0xc4, 0xe1, 0xf9, 0x6e, 0xd8, //0x00000574 vmovq %rax, %xmm3
0xc5, 0xe9, 0xf4, 0xe3, //0x00000579 vpmuludq %xmm3, %xmm2, %xmm4
0xc5, 0xf9, 0xfa, 0xc4, //0x0000057d vpsubd %xmm4, %xmm0, %xmm0
0xc5, 0xe9, 0x61, 0xc0, //0x00000581 vpunpcklwd %xmm0, %xmm2, %xmm0
0xc5, 0xf9, 0x73, 0xf0, 0x02, //0x00000585 vpsllq $2, %xmm0, %xmm0
0xc5, 0xfb, 0x70, 0xc0, 0x50, //0x0000058a vpshuflw $80, %xmm0, %xmm0
0xc5, 0xf9, 0x70, 0xc0, 0x50, //0x0000058f vpshufd $80, %xmm0, %xmm0
0xc5, 0xfb, 0x12, 0x15, 0x94, 0xfa, 0xff, 0xff, //0x00000594 vmovddup $-1388(%rip), %xmm2 /* LCPI0_1+0(%rip) */
0xc5, 0xf9, 0xe4, 0xc2, //0x0000059c vpmulhuw %xmm2, %xmm0, %xmm0
0xc5, 0xfb, 0x12, 0x25, 0x90, 0xfa, 0xff, 0xff, //0x000005a0 vmovddup $-1392(%rip), %xmm4 /* LCPI0_2+0(%rip) */
0xc5, 0xf9, 0xe4, 0xc4, //0x000005a8 vpmulhuw %xmm4, %xmm0, %xmm0
0xc5, 0xfa, 0x6f, 0x2d, 0x5c, 0xfa, 0xff, 0xff, //0x000005ac vmovdqu $-1444(%rip), %xmm5 /* LCPI0_3+0(%rip) */
0xc5, 0xf9, 0xd5, 0xf5, //0x000005b4 vpmullw %xmm5, %xmm0, %xmm6
0xc5, 0xc9, 0x73, 0xf6, 0x10, //0x000005b8 vpsllq $16, %xmm6, %xmm6
0xc5, 0xf9, 0xf9, 0xc6, //0x000005bd vpsubw %xmm6, %xmm0, %xmm0
0xc5, 0xf9, 0x6e, 0xf6, //0x000005c1 vmovd %esi, %xmm6
0xc5, 0xc9, 0xf4, 0xc9, //0x000005c5 vpmuludq %xmm1, %xmm6, %xmm1
0xc5, 0xf1, 0x73, 0xd1, 0x2d, //0x000005c9 vpsrlq $45, %xmm1, %xmm1
0xc5, 0xf1, 0xf4, 0xdb, //0x000005ce vpmuludq %xmm3, %xmm1, %xmm3
0xc5, 0xc9, 0xfa, 0xdb, //0x000005d2 vpsubd %xmm3, %xmm6, %xmm3
0xc5, 0xf1, 0x61, 0xcb, //0x000005d6 vpunpcklwd %xmm3, %xmm1, %xmm1
0xc5, 0xf1, 0x73, 0xf1, 0x02, //0x000005da vpsllq $2, %xmm1, %xmm1
0xc5, 0xfb, 0x70, 0xc9, 0x50, //0x000005df vpshuflw $80, %xmm1, %xmm1
0xc5, 0xf9, 0x70, 0xc9, 0x50, //0x000005e4 vpshufd $80, %xmm1, %xmm1
0xc5, 0xf1, 0xe4, 0xca, //0x000005e9 vpmulhuw %xmm2, %xmm1, %xmm1
0xc5, 0xf1, 0xe4, 0xcc, //0x000005ed vpmulhuw %xmm4, %xmm1, %xmm1
0xc5, 0xf1, 0xd5, 0xd5, //0x000005f1 vpmullw %xmm5, %xmm1, %xmm2
0xc5, 0xe9, 0x73, 0xf2, 0x10, //0x000005f5 vpsllq $16, %xmm2, %xmm2
0xc5, 0xf1, 0xf9, 0xca, //0x000005fa vpsubw %xmm2, %xmm1, %xmm1
0xc5, 0xf9, 0x67, 0xc1, //0x000005fe vpackuswb %xmm1, %xmm0, %xmm0
0xc5, 0xf9, 0xfc, 0x0d, 0x16, 0xfa, 0xff, 0xff, //0x00000602 vpaddb $-1514(%rip), %xmm0, %xmm1 /* LCPI0_4+0(%rip) */
0xc5, 0xe9, 0xef, 0xd2, //0x0000060a vpxor %xmm2, %xmm2, %xmm2
0xc5, 0xf9, 0x74, 0xc2, //0x0000060e vpcmpeqb %xmm2, %xmm0, %xmm0
0xc5, 0xf9, 0xd7, 0xc0, //0x00000612 vpmovmskb %xmm0, %eax
0x0d, 0x00, 0x80, 0x00, 0x00, //0x00000616 orl $32768, %eax
0x35, 0xff, 0x7f, 0xff, 0xff, //0x0000061b xorl $-32769, %eax
0x0f, 0xbc, 0xc0, //0x00000620 bsfl %eax, %eax
0xb9, 0x10, 0x00, 0x00, 0x00, //0x00000623 movl $16, %ecx
0x29, 0xc1, //0x00000628 subl %eax, %ecx
0x48, 0xc1, 0xe0, 0x04, //0x0000062a shlq $4, %rax
0x48, 0x8d, 0x15, 0xbb, 0x03, 0x00, 0x00, //0x0000062e leaq $955(%rip), %rdx /* _VecShiftShuffles+0(%rip) */
0xc4, 0xe2, 0x71, 0x00, 0x04, 0x10, //0x00000635 vpshufb (%rax,%rdx), %xmm1, %xmm0
0xc5, 0xfa, 0x7f, 0x47, 0x01, //0x0000063b vmovdqu %xmm0, $1(%rdi)
0xff, 0xc1, //0x00000640 incl %ecx
0x89, 0xc8, //0x00000642 movl %ecx, %eax
0x5d, //0x00000644 popq %rbp
0xc3, //0x00000645 retq
//0x00000646 LBB0_19
0x48, 0xba, 0x57, 0x78, 0x13, 0xb1, 0x2f, 0x65, 0xa5, 0x39, //0x00000646 movabsq $4153837486827862103, %rdx
0x48, 0x89, 0xf0, //0x00000650 movq %rsi, %rax
0x48, 0xf7, 0xe2, //0x00000653 mulq %rdx
0x48, 0xc1, 0xea, 0x33, //0x00000656 shrq $51, %rdx
0x48, 0x0f, 0xaf, 0xca, //0x0000065a imulq %rdx, %rcx
0x48, 0x29, 0xce, //0x0000065e subq %rcx, %rsi
0x83, 0xfa, 0x09, //0x00000661 cmpl $9, %edx
0x0f, 0x87, 0x0f, 0x00, 0x00, 0x00, //0x00000664 ja LBB0_21
0x80, 0xc2, 0x30, //0x0000066a addb $48, %dl
0x88, 0x17, //0x0000066d movb %dl, (%rdi)
0xb9, 0x01, 0x00, 0x00, 0x00, //0x0000066f movl $1, %ecx
0xe9, 0x5c, 0x00, 0x00, 0x00, //0x00000674 jmp LBB0_24
//0x00000679 LBB0_21
0x83, 0xfa, 0x63, //0x00000679 cmpl $99, %edx
0x0f, 0x87, 0x1f, 0x00, 0x00, 0x00, //0x0000067c ja LBB0_23
0x89, 0xd0, //0x00000682 movl %edx, %eax
0x48, 0x8d, 0x0d, 0x95, 0x02, 0x00, 0x00, //0x00000684 leaq $661(%rip), %rcx /* _Digits+0(%rip) */
0x8a, 0x14, 0x41, //0x0000068b movb (%rcx,%rax,2), %dl
0x8a, 0x44, 0x41, 0x01, //0x0000068e movb $1(%rcx,%rax,2), %al
0x88, 0x17, //0x00000692 movb %dl, (%rdi)
0x88, 0x47, 0x01, //0x00000694 movb %al, $1(%rdi)
0xb9, 0x02, 0x00, 0x00, 0x00, //0x00000697 movl $2, %ecx
0xe9, 0x34, 0x00, 0x00, 0x00, //0x0000069c jmp LBB0_24
//0x000006a1 LBB0_23
0x89, 0xd0, //0x000006a1 movl %edx, %eax
0xc1, 0xe8, 0x02, //0x000006a3 shrl $2, %eax
0x69, 0xc0, 0x7b, 0x14, 0x00, 0x00, //0x000006a6 imull $5243, %eax, %eax
0xc1, 0xe8, 0x11, //0x000006ac shrl $17, %eax
0x8d, 0x48, 0x30, //0x000006af leal $48(%rax), %ecx
0x88, 0x0f, //0x000006b2 movb %cl, (%rdi)
0x6b, 0xc0, 0x64, //0x000006b4 imull $100, %eax, %eax
0x29, 0xc2, //0x000006b7 subl %eax, %edx
0x0f, 0xb7, 0xc2, //0x000006b9 movzwl %dx, %eax
0x48, 0x8d, 0x0d, 0x5d, 0x02, 0x00, 0x00, //0x000006bc leaq $605(%rip), %rcx /* _Digits+0(%rip) */
0x8a, 0x14, 0x41, //0x000006c3 movb (%rcx,%rax,2), %dl
0x8a, 0x44, 0x41, 0x01, //0x000006c6 movb $1(%rcx,%rax,2), %al
0x88, 0x57, 0x01, //0x000006ca movb %dl, $1(%rdi)
0x88, 0x47, 0x02, //0x000006cd movb %al, $2(%rdi)
0xb9, 0x03, 0x00, 0x00, 0x00, //0x000006d0 movl $3, %ecx
//0x000006d5 LBB0_24
0x48, 0xba, 0xfd, 0xce, 0x61, 0x84, 0x11, 0x77, 0xcc, 0xab, //0x000006d5 movabsq $-6067343680855748867, %rdx
0x48, 0x89, 0xf0, //0x000006df movq %rsi, %rax
0x48, 0xf7, 0xe2, //0x000006e2 mulq %rdx
0x48, 0xc1, 0xea, 0x1a, //0x000006e5 shrq $26, %rdx
0xc5, 0xf9, 0x6e, 0xc2, //0x000006e9 vmovd %edx, %xmm0
0xc5, 0xfa, 0x6f, 0x0d, 0x0b, 0xf9, 0xff, 0xff, //0x000006ed vmovdqu $-1781(%rip), %xmm1 /* LCPI0_0+0(%rip) */
0xc5, 0xf9, 0xf4, 0xd1, //0x000006f5 vpmuludq %xmm1, %xmm0, %xmm2
0xc5, 0xe9, 0x73, 0xd2, 0x2d, //0x000006f9 vpsrlq $45, %xmm2, %xmm2
0xb8, 0x10, 0x27, 0x00, 0x00, //0x000006fe movl $10000, %eax
0xc4, 0xe1, 0xf9, 0x6e, 0xd8, //0x00000703 vmovq %rax, %xmm3
0xc5, 0xe9, 0xf4, 0xe3, //0x00000708 vpmuludq %xmm3, %xmm2, %xmm4
0xc5, 0xf9, 0xfa, 0xc4, //0x0000070c vpsubd %xmm4, %xmm0, %xmm0
0xc5, 0xe9, 0x61, 0xc0, //0x00000710 vpunpcklwd %xmm0, %xmm2, %xmm0
0xc5, 0xf9, 0x73, 0xf0, 0x02, //0x00000714 vpsllq $2, %xmm0, %xmm0
0xc5, 0xfb, 0x70, 0xc0, 0x50, //0x00000719 vpshuflw $80, %xmm0, %xmm0
0xc5, 0xf9, 0x70, 0xc0, 0x50, //0x0000071e vpshufd $80, %xmm0, %xmm0
0xc5, 0xfb, 0x12, 0x15, 0x05, 0xf9, 0xff, 0xff, //0x00000723 vmovddup $-1787(%rip), %xmm2 /* LCPI0_1+0(%rip) */
0xc5, 0xf9, 0xe4, 0xc2, //0x0000072b vpmulhuw %xmm2, %xmm0, %xmm0
0xc5, 0xfb, 0x12, 0x25, 0x01, 0xf9, 0xff, 0xff, //0x0000072f vmovddup $-1791(%rip), %xmm4 /* LCPI0_2+0(%rip) */
0xc5, 0xf9, 0xe4, 0xc4, //0x00000737 vpmulhuw %xmm4, %xmm0, %xmm0
0xc5, 0xfa, 0x6f, 0x2d, 0xcd, 0xf8, 0xff, 0xff, //0x0000073b vmovdqu $-1843(%rip), %xmm5 /* LCPI0_3+0(%rip) */
0xc5, 0xf9, 0xd5, 0xf5, //0x00000743 vpmullw %xmm5, %xmm0, %xmm6
0xc5, 0xc9, 0x73, 0xf6, 0x10, //0x00000747 vpsllq $16, %xmm6, %xmm6
0xc5, 0xf9, 0xf9, 0xc6, //0x0000074c vpsubw %xmm6, %xmm0, %xmm0
0x69, 0xc2, 0x00, 0xe1, 0xf5, 0x05, //0x00000750 imull $100000000, %edx, %eax
0x29, 0xc6, //0x00000756 subl %eax, %esi
0xc5, 0xf9, 0x6e, 0xf6, //0x00000758 vmovd %esi, %xmm6
0xc5, 0xc9, 0xf4, 0xc9, //0x0000075c vpmuludq %xmm1, %xmm6, %xmm1
0xc5, 0xf1, 0x73, 0xd1, 0x2d, //0x00000760 vpsrlq $45, %xmm1, %xmm1
0xc5, 0xf1, 0xf4, 0xdb, //0x00000765 vpmuludq %xmm3, %xmm1, %xmm3
0xc5, 0xc9, 0xfa, 0xdb, //0x00000769 vpsubd %xmm3, %xmm6, %xmm3
0xc5, 0xf1, 0x61, 0xcb, //0x0000076d vpunpcklwd %xmm3, %xmm1, %xmm1
0xc5, 0xf1, 0x73, 0xf1, 0x02, //0x00000771 vpsllq $2, %xmm1, %xmm1
0xc5, 0xfb, 0x70, 0xc9, 0x50, //0x00000776 vpshuflw $80, %xmm1, %xmm1
0xc5, 0xf9, 0x70, 0xc9, 0x50, //0x0000077b vpshufd $80, %xmm1, %xmm1
0xc5, 0xf1, 0xe4, 0xca, //0x00000780 vpmulhuw %xmm2, %xmm1, %xmm1
0xc5, 0xf1, 0xe4, 0xcc, //0x00000784 vpmulhuw %xmm4, %xmm1, %xmm1
0xc5, 0xf1, 0xd5, 0xd5, //0x00000788 vpmullw %xmm5, %xmm1, %xmm2
0xc5, 0xe9, 0x73, 0xf2, 0x10, //0x0000078c vpsllq $16, %xmm2, %xmm2
0xc5, 0xf1, 0xf9, 0xca, //0x00000791 vpsubw %xmm2, %xmm1, %xmm1
0xc5, 0xf9, 0x67, 0xc1, //0x00000795 vpackuswb %xmm1, %xmm0, %xmm0
0xc5, 0xf9, 0xfc, 0x05, 0x7f, 0xf8, 0xff, 0xff, //0x00000799 vpaddb $-1921(%rip), %xmm0, %xmm0 /* LCPI0_4+0(%rip) */
0x89, 0xc8, //0x000007a1 movl %ecx, %eax
0xc5, 0xfa, 0x7f, 0x04, 0x07, //0x000007a3 vmovdqu %xmm0, (%rdi,%rax)
0x83, 0xc9, 0x10, //0x000007a8 orl $16, %ecx
0x89, 0xc8, //0x000007ab movl %ecx, %eax
0x5d, //0x000007ad popq %rbp
0xc3, //0x000007ae retq
//0x000007af LBB0_43
0x48, 0xba, 0x57, 0x78, 0x13, 0xb1, 0x2f, 0x65, 0xa5, 0x39, //0x000007af movabsq $4153837486827862103, %rdx
0x48, 0x89, 0xf0, //0x000007b9 movq %rsi, %rax
0x48, 0xf7, 0xe2, //0x000007bc mulq %rdx
0x48, 0xc1, 0xea, 0x33, //0x000007bf shrq $51, %rdx
0x48, 0x0f, 0xaf, 0xca, //0x000007c3 imulq %rdx, %rcx
0x48, 0x29, 0xce, //0x000007c7 subq %rcx, %rsi
0x83, 0xfa, 0x09, //0x000007ca cmpl $9, %edx
0x0f, 0x87, 0x10, 0x00, 0x00, 0x00, //0x000007cd ja LBB0_45
0x80, 0xc2, 0x30, //0x000007d3 addb $48, %dl
0x88, 0x57, 0x01, //0x000007d6 movb %dl, $1(%rdi)
0xb9, 0x01, 0x00, 0x00, 0x00, //0x000007d9 movl $1, %ecx
0xe9, 0x5e, 0x00, 0x00, 0x00, //0x000007de jmp LBB0_48
//0x000007e3 LBB0_45
0x83, 0xfa, 0x63, //0x000007e3 cmpl $99, %edx
0x0f, 0x87, 0x20, 0x00, 0x00, 0x00, //0x000007e6 ja LBB0_47
0x89, 0xd0, //0x000007ec movl %edx, %eax
0x48, 0x8d, 0x0d, 0x2b, 0x01, 0x00, 0x00, //0x000007ee leaq $299(%rip), %rcx /* _Digits+0(%rip) */
0x8a, 0x14, 0x41, //0x000007f5 movb (%rcx,%rax,2), %dl
0x8a, 0x44, 0x41, 0x01, //0x000007f8 movb $1(%rcx,%rax,2), %al
0x88, 0x57, 0x01, //0x000007fc movb %dl, $1(%rdi)
0x88, 0x47, 0x02, //0x000007ff movb %al, $2(%rdi)
0xb9, 0x02, 0x00, 0x00, 0x00, //0x00000802 movl $2, %ecx
0xe9, 0x35, 0x00, 0x00, 0x00, //0x00000807 jmp LBB0_48
//0x0000080c LBB0_47
0x89, 0xd0, //0x0000080c movl %edx, %eax
0xc1, 0xe8, 0x02, //0x0000080e shrl $2, %eax
0x69, 0xc0, 0x7b, 0x14, 0x00, 0x00, //0x00000811 imull $5243, %eax, %eax
0xc1, 0xe8, 0x11, //0x00000817 shrl $17, %eax
0x8d, 0x48, 0x30, //0x0000081a leal $48(%rax), %ecx
0x88, 0x4f, 0x01, //0x0000081d movb %cl, $1(%rdi)
0x6b, 0xc0, 0x64, //0x00000820 imull $100, %eax, %eax
0x29, 0xc2, //0x00000823 subl %eax, %edx
0x0f, 0xb7, 0xc2, //0x00000825 movzwl %dx, %eax
0x48, 0x8d, 0x0d, 0xf1, 0x00, 0x00, 0x00, //0x00000828 leaq $241(%rip), %rcx /* _Digits+0(%rip) */
0x8a, 0x14, 0x41, //0x0000082f movb (%rcx,%rax,2), %dl
0x8a, 0x44, 0x41, 0x01, //0x00000832 movb $1(%rcx,%rax,2), %al
0x88, 0x57, 0x02, //0x00000836 movb %dl, $2(%rdi)
0x88, 0x47, 0x03, //0x00000839 movb %al, $3(%rdi)
0xb9, 0x03, 0x00, 0x00, 0x00, //0x0000083c movl $3, %ecx
//0x00000841 LBB0_48
0x48, 0xba, 0xfd, 0xce, 0x61, 0x84, 0x11, 0x77, 0xcc, 0xab, //0x00000841 movabsq $-6067343680855748867, %rdx
0x48, 0x89, 0xf0, //0x0000084b movq %rsi, %rax
0x48, 0xf7, 0xe2, //0x0000084e mulq %rdx
0x48, 0xc1, 0xea, 0x1a, //0x00000851 shrq $26, %rdx
0xc5, 0xf9, 0x6e, 0xc2, //0x00000855 vmovd %edx, %xmm0
0xc5, 0xfa, 0x6f, 0x0d, 0x9f, 0xf7, 0xff, 0xff, //0x00000859 vmovdqu $-2145(%rip), %xmm1 /* LCPI0_0+0(%rip) */
0xc5, 0xf9, 0xf4, 0xd1, //0x00000861 vpmuludq %xmm1, %xmm0, %xmm2
0xc5, 0xe9, 0x73, 0xd2, 0x2d, //0x00000865 vpsrlq $45, %xmm2, %xmm2
0xb8, 0x10, 0x27, 0x00, 0x00, //0x0000086a movl $10000, %eax
0xc4, 0xe1, 0xf9, 0x6e, 0xd8, //0x0000086f vmovq %rax, %xmm3
0xc5, 0xe9, 0xf4, 0xe3, //0x00000874 vpmuludq %xmm3, %xmm2, %xmm4
0xc5, 0xf9, 0xfa, 0xc4, //0x00000878 vpsubd %xmm4, %xmm0, %xmm0
0xc5, 0xe9, 0x61, 0xc0, //0x0000087c vpunpcklwd %xmm0, %xmm2, %xmm0
0xc5, 0xf9, 0x73, 0xf0, 0x02, //0x00000880 vpsllq $2, %xmm0, %xmm0
0xc5, 0xfb, 0x70, 0xc0, 0x50, //0x00000885 vpshuflw $80, %xmm0, %xmm0
0xc5, 0xf9, 0x70, 0xc0, 0x50, //0x0000088a vpshufd $80, %xmm0, %xmm0
0xc5, 0xfb, 0x12, 0x15, 0x99, 0xf7, 0xff, 0xff, //0x0000088f vmovddup $-2151(%rip), %xmm2 /* LCPI0_1+0(%rip) */
0xc5, 0xf9, 0xe4, 0xc2, //0x00000897 vpmulhuw %xmm2, %xmm0, %xmm0
0xc5, 0xfb, 0x12, 0x25, 0x95, 0xf7, 0xff, 0xff, //0x0000089b vmovddup $-2155(%rip), %xmm4 /* LCPI0_2+0(%rip) */
0xc5, 0xf9, 0xe4, 0xc4, //0x000008a3 vpmulhuw %xmm4, %xmm0, %xmm0
0xc5, 0xfa, 0x6f, 0x2d, 0x61, 0xf7, 0xff, 0xff, //0x000008a7 vmovdqu $-2207(%rip), %xmm5 /* LCPI0_3+0(%rip) */
0xc5, 0xf9, 0xd5, 0xf5, //0x000008af vpmullw %xmm5, %xmm0, %xmm6
0xc5, 0xc9, 0x73, 0xf6, 0x10, //0x000008b3 vpsllq $16, %xmm6, %xmm6
0xc5, 0xf9, 0xf9, 0xc6, //0x000008b8 vpsubw %xmm6, %xmm0, %xmm0
0x69, 0xc2, 0x00, 0xe1, 0xf5, 0x05, //0x000008bc imull $100000000, %edx, %eax
0x29, 0xc6, //0x000008c2 subl %eax, %esi
0xc5, 0xf9, 0x6e, 0xf6, //0x000008c4 vmovd %esi, %xmm6
0xc5, 0xc9, 0xf4, 0xc9, //0x000008c8 vpmuludq %xmm1, %xmm6, %xmm1
0xc5, 0xf1, 0x73, 0xd1, 0x2d, //0x000008cc vpsrlq $45, %xmm1, %xmm1
0xc5, 0xf1, 0xf4, 0xdb, //0x000008d1 vpmuludq %xmm3, %xmm1, %xmm3
0xc5, 0xc9, 0xfa, 0xdb, //0x000008d5 vpsubd %xmm3, %xmm6, %xmm3
0xc5, 0xf1, 0x61, 0xcb, //0x000008d9 vpunpcklwd %xmm3, %xmm1, %xmm1
0xc5, 0xf1, 0x73, 0xf1, 0x02, //0x000008dd vpsllq $2, %xmm1, %xmm1
0xc5, 0xfb, 0x70, 0xc9, 0x50, //0x000008e2 vpshuflw $80, %xmm1, %xmm1
0xc5, 0xf9, 0x70, 0xc9, 0x50, //0x000008e7 vpshufd $80, %xmm1, %xmm1
0xc5, 0xf1, 0xe4, 0xca, //0x000008ec vpmulhuw %xmm2, %xmm1, %xmm1
0xc5, 0xf1, 0xe4, 0xcc, //0x000008f0 vpmulhuw %xmm4, %xmm1, %xmm1
0xc5, 0xf1, 0xd5, 0xd5, //0x000008f4 vpmullw %xmm5, %xmm1, %xmm2
0xc5, 0xe9, 0x73, 0xf2, 0x10, //0x000008f8 vpsllq $16, %xmm2, %xmm2
0xc5, 0xf1, 0xf9, 0xca, //0x000008fd vpsubw %xmm2, %xmm1, %xmm1
0xc5, 0xf9, 0x67, 0xc1, //0x00000901 vpackuswb %xmm1, %xmm0, %xmm0
0xc5, 0xf9, 0xfc, 0x05, 0x13, 0xf7, 0xff, 0xff, //0x00000905 vpaddb $-2285(%rip), %xmm0, %xmm0 /* LCPI0_4+0(%rip) */
0x89, 0xc8, //0x0000090d movl %ecx, %eax
0xc5, 0xfa, 0x7f, 0x44, 0x07, 0x01, //0x0000090f vmovdqu %xmm0, $1(%rdi,%rax)
0x83, 0xc9, 0x10, //0x00000915 orl $16, %ecx
0xff, 0xc1, //0x00000918 incl %ecx
0x89, 0xc8, //0x0000091a movl %ecx, %eax
0x5d, //0x0000091c popq %rbp
0xc3, //0x0000091d retq
0x00, 0x00, //0x0000091e .p2align 4, 0x00
//0x00000920 _Digits
0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, //0x00000920 QUAD $0x3330323031303030; QUAD $0x3730363035303430 // .ascii 16, '0001020304050607'
0x30, 0x38, 0x30, 0x39, 0x31, 0x30, 0x31, 0x31, 0x31, 0x32, 0x31, 0x33, 0x31, 0x34, 0x31, 0x35, //0x00000930 QUAD $0x3131303139303830; QUAD $0x3531343133313231 // .ascii 16, '0809101112131415'
0x31, 0x36, 0x31, 0x37, 0x31, 0x38, 0x31, 0x39, 0x32, 0x30, 0x32, 0x31, 0x32, 0x32, 0x32, 0x33, //0x00000940 QUAD $0x3931383137313631; QUAD $0x3332323231323032 // .ascii 16, '1617181920212223'
0x32, 0x34, 0x32, 0x35, 0x32, 0x36, 0x32, 0x37, 0x32, 0x38, 0x32, 0x39, 0x33, 0x30, 0x33, 0x31, //0x00000950 QUAD $0x3732363235323432; QUAD $0x3133303339323832 // .ascii 16, '2425262728293031'
0x33, 0x32, 0x33, 0x33, 0x33, 0x34, 0x33, 0x35, 0x33, 0x36, 0x33, 0x37, 0x33, 0x38, 0x33, 0x39, //0x00000960 QUAD $0x3533343333333233; QUAD $0x3933383337333633 // .ascii 16, '3233343536373839'
0x34, 0x30, 0x34, 0x31, 0x34, 0x32, 0x34, 0x33, 0x34, 0x34, 0x34, 0x35, 0x34, 0x36, 0x34, 0x37, //0x00000970 QUAD $0x3334323431343034; QUAD $0x3734363435343434 // .ascii 16, '4041424344454647'
0x34, 0x38, 0x34, 0x39, 0x35, 0x30, 0x35, 0x31, 0x35, 0x32, 0x35, 0x33, 0x35, 0x34, 0x35, 0x35, //0x00000980 QUAD $0x3135303539343834; QUAD $0x3535343533353235 // .ascii 16, '4849505152535455'
0x35, 0x36, 0x35, 0x37, 0x35, 0x38, 0x35, 0x39, 0x36, 0x30, 0x36, 0x31, 0x36, 0x32, 0x36, 0x33, //0x00000990 QUAD $0x3935383537353635; QUAD $0x3336323631363036 // .ascii 16, '5657585960616263'
0x36, 0x34, 0x36, 0x35, 0x36, 0x36, 0x36, 0x37, 0x36, 0x38, 0x36, 0x39, 0x37, 0x30, 0x37, 0x31, //0x000009a0 QUAD $0x3736363635363436; QUAD $0x3137303739363836 // .ascii 16, '6465666768697071'
0x37, 0x32, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35, 0x37, 0x36, 0x37, 0x37, 0x37, 0x38, 0x37, 0x39, //0x000009b0 QUAD $0x3537343733373237; QUAD $0x3937383737373637 // .ascii 16, '7273747576777879'
0x38, 0x30, 0x38, 0x31, 0x38, 0x32, 0x38, 0x33, 0x38, 0x34, 0x38, 0x35, 0x38, 0x36, 0x38, 0x37, //0x000009c0 QUAD $0x3338323831383038; QUAD $0x3738363835383438 // .ascii 16, '8081828384858687'
0x38, 0x38, 0x38, 0x39, 0x39, 0x30, 0x39, 0x31, 0x39, 0x32, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35, //0x000009d0 QUAD $0x3139303939383838; QUAD $0x3539343933393239 // .ascii 16, '8889909192939495'
0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39, //0x000009e0 QUAD $0x3939383937393639 // .ascii 8, '96979899'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0x000009e8 .p2align 4, 0x00
//0x000009f0 _VecShiftShuffles
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, //0x000009f0 QUAD $0x0706050403020100; QUAD $0x0f0e0d0c0b0a0908 // .ascii 16, '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, //0x00000a00 QUAD $0x0807060504030201; QUAD $0xff0f0e0d0c0b0a09 // .ascii 16, '\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\xff'
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, //0x00000a10 QUAD $0x0908070605040302; QUAD $0xffff0f0e0d0c0b0a // .ascii 16, '\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\xff\xff'
0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, //0x00000a20 QUAD $0x0a09080706050403; QUAD $0xffffff0f0e0d0c0b // .ascii 16, '\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\xff\xff\xff'
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, //0x00000a30 QUAD $0x0b0a090807060504; QUAD $0xffffffff0f0e0d0c // .ascii 16, '\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\xff\xff\xff\xff'
0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, //0x00000a40 QUAD $0x0c0b0a0908070605; QUAD $0xffffffffff0f0e0d // .ascii 16, '\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\xff\xff\xff\xff\xff'
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //0x00000a50 QUAD $0x0d0c0b0a09080706; QUAD $0xffffffffffff0f0e // .ascii 16, '\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\xff\xff\xff\xff\xff\xff'
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //0x00000a60 QUAD $0x0e0d0c0b0a090807; QUAD $0xffffffffffffff0f // .ascii 16, '\x07\x08\t\n\x0b\x0c\r\x0e\x0f\xff\xff\xff\xff\xff\xff\xff'
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //0x00000a70 QUAD $0x0f0e0d0c0b0a0908; QUAD $0xffffffffffffffff // .ascii 16, '\x08\t\n\x0b\x0c\r\x0e\x0f\xff\xff\xff\xff\xff\xff\xff\xff'
}

View file

@ -1,36 +0,0 @@
// Code generated by Makefile, DO NOT EDIT.
// Code generated by Makefile, DO NOT EDIT.
/*
* 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 avx
import (
`unsafe`
`github.com/bytedance/sonic/internal/rt`
)
var F_lspace func(sp unsafe.Pointer, nb int, off int) (ret int)
var S_lspace uintptr
//go:nosplit
func lspace(sp *byte, nb int, off int) (ret int) {
return F_lspace(rt.NoEscape(unsafe.Pointer(sp)), nb, off)
}

View file

@ -1,37 +0,0 @@
// +build !noasm !appengine
// Code generated by asm2asm, DO NOT EDIT.
package avx
import (
`github.com/bytedance/sonic/loader`
)
const (
_entry__lspace = 0
)
const (
_stack__lspace = 8
)
const (
_size__lspace = 113
)
var (
_pcsp__lspace = [][2]uint32{
{1, 0},
{89, 8},
{90, 0},
{103, 8},
{104, 0},
{111, 8},
{112, 0},
}
)
var _cfunc_lspace = []loader.CFunc{
{"_lspace_entry", 0, _entry__lspace, 0, nil},
{"_lspace", _entry__lspace, _size__lspace, _stack__lspace, _pcsp__lspace},
}

View file

@ -1,44 +0,0 @@
// +build amd64
// Code generated by asm2asm, DO NOT EDIT.
package avx
var _text_lspace = []byte{
// .p2align 4, 0x90
// _lspace
0x55, // pushq %rbp
0x48, 0x89, 0xe5, //0x00000001 movq %rsp, %rbp
0x48, 0x39, 0xd6, //0x00000004 cmpq %rdx, %rsi
0x0f, 0x84, 0x4e, 0x00, 0x00, 0x00, //0x00000007 je LBB0_1
0x4c, 0x8d, 0x04, 0x37, //0x0000000d leaq (%rdi,%rsi), %r8
0x48, 0x8d, 0x44, 0x3a, 0x01, //0x00000011 leaq $1(%rdx,%rdi), %rax
0x48, 0x29, 0xf2, //0x00000016 subq %rsi, %rdx
0x48, 0xbe, 0x00, 0x26, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, //0x00000019 movabsq $4294977024, %rsi
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, //0x00000023 .p2align 4, 0x90
//0x00000030 LBB0_3
0x0f, 0xbe, 0x48, 0xff, //0x00000030 movsbl $-1(%rax), %ecx
0x83, 0xf9, 0x20, //0x00000034 cmpl $32, %ecx
0x0f, 0x87, 0x2c, 0x00, 0x00, 0x00, //0x00000037 ja LBB0_5
0x48, 0x0f, 0xa3, 0xce, //0x0000003d btq %rcx, %rsi
0x0f, 0x83, 0x22, 0x00, 0x00, 0x00, //0x00000041 jae LBB0_5
0x48, 0xff, 0xc0, //0x00000047 incq %rax
0x48, 0xff, 0xc2, //0x0000004a incq %rdx
0x0f, 0x85, 0xdd, 0xff, 0xff, 0xff, //0x0000004d jne LBB0_3
0x49, 0x29, 0xf8, //0x00000053 subq %rdi, %r8
0x4c, 0x89, 0xc0, //0x00000056 movq %r8, %rax
0x5d, //0x00000059 popq %rbp
0xc3, //0x0000005a retq
//0x0000005b LBB0_1
0x48, 0x01, 0xfa, //0x0000005b addq %rdi, %rdx
0x49, 0x89, 0xd0, //0x0000005e movq %rdx, %r8
0x49, 0x29, 0xf8, //0x00000061 subq %rdi, %r8
0x4c, 0x89, 0xc0, //0x00000064 movq %r8, %rax
0x5d, //0x00000067 popq %rbp
0xc3, //0x00000068 retq
//0x00000069 LBB0_5
0x48, 0xf7, 0xd7, //0x00000069 notq %rdi
0x48, 0x01, 0xf8, //0x0000006c addq %rdi, %rax
0x5d, //0x0000006f popq %rbp
0xc3, //0x00000070 retq
}

View file

@ -1,47 +0,0 @@
/*
* 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 avx
import (
`github.com/bytedance/sonic/loader`
)
func Use() {
loader.WrapGoC(_text_f64toa, _cfunc_f64toa, []loader.GoC{{"_f64toa", &S_f64toa, &F_f64toa}}, "avx", "avx/f64toa.c")
loader.WrapGoC(_text_f32toa, _cfunc_f32toa, []loader.GoC{{"_f32toa", &S_f32toa, &F_f32toa}}, "avx", "avx/f32toa.c")
loader.WrapGoC(_text_get_by_path, _cfunc_get_by_path, []loader.GoC{{"_get_by_path", &S_get_by_path, &F_get_by_path}}, "avx", "avx/get_by_path.c")
loader.WrapGoC(_text_html_escape, _cfunc_html_escape, []loader.GoC{{"_html_escape", &S_html_escape, &F_html_escape}}, "avx", "avx/html_escape.c")
loader.WrapGoC(_text_i64toa, _cfunc_i64toa, []loader.GoC{{"_i64toa", &S_i64toa, &F_i64toa}}, "avx", "avx/i64toa.c")
loader.WrapGoC(_text_lspace, _cfunc_lspace, []loader.GoC{{"_lspace", &S_lspace, &F_lspace}}, "avx", "avx/lspace.c")
loader.WrapGoC(_text_quote, _cfunc_quote, []loader.GoC{{"_quote", &S_quote, &F_quote}}, "avx", "avx/quote.c")
loader.WrapGoC(_text_skip_array, _cfunc_skip_array, []loader.GoC{{"_skip_array", &S_skip_array, &F_skip_array}}, "avx", "avx/skip_array.c")
loader.WrapGoC(_text_skip_number, _cfunc_skip_number, []loader.GoC{{"_skip_number", &S_skip_number, &F_skip_number}}, "avx", "avx/skip_number.c")
loader.WrapGoC(_text_skip_one, _cfunc_skip_one, []loader.GoC{{"_skip_one", &S_skip_one, &F_skip_one}}, "avx", "avx/skip_one.c")
loader.WrapGoC(_text_skip_object, _cfunc_skip_object, []loader.GoC{{"_skip_object", &S_skip_object, &F_skip_object}}, "avx", "avx/skip_object.c")
loader.WrapGoC(_text_skip_one_fast, _cfunc_skip_one_fast, []loader.GoC{{"_skip_one_fast", &S_skip_one_fast, &F_skip_one_fast}}, "avx", "avx/skip_one_fast.c")
loader.WrapGoC(_text_u64toa, _cfunc_u64toa, []loader.GoC{{"_u64toa", &S_u64toa, &F_u64toa}}, "avx", "avx/u64toa.c")
loader.WrapGoC(_text_unquote, _cfunc_unquote, []loader.GoC{{"_unquote", &S_unquote, &F_unquote}}, "avx", "avx/unquote.c")
loader.WrapGoC(_text_validate_one, _cfunc_validate_one, []loader.GoC{{"_validate_one", &S_validate_one, &F_validate_one}}, "avx", "avx/validate_one.c")
loader.WrapGoC(_text_validate_utf8, _cfunc_validate_utf8, []loader.GoC{{"_validate_utf8", &S_validate_utf8, &F_validate_utf8}}, "avx", "avx/validate_utf8.c")
loader.WrapGoC(_text_validate_utf8_fast, _cfunc_validate_utf8_fast, []loader.GoC{{"_validate_utf8_fast", &S_validate_utf8_fast, &F_validate_utf8_fast}}, "avx", "avx/validate_utf8_fast.c")
loader.WrapGoC(_text_vnumber, _cfunc_vnumber, []loader.GoC{{"_vnumber", &S_vnumber, &F_vnumber}}, "avx", "avx/vnumber.c")
loader.WrapGoC(_text_vsigned, _cfunc_vsigned, []loader.GoC{{"_vsigned", &S_vsigned, &F_vsigned}}, "avx", "avx/vsigned.c")
loader.WrapGoC(_text_vunsigned, _cfunc_vunsigned, []loader.GoC{{"_vunsigned", &S_vunsigned, &F_vunsigned}}, "avx", "avx/vunsigned.c")
loader.WrapGoC(_text_vstring, _cfunc_vstring, []loader.GoC{{"_vstring", &S_vstring, &F_vstring}}, "avx", "avx/vstring.c")
loader.WrapGoC(_text_value, _cfunc_value, []loader.GoC{{"_value", &S_value, &F_value}}, "avx", "avx/value.c")
}

View file

@ -1,35 +0,0 @@
// Code generated by Makefile, DO NOT EDIT.
// Code generated by Makefile, DO NOT EDIT.
/*
* 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 avx
import (
`unsafe`
`github.com/bytedance/sonic/internal/rt`
)
var F_quote func(sp unsafe.Pointer, nb int, dp unsafe.Pointer, dn unsafe.Pointer, flags uint64) (ret int)
var S_quote uintptr
//go:nosplit
func quote(sp unsafe.Pointer, nb int, dp unsafe.Pointer, dn *int, flags uint64) (ret int) {
return F_quote(rt.NoEscape(sp), nb, rt.NoEscape(dp), rt.NoEscape(unsafe.Pointer(dn)), flags)
}

Some files were not shown because too many files have changed in this diff Show more