podman

Форк
0
733 строки · 37.8 Кб
1
// +build go1.16,!go1.17
2

3
/*
4
 * Copyright 2021 ByteDance Inc.
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18

19
package decoder
20

21
import (
22
    `encoding/json`
23
    `fmt`
24
    `reflect`
25

26
    `github.com/bytedance/sonic/internal/jit`
27
    `github.com/bytedance/sonic/internal/native`
28
    `github.com/bytedance/sonic/internal/native/types`
29
    `github.com/twitchyliquid64/golang-asm/obj`
30
)
31

32
/** Crucial Registers:
33
 *
34
 *      ST(BX)  : ro, decoder stack
35
 *      DF(R10) : ro, decoder flags
36
 *      EP(R11) : wo, error pointer
37
 *      IP(R12) : ro, input pointer
38
 *      IL(R13) : ro, input length
39
 *      IC(R14) : rw, input cursor
40
 *      VP(R15) : ro, value pointer (to an interface{})
41
 */
42

43
const (
44
    _VD_args   = 8      // 8 bytes  for passing arguments to this functions
45
    _VD_fargs  = 64     // 64 bytes for passing arguments to other Go functions
46
    _VD_saves  = 40     // 40 bytes for saving the registers before CALL instructions
47
    _VD_locals = 88     // 88 bytes for local variables
48
)
49

50
const (
51
    _VD_offs = _VD_fargs + _VD_saves + _VD_locals
52
    _VD_size = _VD_offs + 8     // 8 bytes for the parent frame pointer
53
)
54

55
var (
56
    _VAR_ss = _VAR_ss_Vt
57
    _VAR_df = jit.Ptr(_SP, _VD_fargs + _VD_saves)
58
)
59

60
var (
61
    _VAR_ss_Vt = jit.Ptr(_SP, _VD_fargs + _VD_saves + 8)
62
    _VAR_ss_Dv = jit.Ptr(_SP, _VD_fargs + _VD_saves + 16)
63
    _VAR_ss_Iv = jit.Ptr(_SP, _VD_fargs + _VD_saves + 24)
64
    _VAR_ss_Ep = jit.Ptr(_SP, _VD_fargs + _VD_saves + 32)
65
    _VAR_ss_Db = jit.Ptr(_SP, _VD_fargs + _VD_saves + 40)
66
    _VAR_ss_Dc = jit.Ptr(_SP, _VD_fargs + _VD_saves + 48)
67
)
68

69
var (
70
    _VAR_cs_LR = jit.Ptr(_SP, _VD_fargs + _VD_saves + 56)
71
    _VAR_cs_p = jit.Ptr(_SP, _VD_fargs + _VD_saves + 64)
72
    _VAR_cs_n = jit.Ptr(_SP, _VD_fargs + _VD_saves + 72)
73
    _VAR_cs_d = jit.Ptr(_SP, _VD_fargs + _VD_saves + 80)
74
)
75

76
type _ValueDecoder struct {
77
    jit.BaseAssembler
78
}
79

80
func (self *_ValueDecoder) build() uintptr {
81
    self.Init(self.compile)
82
    return *(*uintptr)(self.Load("decode_value", _VD_size, _VD_args, argPtrs_generic, localPtrs_generic))
83
}
84

85
/** Function Calling Helpers **/
86

87
func (self *_ValueDecoder) save(r ...obj.Addr) {
88
    for i, v := range r {
89
        if i > _VD_saves / 8 - 1 {
90
            panic("too many registers to save")
91
        } else {
92
            self.Emit("MOVQ", v, jit.Ptr(_SP, _VD_fargs + int64(i) * 8))
93
        }
94
    }
95
}
96

97
func (self *_ValueDecoder) load(r ...obj.Addr) {
98
    for i, v := range r {
99
        if i > _VD_saves / 8 - 1 {
100
            panic("too many registers to load")
101
        } else {
102
            self.Emit("MOVQ", jit.Ptr(_SP, _VD_fargs + int64(i) * 8), v)
103
        }
104
    }
105
}
106

107
func (self *_ValueDecoder) call(fn obj.Addr) {
108
    self.Emit("MOVQ", fn, _AX)  // MOVQ ${fn}, AX
109
    self.Rjmp("CALL", _AX)      // CALL AX
110
}
111

112
func (self *_ValueDecoder) call_go(fn obj.Addr) {
113
    self.save(_REG_go...)   // SAVE $REG_go
114
    self.call(fn)           // CALL ${fn}
115
    self.load(_REG_go...)   // LOAD $REG_go
116
}
117

118
/** Decoder Assembler **/
119

120
const (
121
    _S_val = iota + 1
122
    _S_arr
123
    _S_arr_0
124
    _S_obj
125
    _S_obj_0
126
    _S_obj_delim
127
    _S_obj_sep
128
)
129

130
const (
131
    _S_omask_key = (1 << _S_obj_0) | (1 << _S_obj_sep)
132
    _S_omask_end = (1 << _S_obj_0) | (1 << _S_obj)
133
    _S_vmask = (1 << _S_val) | (1 << _S_arr_0)
134
)
135

136
const (
137
    _A_init_len = 1
138
    _A_init_cap = 16
139
)
140

141
const (
142
    _ST_Sp = 0
143
    _ST_Vt = _PtrBytes
144
    _ST_Vp = _PtrBytes * (types.MAX_RECURSE + 1)
145
)
146

147
var (
148
    _V_true  = jit.Imm(int64(pbool(true)))
149
    _V_false = jit.Imm(int64(pbool(false)))
150
    _F_value = jit.Imm(int64(native.S_value))
151
)
152

153
var (
154
    _V_max     = jit.Imm(int64(types.V_MAX))
155
    _E_eof     = jit.Imm(int64(types.ERR_EOF))
156
    _E_invalid = jit.Imm(int64(types.ERR_INVALID_CHAR))
157
    _E_recurse = jit.Imm(int64(types.ERR_RECURSE_EXCEED_MAX))
158
)
159

160
var (
161
    _F_convTslice    = jit.Func(convTslice)
162
    _F_convTstring   = jit.Func(convTstring)
163
    _F_invalid_vtype = jit.Func(invalid_vtype)
164
)
165

166
var (
167
    _T_map     = jit.Type(reflect.TypeOf((map[string]interface{})(nil)))
168
    _T_bool    = jit.Type(reflect.TypeOf(false))
169
    _T_int64   = jit.Type(reflect.TypeOf(int64(0)))
170
    _T_eface   = jit.Type(reflect.TypeOf((*interface{})(nil)).Elem())
171
    _T_slice   = jit.Type(reflect.TypeOf(([]interface{})(nil)))
172
    _T_string  = jit.Type(reflect.TypeOf(""))
173
    _T_number  = jit.Type(reflect.TypeOf(json.Number("")))
174
    _T_float64 = jit.Type(reflect.TypeOf(float64(0)))
175
)
176

177
var _R_tab = map[int]string {
178
    '[': "_decode_V_ARRAY",
179
    '{': "_decode_V_OBJECT",
180
    ':': "_decode_V_KEY_SEP",
181
    ',': "_decode_V_ELEM_SEP",
182
    ']': "_decode_V_ARRAY_END",
183
    '}': "_decode_V_OBJECT_END",
184
}
185

186
func (self *_ValueDecoder) compile() {
187
    self.Emit("SUBQ", jit.Imm(_VD_size), _SP)       // SUBQ $_VD_size, SP
188
    self.Emit("MOVQ", _BP, jit.Ptr(_SP, _VD_offs))  // MOVQ BP, _VD_offs(SP)
189
    self.Emit("LEAQ", jit.Ptr(_SP, _VD_offs), _BP)  // LEAQ _VD_offs(SP), BP
190

191
    /* initialize the state machine */
192
    self.Emit("XORL", _CX, _CX)                                 // XORL CX, CX
193
    self.Emit("MOVQ", _DF, _VAR_df)                             // MOVQ DF, df
194
    /* initialize digital buffer first */
195
    self.Emit("MOVQ", jit.Imm(_MaxDigitNums), _VAR_ss_Dc)       // MOVQ $_MaxDigitNums, ss.Dcap
196
    self.Emit("LEAQ", jit.Ptr(_ST, _DbufOffset), _AX)           // LEAQ _DbufOffset(ST), AX
197
    self.Emit("MOVQ", _AX, _VAR_ss_Db)                          // MOVQ AX, ss.Dbuf
198
    /* add ST offset */
199
    self.Emit("ADDQ", jit.Imm(_FsmOffset), _ST)                 // ADDQ _FsmOffset, _ST
200
    self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp))                // MOVQ CX, ST.Sp
201
    self.WriteRecNotAX(0, _VP, jit.Ptr(_ST, _ST_Vp), false)                // MOVQ VP, ST.Vp[0]
202
    self.Emit("MOVQ", jit.Imm(_S_val), jit.Ptr(_ST, _ST_Vt))    // MOVQ _S_val, ST.Vt[0]
203
    self.Sjmp("JMP" , "_next")                                  // JMP  _next
204

205
    /* set the value from previous round */
206
    self.Link("_set_value")                                 // _set_value:
207
    self.Emit("MOVL" , jit.Imm(_S_vmask), _DX)              // MOVL  _S_vmask, DX
208
    self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _CX)           // MOVQ  ST.Sp, CX
209
    self.Emit("MOVQ" , jit.Sib(_ST, _CX, 8, _ST_Vt), _AX)   // MOVQ  ST.Vt[CX], AX
210
    self.Emit("BTQ"  , _AX, _DX)                            // BTQ   AX, DX
211
    self.Sjmp("JNC"  , "_vtype_error")                      // JNC   _vtype_error
212
    self.Emit("XORL" , _SI, _SI)                            // XORL  SI, SI
213
    self.Emit("SUBQ" , jit.Imm(1), jit.Ptr(_ST, _ST_Sp))    // SUBQ  $1, ST.Sp
214
    self.Emit("XCHGQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI)   // XCHGQ ST.Vp[CX], SI
215
    self.Emit("MOVQ" , _R8, jit.Ptr(_SI, 0))                // MOVQ  R8, (SI)
216
    self.WriteRecNotAX(1, _R9, jit.Ptr(_SI, 8), false)           // MOVQ  R9, 8(SI)
217

218
    /* check for value stack */
219
    self.Link("_next")                              // _next:
220
    self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _AX)   // MOVQ  ST.Sp, AX
221
    self.Emit("TESTQ", _AX, _AX)                    // TESTQ AX, AX
222
    self.Sjmp("JS"   , "_return")                   // JS    _return
223

224
    /* fast path: test up to 4 characters manually */
225
    self.Emit("CMPQ"   , _IC, _IL)                      // CMPQ    IC, IL
226
    self.Sjmp("JAE"    , "_decode_V_EOF")               // JAE     _decode_V_EOF
227
    self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX)  // MOVBQZX (IP)(IC), AX
228
    self.Emit("MOVQ"   , jit.Imm(_BM_space), _DX)       // MOVQ    _BM_space, DX
229
    self.Emit("CMPQ"   , _AX, jit.Imm(' '))             // CMPQ    AX, $' '
230
    self.Sjmp("JA"     , "_decode_fast")                // JA      _decode_fast
231
    self.Emit("BTQ"    , _AX, _DX)                      // BTQ     _AX, _DX
232
    self.Sjmp("JNC"    , "_decode_fast")                // JNC     _decode_fast
233
    self.Emit("ADDQ"   , jit.Imm(1), _IC)               // ADDQ    $1, IC
234

235
    /* at least 1 to 3 spaces */
236
    for i := 0; i < 3; i++ {
237
        self.Emit("CMPQ"   , _IC, _IL)                      // CMPQ    IC, IL
238
        self.Sjmp("JAE"    , "_decode_V_EOF")               // JAE     _decode_V_EOF
239
        self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX)  // MOVBQZX (IP)(IC), AX
240
        self.Emit("CMPQ"   , _AX, jit.Imm(' '))             // CMPQ    AX, $' '
241
        self.Sjmp("JA"     , "_decode_fast")                // JA      _decode_fast
242
        self.Emit("BTQ"    , _AX, _DX)                      // BTQ     _AX, _DX
243
        self.Sjmp("JNC"    , "_decode_fast")                // JNC     _decode_fast
244
        self.Emit("ADDQ"   , jit.Imm(1), _IC)               // ADDQ    $1, IC
245
    }
246

247
    /* at least 4 spaces */
248
    self.Emit("CMPQ"   , _IC, _IL)                      // CMPQ    IC, IL
249
    self.Sjmp("JAE"    , "_decode_V_EOF")               // JAE     _decode_V_EOF
250
    self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX)  // MOVBQZX (IP)(IC), AX
251

252
    /* fast path: use lookup table to select decoder */
253
    self.Link("_decode_fast")                           // _decode_fast:
254
    self.Byte(0x48, 0x8d, 0x3d)                         // LEAQ    ?(PC), DI
255
    self.Sref("_decode_tab", 4)                         // ....    &_decode_tab
256
    self.Emit("MOVLQSX", jit.Sib(_DI, _AX, 4, 0), _AX)  // MOVLQSX (DI)(AX*4), AX
257
    self.Emit("TESTQ"  , _AX, _AX)                      // TESTQ   AX, AX
258
    self.Sjmp("JZ"     , "_decode_native")              // JZ      _decode_native
259
    self.Emit("ADDQ"   , jit.Imm(1), _IC)               // ADDQ    $1, IC
260
    self.Emit("ADDQ"   , _DI, _AX)                      // ADDQ    DI, AX
261
    self.Rjmp("JMP"    , _AX)                           // JMP     AX
262

263
    /* decode with native decoder */
264
    self.Link("_decode_native")         // _decode_native:
265
    self.Emit("MOVQ", _IP, _DI)         // MOVQ IP, DI
266
    self.Emit("MOVQ", _IL, _SI)         // MOVQ IL, SI
267
    self.Emit("MOVQ", _IC, _DX)         // MOVQ IC, DX
268
    self.Emit("LEAQ", _VAR_ss, _CX)     // LEAQ ss, CX
269
    self.Emit("MOVQ", _VAR_df, _R8)     // MOVQ $df, R8
270
    self.Emit("BTSQ", jit.Imm(_F_allow_control), _R8)  // ANDQ $1<<_F_allow_control, R8
271
    self.call(_F_value)                 // CALL value
272
    self.Emit("MOVQ", _AX, _IC)         // MOVQ AX, IC
273

274
    /* check for errors */
275
    self.Emit("MOVQ" , _VAR_ss_Vt, _AX)     // MOVQ  ss.Vt, AX
276
    self.Emit("TESTQ", _AX, _AX)            // TESTQ AX, AX
277
    self.Sjmp("JS"   , "_parsing_error")
278
    self.Sjmp("JZ"   , "_invalid_vtype")    // JZ    _invalid_vtype
279
    self.Emit("CMPQ" , _AX, _V_max)         // CMPQ  AX, _V_max
280
    self.Sjmp("JA"   , "_invalid_vtype")    // JA    _invalid_vtype
281

282
    /* jump table selector */
283
    self.Byte(0x48, 0x8d, 0x3d)                             // LEAQ    ?(PC), DI
284
    self.Sref("_switch_table", 4)                           // ....    &_switch_table
285
    self.Emit("MOVLQSX", jit.Sib(_DI, _AX, 4, -4), _AX)     // MOVLQSX -4(DI)(AX*4), AX
286
    self.Emit("ADDQ"   , _DI, _AX)                          // ADDQ    DI, AX
287
    self.Rjmp("JMP"    , _AX)                               // JMP     AX
288

289
    /** V_EOF **/
290
    self.Link("_decode_V_EOF")          // _decode_V_EOF:
291
    self.Emit("MOVL", _E_eof, _EP)      // MOVL _E_eof, EP
292
    self.Sjmp("JMP" , "_error")         // JMP  _error
293

294
    /** V_NULL **/
295
    self.Link("_decode_V_NULL")                 // _decode_V_NULL:
296
    self.Emit("XORL", _R8, _R8)                 // XORL R8, R8
297
    self.Emit("XORL", _R9, _R9)                 // XORL R9, R9
298
    self.Emit("LEAQ", jit.Ptr(_IC, -4), _DI)    // LEAQ -4(IC), DI
299
    self.Sjmp("JMP" , "_set_value")             // JMP  _set_value
300

301
    /** V_TRUE **/
302
    self.Link("_decode_V_TRUE")                 // _decode_V_TRUE:
303
    self.Emit("MOVQ", _T_bool, _R8)             // MOVQ _T_bool, R8
304
    // TODO: maybe modified by users?
305
    self.Emit("MOVQ", _V_true, _R9)             // MOVQ _V_true, R9 
306
    self.Emit("LEAQ", jit.Ptr(_IC, -4), _DI)    // LEAQ -4(IC), DI
307
    self.Sjmp("JMP" , "_set_value")             // JMP  _set_value
308

309
    /** V_FALSE **/
310
    self.Link("_decode_V_FALSE")                // _decode_V_FALSE:
311
    self.Emit("MOVQ", _T_bool, _R8)             // MOVQ _T_bool, R8
312
    self.Emit("MOVQ", _V_false, _R9)            // MOVQ _V_false, R9
313
    self.Emit("LEAQ", jit.Ptr(_IC, -5), _DI)    // LEAQ -5(IC), DI
314
    self.Sjmp("JMP" , "_set_value")             // JMP  _set_value
315

316
    /** V_ARRAY **/
317
    self.Link("_decode_V_ARRAY")                            // _decode_V_ARRAY
318
    self.Emit("MOVL", jit.Imm(_S_vmask), _DX)               // MOVL _S_vmask, DX
319
    self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX)            // MOVQ ST.Sp, CX
320
    self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX)    // MOVQ ST.Vt[CX], AX
321
    self.Emit("BTQ" , _AX, _DX)                             // BTQ  AX, DX
322
    self.Sjmp("JNC" , "_invalid_char")                      // JNC  _invalid_char
323

324
    /* create a new array */
325
    self.Emit("MOVQ", _T_eface, _AX)                            // MOVQ    _T_eface, AX
326
    self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0))                     // MOVQ    AX, (SP)
327
    self.Emit("MOVQ", jit.Imm(_A_init_len), jit.Ptr(_SP, 8))    // MOVQ    _A_init_len, 8(SP)
328
    self.Emit("MOVQ", jit.Imm(_A_init_cap), jit.Ptr(_SP, 16))   // MOVQ    _A_init_cap, 16(SP)
329
    self.call_go(_F_makeslice)                                  // CALL_GO runtime.makeslice
330
    self.Emit("MOVQ", jit.Ptr(_SP, 24), _DX)                    // MOVQ    24(SP), DX
331

332
    /* pack into an interface */
333
    self.Emit("MOVQ", _DX, jit.Ptr(_SP, 0))                     // MOVQ    DX, (SP)
334
    self.Emit("MOVQ", jit.Imm(_A_init_len), jit.Ptr(_SP, 8))    // MOVQ    _A_init_len, 8(SP)
335
    self.Emit("MOVQ", jit.Imm(_A_init_cap), jit.Ptr(_SP, 16))   // MOVQ    _A_init_cap, 16(SP)
336
    self.call_go(_F_convTslice)                                 // CALL_GO runtime.convTslice
337
    self.Emit("MOVQ", jit.Ptr(_SP, 24), _R8)                    // MOVQ    24(SP), R8
338

339
    /* replace current state with an array */
340
    self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX)                        // MOVQ ST.Sp, CX
341
    self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI)                // MOVQ ST.Vp[CX], SI
342
    self.Emit("MOVQ", jit.Imm(_S_arr), jit.Sib(_ST, _CX, 8, _ST_Vt))    // MOVQ _S_arr, ST.Vt[CX]
343
    self.Emit("MOVQ", _T_slice, _AX)                                    // MOVQ _T_slice, AX
344
    self.Emit("MOVQ", _AX, jit.Ptr(_SI, 0))                             // MOVQ AX, (SI)
345
    self.WriteRecNotAX(2, _R8, jit.Ptr(_SI, 8), false)                            // MOVQ R8, 8(SI)
346

347
    /* add a new slot for the first element */
348
    self.Emit("ADDQ", jit.Imm(1), _CX)                                  // ADDQ $1, CX
349
    self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE))                  // CMPQ CX, ${types.MAX_RECURSE}
350
    self.Sjmp("JAE"  , "_stack_overflow")                                // JA   _stack_overflow
351
    self.Emit("MOVQ", jit.Ptr(_R8, 0), _AX)                             // MOVQ (R8), AX
352
    self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp))                        // MOVQ CX, ST.Sp
353
    self.WritePtrAX(3, jit.Sib(_ST, _CX, 8, _ST_Vp), false)                // MOVQ AX, ST.Vp[CX]
354
    self.Emit("MOVQ", jit.Imm(_S_arr_0), jit.Sib(_ST, _CX, 8, _ST_Vt))  // MOVQ _S_arr_0, ST.Vt[CX]
355
    self.Sjmp("JMP" , "_next")                                          // JMP  _next
356

357
    /** V_OBJECT **/
358
    self.Link("_decode_V_OBJECT")                                       // _decode_V_OBJECT:
359
    self.Emit("MOVL", jit.Imm(_S_vmask), _DX)                           // MOVL    _S_vmask, DX
360
    self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX)                        // MOVQ    ST.Sp, CX
361
    self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX)                // MOVQ    ST.Vt[CX], AX
362
    self.Emit("BTQ" , _AX, _DX)                                         // BTQ     AX, DX
363
    self.Sjmp("JNC" , "_invalid_char")                                  // JNC     _invalid_char
364
    self.call_go(_F_makemap_small)                                      // CALL_GO runtime.makemap_small
365
    self.Emit("MOVQ", jit.Ptr(_SP, 0), _AX)                             // MOVQ    (SP), AX
366
    self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX)                        // MOVQ    ST.Sp, CX
367
    self.Emit("MOVQ", jit.Imm(_S_obj_0), jit.Sib(_ST, _CX, 8, _ST_Vt))    // MOVQ    _S_obj, ST.Vt[CX]
368
    self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI)                // MOVQ    ST.Vp[CX], SI
369
    self.Emit("MOVQ", _T_map, _DX)                                      // MOVQ    _T_map, DX
370
    self.Emit("MOVQ", _DX, jit.Ptr(_SI, 0))                             // MOVQ    DX, (SI)
371
    self.WritePtrAX(4, jit.Ptr(_SI, 8), false)                             // MOVQ    AX, 8(SI)
372
    self.Sjmp("JMP" , "_next")                                          // JMP     _next
373

374
    /** V_STRING **/
375
    self.Link("_decode_V_STRING")       // _decode_V_STRING:
376
    self.Emit("MOVQ", _VAR_ss_Iv, _CX)  // MOVQ ss.Iv, CX
377
    self.Emit("MOVQ", _IC, _AX)         // MOVQ IC, AX
378
    self.Emit("SUBQ", _CX, _AX)         // SUBQ CX, AX
379

380
    /* check for escapes */
381
    self.Emit("CMPQ", _VAR_ss_Ep, jit.Imm(-1))          // CMPQ ss.Ep, $-1
382
    self.Sjmp("JNE" , "_unquote")                       // JNE  _unquote
383
    self.Emit("SUBQ", jit.Imm(1), _AX)                  // SUBQ $1, AX
384
    self.Emit("LEAQ", jit.Sib(_IP, _CX, 1, 0), _R8)     // LEAQ (IP)(CX), R8
385
    self.Byte(0x48, 0x8d, 0x3d)                         // LEAQ (PC), DI
386
    self.Sref("_copy_string_end", 4)
387
    self.Emit("BTQ", jit.Imm(_F_copy_string), _VAR_df)
388
    self.Sjmp("JC", "copy_string")
389
    self.Link("_copy_string_end")                                 
390
    self.Emit("XORL", _DX, _DX)                             // XORL DX, DX
391
    /* strings with no escape sequences */
392
    self.Link("_noescape")                                  // _noescape:
393
    self.Emit("MOVL", jit.Imm(_S_omask_key), _DI)               // MOVL _S_omask, DI
394
    self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX)            // MOVQ ST.Sp, CX
395
    self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _SI)    // MOVQ ST.Vt[CX], SI
396
    self.Emit("BTQ" , _SI, _DI)                             // BTQ  SI, DI
397
    self.Sjmp("JC"  , "_object_key")                        // JC   _object_key
398

399
    /* check for pre-packed strings, avoid 1 allocation */
400
    self.Emit("TESTQ", _DX, _DX)                // TESTQ   DX, DX
401
    self.Sjmp("JNZ"  , "_packed_str")           // JNZ     _packed_str
402
    self.Emit("MOVQ" , _R8, jit.Ptr(_SP, 0))    // MOVQ    R8, (SP)
403
    self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 8))    // MOVQ    AX, 8(SP)
404
    self.call_go(_F_convTstring)                // CALL_GO runtime.convTstring
405
    self.Emit("MOVQ" , jit.Ptr(_SP, 16), _R9)   // MOVQ    16(SP), R9
406

407
    /* packed string already in R9 */
408
    self.Link("_packed_str")            // _packed_str:
409
    self.Emit("MOVQ", _T_string, _R8)   // MOVQ _T_string, R8
410
    self.Emit("MOVQ", _VAR_ss_Iv, _DI)  // MOVQ ss.Iv, DI
411
    self.Emit("SUBQ", jit.Imm(1), _DI)  // SUBQ $1, DI
412
    self.Sjmp("JMP" , "_set_value")     // JMP  _set_value
413

414
    /* the string is an object key, get the map */
415
    self.Link("_object_key")
416
    self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX)            // MOVQ ST.Sp, CX
417
    self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI)    // MOVQ ST.Vp[CX], SI
418
    self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI)                 // MOVQ 8(SI), SI
419

420
    /* add a new delimiter */
421
    self.Emit("ADDQ", jit.Imm(1), _CX)                                      // ADDQ $1, CX
422
    self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE))                      // CMPQ CX, ${types.MAX_RECURSE}
423
    self.Sjmp("JAE"  , "_stack_overflow")                                    // JA   _stack_overflow
424
    self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp))                            // MOVQ CX, ST.Sp
425
    self.Emit("MOVQ", jit.Imm(_S_obj_delim), jit.Sib(_ST, _CX, 8, _ST_Vt))  // MOVQ _S_obj_delim, ST.Vt[CX]
426

427
    /* add a new slot int the map */
428
    self.Emit("MOVQ", _T_map, _DX)                      // MOVQ    _T_map, DX
429
    self.Emit("MOVQ", _DX, jit.Ptr(_SP, 0))             // MOVQ    DX, (SP)
430
    self.Emit("MOVQ", _SI, jit.Ptr(_SP, 8))             // MOVQ    SI, 8(SP)
431
    self.Emit("MOVQ", _R8, jit.Ptr(_SP, 16))            // MOVQ    R9, 16(SP)
432
    self.Emit("MOVQ", _AX, jit.Ptr(_SP, 24))            // MOVQ    AX, 24(SP)
433
    self.call_go(_F_mapassign_faststr)                  // CALL_GO runtime.mapassign_faststr
434
    self.Emit("MOVQ", jit.Ptr(_SP, 32), _AX)            // MOVQ    32(SP), AX
435

436
    /* add to the pointer stack */
437
    self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX)                 // MOVQ ST.Sp, CX
438
    self.WritePtrAX(6, jit.Sib(_ST, _CX, 8, _ST_Vp), false)    // MOVQ AX, ST.Vp[CX]
439
    self.Sjmp("JMP" , "_next")                                   // JMP  _next
440

441
    /* allocate memory to store the string header and unquoted result */
442
    self.Link("_unquote")                               // _unquote:
443
    self.Emit("ADDQ", jit.Imm(15), _AX)                 // ADDQ    $15, AX
444
    self.Emit("MOVQ", _T_byte, _CX)                     // MOVQ    _T_byte, CX
445
    self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0))             // MOVQ    AX, (SP)
446
    self.Emit("MOVQ", _CX, jit.Ptr(_SP, 8))             // MOVQ    CX, 8(SP)
447
    self.Emit("MOVB", jit.Imm(0), jit.Ptr(_SP, 16))     // MOVB    $0, 16(SP)
448
    self.call_go(_F_mallocgc)                           // CALL_GO runtime.mallocgc
449
    self.Emit("MOVQ", jit.Ptr(_SP, 24), _R9)            // MOVQ    24(SP), R9
450

451
    /* prepare the unquoting parameters */
452
    self.Emit("MOVQ" , _VAR_ss_Iv, _CX)                         // MOVQ  ss.Iv, CX
453
    self.Emit("LEAQ" , jit.Sib(_IP, _CX, 1, 0), _DI)            // LEAQ  (IP)(CX), DI
454
    self.Emit("NEGQ" , _CX)                                     // NEGQ  CX
455
    self.Emit("LEAQ" , jit.Sib(_IC, _CX, 1, -1), _SI)           // LEAQ  -1(IC)(CX), SI
456
    self.Emit("LEAQ" , jit.Ptr(_R9, 16), _DX)                   // LEAQ  16(R8), DX
457
    self.Emit("LEAQ" , _VAR_ss_Ep, _CX)                         // LEAQ  ss.Ep, CX
458
    self.Emit("XORL" , _R8, _R8)                                // XORL  R8, R8
459
    self.Emit("BTQ"  , jit.Imm(_F_disable_urc), _VAR_df)        // BTQ   ${_F_disable_urc}, fv
460
    self.Emit("SETCC", _R8)                                     // SETCC R8
461
    self.Emit("SHLQ" , jit.Imm(types.B_UNICODE_REPLACE), _R8)   // SHLQ  ${types.B_UNICODE_REPLACE}, R8
462

463
    /* unquote the string, with R9 been preserved */
464
    self.save(_R9)                                      // SAVE R9
465
    self.call(_F_unquote)                               // CALL unquote
466
    self.load(_R9)                                      // LOAD R9
467

468
    /* check for errors */
469
    self.Emit("TESTQ", _AX, _AX)                // TESTQ AX, AX
470
    self.Sjmp("JS"   , "_unquote_error")        // JS    _unquote_error
471
    self.Emit("MOVL" , jit.Imm(1), _DX)         // MOVL  $1, DX
472
    self.Emit("LEAQ" , jit.Ptr(_R9, 16), _R8)   // ADDQ  $16, R8
473
    self.Emit("MOVQ" , _R8, jit.Ptr(_R9, 0))    // MOVQ  R8, (R9)
474
    self.Emit("MOVQ" , _AX, jit.Ptr(_R9, 8))    // MOVQ  AX, 8(R9)
475
    self.Sjmp("JMP"  , "_noescape")             // JMP   _noescape
476

477
    /** V_DOUBLE **/
478
    self.Link("_decode_V_DOUBLE")                           // _decode_V_DOUBLE:
479
    self.Emit("BTQ"  , jit.Imm(_F_use_number), _VAR_df)     // BTQ     _F_use_number, df
480
    self.Sjmp("JC"   , "_use_number")                       // JC      _use_number
481
    self.Emit("MOVSD", _VAR_ss_Dv, _X0)                     // MOVSD   ss.Dv, X0
482
    self.Sjmp("JMP"  , "_use_float64")                      // JMP     _use_float64
483

484
    /** V_INTEGER **/
485
    self.Link("_decode_V_INTEGER")                          // _decode_V_INTEGER:
486
    self.Emit("BTQ"     , jit.Imm(_F_use_number), _VAR_df)  // BTQ      _F_use_number, df
487
    self.Sjmp("JC"      , "_use_number")                    // JC       _use_number
488
    self.Emit("BTQ"     , jit.Imm(_F_use_int64), _VAR_df)   // BTQ      _F_use_int64, df
489
    self.Sjmp("JC"      , "_use_int64")                     // JC       _use_int64
490
    self.Emit("MOVQ"    , _VAR_ss_Iv, _AX)                  // MOVQ     ss.Iv, AX
491
    self.Emit("CVTSQ2SD", _AX, _X0)                         // CVTSQ2SD AX, X0
492

493
    /* represent numbers as `float64` */
494
    self.Link("_use_float64")                   // _use_float64:
495
    self.Emit("MOVSD", _X0, jit.Ptr(_SP, 0))    // MOVSD   X0, (SP)
496
    self.call_go(_F_convT64)                    // CALL_GO runtime.convT64
497
    self.Emit("MOVQ" , _T_float64, _R8)         // MOVQ    _T_float64, R8
498
    self.Emit("MOVQ" , jit.Ptr(_SP, 8), _R9)    // MOVQ    8(SP), R9
499
    self.Emit("MOVQ" , _VAR_ss_Ep, _DI)         // MOVQ    ss.Ep, DI
500
    self.Sjmp("JMP"  , "_set_value")            // JMP     _set_value
501

502
    /* represent numbers as `json.Number` */
503
    self.Link("_use_number")                            // _use_number
504
    self.Emit("MOVQ", _VAR_ss_Ep, _AX)                  // MOVQ    ss.Ep, AX
505
    self.Emit("LEAQ", jit.Sib(_IP, _AX, 1, 0), _SI)     // LEAQ    (IP)(AX), SI
506
    self.Emit("MOVQ", _IC, _CX)                         // MOVQ    IC, CX
507
    self.Emit("SUBQ", _AX, _CX)                         // SUBQ    AX, CX
508
    self.Emit("MOVQ", _SI, jit.Ptr(_SP, 0))             // MOVQ    SI, (SP)
509
    self.Emit("MOVQ", _CX, jit.Ptr(_SP, 8))             // MOVQ    CX, 8(SP)
510
    self.call_go(_F_convTstring)                        // CALL_GO runtime.convTstring
511
    self.Emit("MOVQ", _T_number, _R8)                   // MOVQ    _T_number, R8
512
    self.Emit("MOVQ", jit.Ptr(_SP, 16), _R9)            // MOVQ    16(SP), R9
513
    self.Emit("MOVQ", _VAR_ss_Ep, _DI)                  // MOVQ    ss.Ep, DI
514
    self.Sjmp("JMP" , "_set_value")                     // JMP     _set_value
515

516
    /* represent numbers as `int64` */
517
    self.Link("_use_int64")                     // _use_int64:
518
    self.Emit("MOVQ", _VAR_ss_Iv, _AX)          // MOVQ    ss.Iv, AX
519
    self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0))     // MOVQ    AX, (SP)
520
    self.call_go(_F_convT64)                    // CALL_GO runtime.convT64
521
    self.Emit("MOVQ", _T_int64, _R8)            // MOVQ    _T_int64, R8
522
    self.Emit("MOVQ", jit.Ptr(_SP, 8), _R9)     // MOVQ    8(SP), R9
523
    self.Emit("MOVQ", _VAR_ss_Ep, _DI)          // MOVQ    ss.Ep, DI
524
    self.Sjmp("JMP" , "_set_value")             // JMP     _set_value
525

526
    /** V_KEY_SEP **/
527
    self.Link("_decode_V_KEY_SEP")                                          // _decode_V_KEY_SEP:
528
    // self.Byte(0xcc)
529
    self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX)                            // MOVQ ST.Sp, CX
530
    self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX)                    // MOVQ ST.Vt[CX], AX
531
    self.Emit("CMPQ", _AX, jit.Imm(_S_obj_delim))                           // CMPQ AX, _S_obj_delim
532
    self.Sjmp("JNE" , "_invalid_char")                                      // JNE  _invalid_char
533
    self.Emit("MOVQ", jit.Imm(_S_val), jit.Sib(_ST, _CX, 8, _ST_Vt))        // MOVQ _S_val, ST.Vt[CX]
534
    self.Emit("MOVQ", jit.Imm(_S_obj), jit.Sib(_ST, _CX, 8, _ST_Vt - 8))    // MOVQ _S_obj, ST.Vt[CX - 1]
535
    self.Sjmp("JMP" , "_next")                                              // JMP  _next
536

537
    /** V_ELEM_SEP **/
538
    self.Link("_decode_V_ELEM_SEP")                             // _decode_V_ELEM_SEP:
539
    self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _CX)            // MOVQ     ST.Sp, CX
540
    self.Emit("MOVQ" , jit.Sib(_ST, _CX, 8, _ST_Vt), _AX)    // MOVQ     ST.Vt[CX], AX
541
    self.Emit("CMPQ" , _AX, jit.Imm(_S_arr))                 // CMPQ     _AX, _S_arr
542
    self.Sjmp("JE"   , "_array_sep")                         // JZ       _next
543
    self.Emit("CMPQ" , _AX, jit.Imm(_S_obj))                 // CMPQ     _AX, _S_arr
544
    self.Sjmp("JNE"  , "_invalid_char")                      // JNE      _invalid_char
545
    self.Emit("MOVQ" , jit.Imm(_S_obj_sep), jit.Sib(_ST, _CX, 8, _ST_Vt))
546
    self.Sjmp("JMP"  , "_next")                              // JMP      _next
547

548
    /* arrays */
549
    self.Link("_array_sep")
550
    self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI)    // MOVQ ST.Vp[CX], SI
551
    self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI)                 // MOVQ 8(SI), SI
552
    self.Emit("MOVQ", jit.Ptr(_SI, 8), _DX)                 // MOVQ 8(SI), DX
553
    self.Emit("CMPQ", _DX, jit.Ptr(_SI, 16))                // CMPQ DX, 16(SI)
554
    self.Sjmp("JAE" , "_array_more")                        // JAE  _array_more
555

556
    /* add a slot for the new element */
557
    self.Link("_array_append")                                          // _array_append:
558
    self.Emit("ADDQ", jit.Imm(1), jit.Ptr(_SI, 8))                      // ADDQ $1, 8(SI)
559
    self.Emit("MOVQ", jit.Ptr(_SI, 0), _SI)                             // MOVQ (SI), SI
560
    self.Emit("ADDQ", jit.Imm(1), _CX)                                  // ADDQ $1, CX
561
    self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE))                  // CMPQ CX, ${types.MAX_RECURSE}
562
    self.Sjmp("JAE"  , "_stack_overflow") 
563
    self.Emit("SHLQ", jit.Imm(1), _DX)                                  // SHLQ $1, DX
564
    self.Emit("LEAQ", jit.Sib(_SI, _DX, 8, 0), _SI)                     // LEAQ (SI)(DX*8), SI
565
    self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp))                        // MOVQ CX, ST.Sp
566
    self.WriteRecNotAX(7 , _SI, jit.Sib(_ST, _CX, 8, _ST_Vp), false)           // MOVQ SI, ST.Vp[CX]
567
    self.Emit("MOVQ", jit.Imm(_S_val), jit.Sib(_ST, _CX, 8, _ST_Vt))    // MOVQ _S_val, ST.Vt[CX}
568
    self.Sjmp("JMP" , "_next")                                          // JMP  _next
569

570
    /** V_ARRAY_END **/
571
    self.Link("_decode_V_ARRAY_END")                        // _decode_V_ARRAY_END:
572
    self.Emit("XORL", _DX, _DX)                             // XORL DX, DX
573
    self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX)            // MOVQ ST.Sp, CX
574
    self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX)    // MOVQ ST.Vt[CX], AX
575
    self.Emit("CMPQ", _AX, jit.Imm(_S_arr_0))               // CMPQ AX, _S_arr_0
576
    self.Sjmp("JE"  , "_first_item")                        // JE   _first_item
577
    self.Emit("CMPQ", _AX, jit.Imm(_S_arr))                 // CMPQ AX, _S_arr
578
    self.Sjmp("JNE" , "_invalid_char")                      // JNE  _invalid_char
579
    self.Emit("SUBQ", jit.Imm(1), jit.Ptr(_ST, _ST_Sp))     // SUBQ $1, ST.Sp
580
    self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp))    // MOVQ DX, ST.Vp[CX]
581
    self.Sjmp("JMP" , "_next")                              // JMP  _next
582

583
    /* first element of an array */
584
    self.Link("_first_item")                                    // _first_item:
585
    self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX)                // MOVQ ST.Sp, CX
586
    self.Emit("SUBQ", jit.Imm(2), jit.Ptr(_ST, _ST_Sp))         // SUBQ $2, ST.Sp
587
    self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp - 8), _SI)    // MOVQ ST.Vp[CX - 1], SI
588
    self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI)                     // MOVQ 8(SI), SI
589
    self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp - 8))    // MOVQ DX, ST.Vp[CX - 1]
590
    self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp))        // MOVQ DX, ST.Vp[CX]
591
    self.Emit("MOVQ", _DX, jit.Ptr(_SI, 8))                     // MOVQ DX, 8(SI)
592
    self.Sjmp("JMP" , "_next")                                  // JMP  _next
593

594
    /** V_OBJECT_END **/
595
    self.Link("_decode_V_OBJECT_END")                       // _decode_V_OBJECT_END:
596
    self.Emit("MOVL", jit.Imm(_S_omask_end), _DX)           // MOVL _S_omask, DI
597
    self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX)            // MOVQ ST.Sp, CX
598
    self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX)    // MOVQ ST.Vt[CX], AX
599
    self.Emit("BTQ" , _AX, _DX)                
600
    self.Sjmp("JNC" , "_invalid_char")                      // JNE  _invalid_char
601
    self.Emit("XORL", _AX, _AX)                             // XORL AX, AX
602
    self.Emit("SUBQ", jit.Imm(1), jit.Ptr(_ST, _ST_Sp))     // SUBQ $1, ST.Sp
603
    self.Emit("MOVQ", _AX, jit.Sib(_ST, _CX, 8, _ST_Vp))    // MOVQ AX, ST.Vp[CX]
604
    self.Sjmp("JMP" , "_next")                              // JMP  _next
605

606
    /* return from decoder */
607
    self.Link("_return")                            // _return:
608
    self.Emit("XORL", _EP, _EP)                     // XORL EP, EP
609
    self.Emit("MOVQ", _EP, jit.Ptr(_ST, _ST_Vp))    // MOVQ EP, ST.Vp[0]
610
    self.Link("_epilogue")                          // _epilogue:
611
    self.Emit("SUBQ", jit.Imm(_FsmOffset), _ST)     // SUBQ _FsmOffset, _ST
612
    self.Emit("MOVQ", jit.Ptr(_SP, _VD_offs), _BP)  // MOVQ _VD_offs(SP), BP
613
    self.Emit("ADDQ", jit.Imm(_VD_size), _SP)       // ADDQ $_VD_size, SP
614
    self.Emit("RET")                                // RET
615

616
    /* array expand */
617
    self.Link("_array_more")                    // _array_more:
618
    self.Emit("MOVQ" , _T_eface, _AX)           // MOVQ    _T_eface, AX
619
    self.Emit("MOVOU", jit.Ptr(_SI, 0), _X0)    // MOVOU   (SI), X0
620
    self.Emit("MOVQ" , jit.Ptr(_SI, 16), _DX)   // MOVQ    16(SI), DX
621
    self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 0))    // MOVQ    AX, (SP)
622
    self.Emit("MOVOU", _X0, jit.Ptr(_SP, 8))    // MOVOU   X0, 8(SP)
623
    self.Emit("MOVQ" , _DX, jit.Ptr(_SP, 24))   // MOVQ    DX, 24(SP)
624
    self.Emit("SHLQ" , jit.Imm(1), _DX)         // SHLQ    $1, DX
625
    self.Emit("MOVQ" , _DX, jit.Ptr(_SP, 32))   // MOVQ    DX, 32(SP)
626
    self.call_go(_F_growslice)                  // CALL_GO runtime.growslice
627
    self.Emit("MOVQ" , jit.Ptr(_SP, 40), _DI)   // MOVOU   40(SP), DI
628
    self.Emit("MOVQ" , jit.Ptr(_SP, 48), _DX)   // MOVOU   48(SP), DX
629
    self.Emit("MOVQ" , jit.Ptr(_SP, 56), _AX)   // MOVQ    56(SP), AX
630

631
    /* update the slice */
632
    self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX)            // MOVQ ST.Sp, CX
633
    self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI)    // MOVQ ST.Vp[CX], SI
634
    self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI)                 // MOVQ 8(SI), SI
635
    self.Emit("MOVQ", _DX, jit.Ptr(_SI, 8))                 // MOVQ DX, 8(SI)
636
    self.Emit("MOVQ", _AX, jit.Ptr(_SI, 16))                // MOVQ AX, 16(AX)
637
    self.WriteRecNotAX(8 , _DI, jit.Ptr(_SI, 0), false)                 // MOVQ R10, (SI)
638
    self.Sjmp("JMP" , "_array_append")                      // JMP  _array_append
639

640
    /* copy string */
641
    self.Link("copy_string")  // pointer: R8, length: AX, return addr: DI
642
    // self.Byte(0xcc)
643
    self.Emit("MOVQ", _R8, _VAR_cs_p)
644
    self.Emit("MOVQ", _AX, _VAR_cs_n)
645
    self.Emit("MOVQ", _DI, _VAR_cs_LR)
646
    self.Emit("MOVQ", _T_byte, _R8)
647
    self.Emit("MOVQ", _R8, jit.Ptr(_SP, 0))
648
    self.Emit("MOVQ", _AX, jit.Ptr(_SP, 8))
649
    self.Emit("MOVQ", _AX, jit.Ptr(_SP, 16))
650
    self.call_go(_F_makeslice)                              
651
    self.Emit("MOVQ", jit.Ptr(_SP, 24), _R8)      
652
    self.Emit("MOVQ", _R8, _VAR_cs_d)                    
653
    self.Emit("MOVQ", _R8, jit.Ptr(_SP, 0))                    
654
    self.Emit("MOVQ", _VAR_cs_p, _R8)
655
    self.Emit("MOVQ", _R8, jit.Ptr(_SP, 8))
656
    self.Emit("MOVQ", _VAR_cs_n, _AX)
657
    self.Emit("MOVQ", _AX, jit.Ptr(_SP, 16))
658
    self.call_go(_F_memmove)
659
    self.Emit("MOVQ", _VAR_cs_d, _R8)
660
    self.Emit("MOVQ", _VAR_cs_n, _AX)
661
    self.Emit("MOVQ", _VAR_cs_LR, _DI)
662
    // self.Byte(0xcc)
663
    self.Rjmp("JMP", _DI)
664

665
    /* error handlers */
666
    self.Link("_stack_overflow")
667
    self.Emit("MOVL" , _E_recurse, _EP)         // MOVQ  _E_recurse, EP
668
    self.Sjmp("JMP"  , "_error")                // JMP   _error
669
    self.Link("_vtype_error")                   // _vtype_error:
670
    self.Emit("MOVQ" , _DI, _IC)                // MOVQ  DI, IC
671
    self.Emit("MOVL" , _E_invalid, _EP)         // MOVL  _E_invalid, EP
672
    self.Sjmp("JMP"  , "_error")                // JMP   _error
673
    self.Link("_invalid_char")                  // _invalid_char:
674
    self.Emit("SUBQ" , jit.Imm(1), _IC)         // SUBQ  $1, IC
675
    self.Emit("MOVL" , _E_invalid, _EP)         // MOVL  _E_invalid, EP
676
    self.Sjmp("JMP"  , "_error")                // JMP   _error
677
    self.Link("_unquote_error")                 // _unquote_error:
678
    self.Emit("MOVQ" , _VAR_ss_Iv, _IC)         // MOVQ  ss.Iv, IC
679
    self.Emit("SUBQ" , jit.Imm(1), _IC)         // SUBQ  $1, IC
680
    self.Link("_parsing_error")                 // _parsing_error:
681
    self.Emit("NEGQ" , _AX)                     // NEGQ  AX
682
    self.Emit("MOVQ" , _AX, _EP)                // MOVQ  AX, EP
683
    self.Link("_error")                         // _error:
684
    self.Emit("PXOR" , _X0, _X0)                // PXOR  X0, X0
685
    self.Emit("MOVOU", _X0, jit.Ptr(_VP, 0))    // MOVOU X0, (VP)
686
    self.Sjmp("JMP"  , "_epilogue")             // JMP   _epilogue
687

688
    /* invalid value type, never returns */
689
    self.Link("_invalid_vtype")
690
    self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0))     // MOVQ AX, (SP)
691
    self.call(_F_invalid_vtype)                 // CALL invalid_type
692
    self.Emit("UD2")                            // UD2
693

694
    /* switch jump table */
695
    self.Link("_switch_table")              // _switch_table:
696
    self.Sref("_decode_V_EOF", 0)           // SREF &_decode_V_EOF, $0
697
    self.Sref("_decode_V_NULL", -4)         // SREF &_decode_V_NULL, $-4
698
    self.Sref("_decode_V_TRUE", -8)         // SREF &_decode_V_TRUE, $-8
699
    self.Sref("_decode_V_FALSE", -12)       // SREF &_decode_V_FALSE, $-12
700
    self.Sref("_decode_V_ARRAY", -16)       // SREF &_decode_V_ARRAY, $-16
701
    self.Sref("_decode_V_OBJECT", -20)      // SREF &_decode_V_OBJECT, $-20
702
    self.Sref("_decode_V_STRING", -24)      // SREF &_decode_V_STRING, $-24
703
    self.Sref("_decode_V_DOUBLE", -28)      // SREF &_decode_V_DOUBLE, $-28
704
    self.Sref("_decode_V_INTEGER", -32)     // SREF &_decode_V_INTEGER, $-32
705
    self.Sref("_decode_V_KEY_SEP", -36)     // SREF &_decode_V_KEY_SEP, $-36
706
    self.Sref("_decode_V_ELEM_SEP", -40)    // SREF &_decode_V_ELEM_SEP, $-40
707
    self.Sref("_decode_V_ARRAY_END", -44)   // SREF &_decode_V_ARRAY_END, $-44
708
    self.Sref("_decode_V_OBJECT_END", -48)  // SREF &_decode_V_OBJECT_END, $-48
709

710
    /* fast character lookup table */
711
    self.Link("_decode_tab")        // _decode_tab:
712
    self.Sref("_decode_V_EOF", 0)   // SREF &_decode_V_EOF, $0
713

714
    /* generate rest of the tabs */
715
    for i := 1; i < 256; i++ {
716
        if to, ok := _R_tab[i]; ok {
717
            self.Sref(to, -int64(i) * 4)
718
        } else {
719
            self.Byte(0x00, 0x00, 0x00, 0x00)
720
        }
721
    }
722
}
723

724
/** Generic Decoder **/
725

726
var (
727
    _subr_decode_value = new(_ValueDecoder).build()
728
)
729

730
//go:nosplit
731
func invalid_vtype(vt types.ValueType) {
732
    throw(fmt.Sprintf("invalid value type: %d", vt))
733
}
734

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.