123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- /*
- * 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 (
- `sync`
- `unsafe`
- `github.com/bytedance/sonic/internal/caching`
- `github.com/bytedance/sonic/internal/native/types`
- `github.com/bytedance/sonic/internal/rt`
- )
- const (
- _MinSlice = 2
- _MaxStack = 4096 // 4k slots
- _MaxStackBytes = _MaxStack * _PtrBytes
- _MaxDigitNums = types.MaxDigitNums // used in atof fallback algorithm
- )
- const (
- _PtrBytes = _PTR_SIZE / 8
- _FsmOffset = (_MaxStack + 1) * _PtrBytes
- _DbufOffset = _FsmOffset + int64(unsafe.Sizeof(types.StateMachine{})) + types.MAX_RECURSE * _PtrBytes
- _StackSize = unsafe.Sizeof(_Stack{})
- )
- var (
- stackPool = sync.Pool{}
- valueCache = []unsafe.Pointer(nil)
- fieldCache = []*caching.FieldMap(nil)
- fieldCacheMux = sync.Mutex{}
- programCache = caching.CreateProgramCache()
- )
- type _Stack struct {
- sp uintptr
- sb [_MaxStack]unsafe.Pointer
- mm types.StateMachine
- vp [types.MAX_RECURSE]unsafe.Pointer
- dp [_MaxDigitNums]byte
- }
- type _Decoder func(
- s string,
- i int,
- vp unsafe.Pointer,
- sb *_Stack,
- fv uint64,
- sv string, // DO NOT pass value to this arguement, since it is only used for local _VAR_sv
- vk unsafe.Pointer, // DO NOT pass value to this arguement, since it is only used for local _VAR_vk
- ) (int, error)
- var _KeepAlive struct {
- s string
- i int
- vp unsafe.Pointer
- sb *_Stack
- fv uint64
- sv string
- vk unsafe.Pointer
- ret int
- err error
- frame_decoder [_FP_offs]byte
- frame_generic [_VD_offs]byte
- }
- var (
- argPtrs = []bool{true, false, false, true, true, false, true, false, true}
- localPtrs = []bool{}
- )
- var (
- argPtrs_generic = []bool{true}
- localPtrs_generic = []bool{}
- )
- 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 freeStack(p *_Stack) {
- p.sp = 0
- stackPool.Put(p)
- }
- func freezeValue(v unsafe.Pointer) uintptr {
- valueCache = append(valueCache, v)
- return uintptr(v)
- }
- func freezeFields(v *caching.FieldMap) int64 {
- fieldCacheMux.Lock()
- fieldCache = append(fieldCache, v)
- fieldCacheMux.Unlock()
- return referenceFields(v)
- }
- func referenceFields(v *caching.FieldMap) int64 {
- return int64(uintptr(unsafe.Pointer(v)))
- }
- func makeDecoder(vt *rt.GoType, _ ...interface{}) (interface{}, error) {
- if pp, err := newCompiler().compile(vt.Pack()); err != nil {
- return nil, err
- } else {
- return newAssembler(pp).Load(), nil
- }
- }
- func findOrCompile(vt *rt.GoType) (_Decoder, error) {
- if val := programCache.Get(vt); val != nil {
- return val.(_Decoder), nil
- } else if ret, err := programCache.Compute(vt, makeDecoder); err == nil {
- return ret.(_Decoder), nil
- } else {
- return nil, err
- }
- }
|