podman

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

17
package decoder
18

19
import (
20
    `encoding/json`
21
    `fmt`
22
    `reflect`
23
    `sort`
24
    `strconv`
25
    `strings`
26
    `unsafe`
27

28
    `github.com/bytedance/sonic/internal/caching`
29
    `github.com/bytedance/sonic/internal/resolver`
30
    `github.com/bytedance/sonic/internal/rt`
31
    `github.com/bytedance/sonic/option`
32
)
33

34
type _Op uint8
35

36
const (
37
    _OP_any _Op = iota + 1
38
    _OP_dyn
39
    _OP_str
40
    _OP_bin
41
    _OP_bool
42
    _OP_num
43
    _OP_i8
44
    _OP_i16
45
    _OP_i32
46
    _OP_i64
47
    _OP_u8
48
    _OP_u16
49
    _OP_u32
50
    _OP_u64
51
    _OP_f32
52
    _OP_f64
53
    _OP_unquote
54
    _OP_nil_1
55
    _OP_nil_2
56
    _OP_nil_3
57
    _OP_deref
58
    _OP_index
59
    _OP_is_null
60
    _OP_is_null_quote
61
    _OP_map_init
62
    _OP_map_key_i8
63
    _OP_map_key_i16
64
    _OP_map_key_i32
65
    _OP_map_key_i64
66
    _OP_map_key_u8
67
    _OP_map_key_u16
68
    _OP_map_key_u32
69
    _OP_map_key_u64
70
    _OP_map_key_f32
71
    _OP_map_key_f64
72
    _OP_map_key_str
73
    _OP_map_key_utext
74
    _OP_map_key_utext_p
75
    _OP_array_skip
76
    _OP_array_clear
77
    _OP_array_clear_p
78
    _OP_slice_init
79
    _OP_slice_append
80
    _OP_object_skip
81
    _OP_object_next
82
    _OP_struct_field
83
    _OP_unmarshal
84
    _OP_unmarshal_p
85
    _OP_unmarshal_text
86
    _OP_unmarshal_text_p
87
    _OP_lspace
88
    _OP_match_char
89
    _OP_check_char
90
    _OP_load
91
    _OP_save
92
    _OP_drop
93
    _OP_drop_2
94
    _OP_recurse
95
    _OP_goto
96
    _OP_switch
97
    _OP_check_char_0
98
    _OP_dismatch_err
99
    _OP_go_skip
100
    _OP_add
101
    _OP_check_empty
102
    _OP_debug
103
)
104

105
const (
106
    _INT_SIZE = 32 << (^uint(0) >> 63)
107
    _PTR_SIZE = 32 << (^uintptr(0) >> 63)
108
    _PTR_BYTE = unsafe.Sizeof(uintptr(0))
109
)
110

111
const (
112
    _MAX_ILBUF = 100000     // cutoff at 100k of IL instructions
113
    _MAX_FIELDS = 50        // cutoff at 50 fields struct
114
)
115

116
var _OpNames = [256]string {
117
    _OP_any              : "any",
118
    _OP_dyn              : "dyn",
119
    _OP_str              : "str",
120
    _OP_bin              : "bin",
121
    _OP_bool             : "bool",
122
    _OP_num              : "num",
123
    _OP_i8               : "i8",
124
    _OP_i16              : "i16",
125
    _OP_i32              : "i32",
126
    _OP_i64              : "i64",
127
    _OP_u8               : "u8",
128
    _OP_u16              : "u16",
129
    _OP_u32              : "u32",
130
    _OP_u64              : "u64",
131
    _OP_f32              : "f32",
132
    _OP_f64              : "f64",
133
    _OP_unquote          : "unquote",
134
    _OP_nil_1            : "nil_1",
135
    _OP_nil_2            : "nil_2",
136
    _OP_nil_3            : "nil_3",
137
    _OP_deref            : "deref",
138
    _OP_index            : "index",
139
    _OP_is_null          : "is_null",
140
    _OP_is_null_quote    : "is_null_quote",
141
    _OP_map_init         : "map_init",
142
    _OP_map_key_i8       : "map_key_i8",
143
    _OP_map_key_i16      : "map_key_i16",
144
    _OP_map_key_i32      : "map_key_i32",
145
    _OP_map_key_i64      : "map_key_i64",
146
    _OP_map_key_u8       : "map_key_u8",
147
    _OP_map_key_u16      : "map_key_u16",
148
    _OP_map_key_u32      : "map_key_u32",
149
    _OP_map_key_u64      : "map_key_u64",
150
    _OP_map_key_f32      : "map_key_f32",
151
    _OP_map_key_f64      : "map_key_f64",
152
    _OP_map_key_str      : "map_key_str",
153
    _OP_map_key_utext    : "map_key_utext",
154
    _OP_map_key_utext_p  : "map_key_utext_p",
155
    _OP_array_skip       : "array_skip",
156
    _OP_slice_init       : "slice_init",
157
    _OP_slice_append     : "slice_append",
158
    _OP_object_skip      : "object_skip",
159
    _OP_object_next      : "object_next",
160
    _OP_struct_field     : "struct_field",
161
    _OP_unmarshal        : "unmarshal",
162
    _OP_unmarshal_p      : "unmarshal_p",
163
    _OP_unmarshal_text   : "unmarshal_text",
164
    _OP_unmarshal_text_p : "unmarshal_text_p",
165
    _OP_lspace           : "lspace",
166
    _OP_match_char       : "match_char",
167
    _OP_check_char       : "check_char",
168
    _OP_load             : "load",
169
    _OP_save             : "save",
170
    _OP_drop             : "drop",
171
    _OP_drop_2           : "drop_2",
172
    _OP_recurse          : "recurse",
173
    _OP_goto             : "goto",
174
    _OP_switch           : "switch",
175
    _OP_check_char_0     : "check_char_0",
176
    _OP_dismatch_err     : "dismatch_err",
177
    _OP_add              : "add",
178
    _OP_go_skip          : "go_skip",
179
    _OP_check_empty      : "check_empty",
180
    _OP_debug            : "debug",
181
}
182

183
func (self _Op) String() string {
184
    if ret := _OpNames[self]; ret != "" {
185
        return ret
186
    } else {
187
        return "<invalid>"
188
    }
189
}
190

191
func _OP_int() _Op {
192
    switch _INT_SIZE {
193
        case 32: return _OP_i32
194
        case 64: return _OP_i64
195
        default: panic("unsupported int size")
196
    }
197
}
198

199
func _OP_uint() _Op {
200
    switch _INT_SIZE {
201
        case 32: return _OP_u32
202
        case 64: return _OP_u64
203
        default: panic("unsupported uint size")
204
    }
205
}
206

207
func _OP_uintptr() _Op {
208
    switch _PTR_SIZE {
209
        case 32: return _OP_u32
210
        case 64: return _OP_u64
211
        default: panic("unsupported pointer size")
212
    }
213
}
214

215
func _OP_map_key_int() _Op {
216
    switch _INT_SIZE {
217
        case 32: return _OP_map_key_i32
218
        case 64: return _OP_map_key_i64
219
        default: panic("unsupported int size")
220
    }
221
}
222

223
func _OP_map_key_uint() _Op {
224
    switch _INT_SIZE {
225
        case 32: return _OP_map_key_u32
226
        case 64: return _OP_map_key_u64
227
        default: panic("unsupported uint size")
228
    }
229
}
230

231
func _OP_map_key_uintptr() _Op {
232
    switch _PTR_SIZE {
233
        case 32: return _OP_map_key_u32
234
        case 64: return _OP_map_key_u64
235
        default: panic("unsupported pointer size")
236
    }
237
}
238

239
type _Instr struct {
240
    u uint64            // union {op: 8, vb: 8, vi: 48}, iv maybe int or len([]int)
241
    p unsafe.Pointer    // maybe GoSlice.Data, *GoType or *caching.FieldMap
242
}
243

244
func packOp(op _Op) uint64 {
245
    return uint64(op) << 56
246
}
247

248
func newInsOp(op _Op) _Instr {
249
    return _Instr{u: packOp(op)}
250
}
251

252
func newInsVi(op _Op, vi int) _Instr {
253
    return _Instr{u: packOp(op) | rt.PackInt(vi)}
254
}
255

256
func newInsVb(op _Op, vb byte) _Instr {
257
    return _Instr{u: packOp(op) | (uint64(vb) << 48)}
258
}
259

260
func newInsVs(op _Op, vs []int) _Instr {
261
    return _Instr {
262
        u: packOp(op) | rt.PackInt(len(vs)),
263
        p: (*rt.GoSlice)(unsafe.Pointer(&vs)).Ptr,
264
    }
265
}
266

267
func newInsVt(op _Op, vt reflect.Type) _Instr {
268
    return _Instr {
269
        u: packOp(op),
270
        p: unsafe.Pointer(rt.UnpackType(vt)),
271
    }
272
}
273

274
func newInsVf(op _Op, vf *caching.FieldMap) _Instr {
275
    return _Instr {
276
        u: packOp(op),
277
        p: unsafe.Pointer(vf),
278
    }
279
}
280

281
func (self _Instr) op() _Op {
282
    return _Op(self.u >> 56)
283
}
284

285
func (self _Instr) vi() int {
286
    return rt.UnpackInt(self.u)
287
}
288

289
func (self _Instr) vb() byte {
290
    return byte(self.u >> 48)
291
}
292

293
func (self _Instr) vs() (v []int) {
294
    (*rt.GoSlice)(unsafe.Pointer(&v)).Ptr = self.p
295
    (*rt.GoSlice)(unsafe.Pointer(&v)).Cap = self.vi()
296
    (*rt.GoSlice)(unsafe.Pointer(&v)).Len = self.vi()
297
    return
298
}
299

300
func (self _Instr) vf() *caching.FieldMap {
301
    return (*caching.FieldMap)(self.p)
302
}
303

304
func (self _Instr) vk() reflect.Kind {
305
    return (*rt.GoType)(self.p).Kind()
306
}
307

308
func (self _Instr) vt() reflect.Type {
309
    return (*rt.GoType)(self.p).Pack()
310
}
311

312
func (self _Instr) i64() int64 {
313
    return int64(self.vi())
314
}
315

316
func (self _Instr) vlen() int {
317
    return int((*rt.GoType)(self.p).Size)
318
}
319

320
func (self _Instr) isBranch() bool {
321
    switch self.op() {
322
        case _OP_goto          : fallthrough
323
        case _OP_switch        : fallthrough
324
        case _OP_is_null       : fallthrough
325
        case _OP_is_null_quote : fallthrough
326
        case _OP_check_char    : return true
327
        default                : return false
328
    }
329
}
330

331
func (self _Instr) disassemble() string {
332
    switch self.op() {
333
        case _OP_dyn              : fallthrough
334
        case _OP_deref            : fallthrough
335
        case _OP_map_key_i8       : fallthrough
336
        case _OP_map_key_i16      : fallthrough
337
        case _OP_map_key_i32      : fallthrough
338
        case _OP_map_key_i64      : fallthrough
339
        case _OP_map_key_u8       : fallthrough
340
        case _OP_map_key_u16      : fallthrough
341
        case _OP_map_key_u32      : fallthrough
342
        case _OP_map_key_u64      : fallthrough
343
        case _OP_map_key_f32      : fallthrough
344
        case _OP_map_key_f64      : fallthrough
345
        case _OP_map_key_str      : fallthrough
346
        case _OP_map_key_utext    : fallthrough
347
        case _OP_map_key_utext_p  : fallthrough
348
        case _OP_slice_init       : fallthrough
349
        case _OP_slice_append     : fallthrough
350
        case _OP_unmarshal        : fallthrough
351
        case _OP_unmarshal_p      : fallthrough
352
        case _OP_unmarshal_text   : fallthrough
353
        case _OP_unmarshal_text_p : fallthrough
354
        case _OP_recurse          : return fmt.Sprintf("%-18s%s", self.op(), self.vt())
355
        case _OP_goto             : fallthrough
356
        case _OP_is_null_quote    : fallthrough
357
        case _OP_is_null          : return fmt.Sprintf("%-18sL_%d", self.op(), self.vi())
358
        case _OP_index            : fallthrough
359
        case _OP_array_clear      : fallthrough
360
        case _OP_array_clear_p    : return fmt.Sprintf("%-18s%d", self.op(), self.vi())
361
        case _OP_switch           : return fmt.Sprintf("%-18s%s", self.op(), self.formatSwitchLabels())
362
        case _OP_struct_field     : return fmt.Sprintf("%-18s%s", self.op(), self.formatStructFields())
363
        case _OP_match_char       : return fmt.Sprintf("%-18s%s", self.op(), strconv.QuoteRune(rune(self.vb())))
364
        case _OP_check_char       : return fmt.Sprintf("%-18sL_%d, %s", self.op(), self.vi(), strconv.QuoteRune(rune(self.vb())))
365
        default                   : return self.op().String()
366
    }
367
}
368

369
func (self _Instr) formatSwitchLabels() string {
370
    var i int
371
    var v int
372
    var m []string
373

374
    /* format each label */
375
    for i, v = range self.vs() {
376
        m = append(m, fmt.Sprintf("%d=L_%d", i, v))
377
    }
378

379
    /* join them with "," */
380
    return strings.Join(m, ", ")
381
}
382

383
func (self _Instr) formatStructFields() string {
384
    var i uint64
385
    var r []string
386
    var m []struct{i int; n string}
387

388
    /* extract all the fields */
389
    for i = 0; i < self.vf().N; i++ {
390
        if v := self.vf().At(i); v.Hash != 0 {
391
            m = append(m, struct{i int; n string}{i: v.ID, n: v.Name})
392
        }
393
    }
394

395
    /* sort by field name */
396
    sort.Slice(m, func(i, j int) bool {
397
        return m[i].n < m[j].n
398
    })
399

400
    /* format each field */
401
    for _, v := range m {
402
        r = append(r, fmt.Sprintf("%s=%d", v.n, v.i))
403
    }
404

405
    /* join them with "," */
406
    return strings.Join(r, ", ")
407
}
408

409
type (
410
    _Program []_Instr
411
)
412

413
func (self _Program) pc() int {
414
    return len(self)
415
}
416

417
func (self _Program) tag(n int) {
418
    if n >= _MaxStack {
419
        panic("type nesting too deep")
420
    }
421
}
422

423
func (self _Program) pin(i int) {
424
    v := &self[i]
425
    v.u &= 0xffff000000000000
426
    v.u |= rt.PackInt(self.pc())
427
}
428

429
func (self _Program) rel(v []int) {
430
    for _, i := range v {
431
        self.pin(i)
432
    }
433
}
434

435
func (self *_Program) add(op _Op) {
436
    *self = append(*self, newInsOp(op))
437
}
438

439
func (self *_Program) int(op _Op, vi int) {
440
    *self = append(*self, newInsVi(op, vi))
441
}
442

443
func (self *_Program) chr(op _Op, vb byte) {
444
    *self = append(*self, newInsVb(op, vb))
445
}
446

447
func (self *_Program) tab(op _Op, vs []int) {
448
    *self = append(*self, newInsVs(op, vs))
449
}
450

451
func (self *_Program) rtt(op _Op, vt reflect.Type) {
452
    *self = append(*self, newInsVt(op, vt))
453
}
454

455
func (self *_Program) fmv(op _Op, vf *caching.FieldMap) {
456
    *self = append(*self, newInsVf(op, vf))
457
}
458

459
func (self _Program) disassemble() string {
460
    nb  := len(self)
461
    tab := make([]bool, nb + 1)
462
    ret := make([]string, 0, nb + 1)
463

464
    /* prescan to get all the labels */
465
    for _, ins := range self {
466
        if ins.isBranch() {
467
            if ins.op() != _OP_switch {
468
                tab[ins.vi()] = true
469
            } else {
470
                for _, v := range ins.vs() {
471
                    tab[v] = true
472
                }
473
            }
474
        }
475
    }
476

477
    /* disassemble each instruction */
478
    for i, ins := range self {
479
        if !tab[i] {
480
            ret = append(ret, "\t" + ins.disassemble())
481
        } else {
482
            ret = append(ret, fmt.Sprintf("L_%d:\n\t%s", i, ins.disassemble()))
483
        }
484
    }
485

486
    /* add the last label, if needed */
487
    if tab[nb] {
488
        ret = append(ret, fmt.Sprintf("L_%d:", nb))
489
    }
490

491
    /* add an "end" indicator, and join all the strings */
492
    return strings.Join(append(ret, "\tend"), "\n")
493
}
494

495
type _Compiler struct {
496
    opts option.CompileOptions
497
    tab  map[reflect.Type]bool
498
    rec  map[reflect.Type]bool
499
}
500

501
func newCompiler() *_Compiler {
502
    return &_Compiler {
503
        opts: option.DefaultCompileOptions(),
504
        tab: map[reflect.Type]bool{},
505
        rec: map[reflect.Type]bool{},
506
    }
507
}
508

509
func (self *_Compiler) apply(opts option.CompileOptions) *_Compiler {
510
    self.opts = opts
511
    return self
512
}
513

514
func (self *_Compiler) rescue(ep *error) {
515
    if val := recover(); val != nil {
516
        if err, ok := val.(error); ok {
517
            *ep = err
518
        } else {
519
            panic(val)
520
        }
521
    }
522
}
523

524
func (self *_Compiler) compile(vt reflect.Type) (ret _Program, err error) {
525
    defer self.rescue(&err)
526
    self.compileOne(&ret, 0, vt)
527
    return
528
}
529

530
func (self *_Compiler) checkMarshaler(p *_Program, vt reflect.Type) bool {
531
    pt := reflect.PtrTo(vt)
532

533
    /* check for `json.Unmarshaler` with pointer receiver */
534
    if pt.Implements(jsonUnmarshalerType) {
535
        p.rtt(_OP_unmarshal_p, pt)
536
        return true
537
    }
538

539
    /* check for `json.Unmarshaler` */
540
    if vt.Implements(jsonUnmarshalerType) {
541
        p.add(_OP_lspace)
542
        self.compileUnmarshalJson(p, vt)
543
        return true
544
    }
545

546
    /* check for `encoding.TextMarshaler` with pointer receiver */
547
    if pt.Implements(encodingTextUnmarshalerType) {
548
        p.add(_OP_lspace)
549
        self.compileUnmarshalTextPtr(p, pt)
550
        return true
551
    }
552

553
    /* check for `encoding.TextUnmarshaler` */
554
    if vt.Implements(encodingTextUnmarshalerType) {
555
        p.add(_OP_lspace)
556
        self.compileUnmarshalText(p, vt)
557
        return true
558
    }
559
    return false
560
}
561

562
func (self *_Compiler) compileOne(p *_Program, sp int, vt reflect.Type) {
563
    /* check for recursive nesting */
564
    ok := self.tab[vt]
565
    if ok {
566
        p.rtt(_OP_recurse, vt)
567
        return
568
    }
569

570
    if self.checkMarshaler(p, vt) {
571
        return
572
    }
573

574
    /* enter the recursion */
575
    p.add(_OP_lspace)
576
    self.tab[vt] = true
577
    self.compileOps(p, sp, vt)
578
    delete(self.tab, vt)
579
}
580

581
func (self *_Compiler) compileOps(p *_Program, sp int, vt reflect.Type) {
582
    switch vt.Kind() {
583
        case reflect.Bool      : self.compilePrimitive (vt, p, _OP_bool)
584
        case reflect.Int       : self.compilePrimitive (vt, p, _OP_int())
585
        case reflect.Int8      : self.compilePrimitive (vt, p, _OP_i8)
586
        case reflect.Int16     : self.compilePrimitive (vt, p, _OP_i16)
587
        case reflect.Int32     : self.compilePrimitive (vt, p, _OP_i32)
588
        case reflect.Int64     : self.compilePrimitive (vt, p, _OP_i64)
589
        case reflect.Uint      : self.compilePrimitive (vt, p, _OP_uint())
590
        case reflect.Uint8     : self.compilePrimitive (vt, p, _OP_u8)
591
        case reflect.Uint16    : self.compilePrimitive (vt, p, _OP_u16)
592
        case reflect.Uint32    : self.compilePrimitive (vt, p, _OP_u32)
593
        case reflect.Uint64    : self.compilePrimitive (vt, p, _OP_u64)
594
        case reflect.Uintptr   : self.compilePrimitive (vt, p, _OP_uintptr())
595
        case reflect.Float32   : self.compilePrimitive (vt, p, _OP_f32)
596
        case reflect.Float64   : self.compilePrimitive (vt, p, _OP_f64)
597
        case reflect.String    : self.compileString    (p, vt)
598
        case reflect.Array     : self.compileArray     (p, sp, vt)
599
        case reflect.Interface : self.compileInterface (p, vt)
600
        case reflect.Map       : self.compileMap       (p, sp, vt)
601
        case reflect.Ptr       : self.compilePtr       (p, sp, vt)
602
        case reflect.Slice     : self.compileSlice     (p, sp, vt)
603
        case reflect.Struct    : self.compileStruct    (p, sp, vt)
604
        default                : panic                 (&json.UnmarshalTypeError{Type: vt})
605
    }
606
}
607

608
func (self *_Compiler) compileMap(p *_Program, sp int, vt reflect.Type) {
609
    if reflect.PtrTo(vt.Key()).Implements(encodingTextUnmarshalerType) {
610
        self.compileMapOp(p, sp, vt, _OP_map_key_utext_p)
611
    } else if vt.Key().Implements(encodingTextUnmarshalerType) {
612
        self.compileMapOp(p, sp, vt, _OP_map_key_utext)
613
    } else {
614
        self.compileMapUt(p, sp, vt)
615
    }
616
}
617

618
func (self *_Compiler) compileMapUt(p *_Program, sp int, vt reflect.Type) {
619
    switch vt.Key().Kind() {
620
        case reflect.Int     : self.compileMapOp(p, sp, vt, _OP_map_key_int())
621
        case reflect.Int8    : self.compileMapOp(p, sp, vt, _OP_map_key_i8)
622
        case reflect.Int16   : self.compileMapOp(p, sp, vt, _OP_map_key_i16)
623
        case reflect.Int32   : self.compileMapOp(p, sp, vt, _OP_map_key_i32)
624
        case reflect.Int64   : self.compileMapOp(p, sp, vt, _OP_map_key_i64)
625
        case reflect.Uint    : self.compileMapOp(p, sp, vt, _OP_map_key_uint())
626
        case reflect.Uint8   : self.compileMapOp(p, sp, vt, _OP_map_key_u8)
627
        case reflect.Uint16  : self.compileMapOp(p, sp, vt, _OP_map_key_u16)
628
        case reflect.Uint32  : self.compileMapOp(p, sp, vt, _OP_map_key_u32)
629
        case reflect.Uint64  : self.compileMapOp(p, sp, vt, _OP_map_key_u64)
630
        case reflect.Uintptr : self.compileMapOp(p, sp, vt, _OP_map_key_uintptr())
631
        case reflect.Float32 : self.compileMapOp(p, sp, vt, _OP_map_key_f32)
632
        case reflect.Float64 : self.compileMapOp(p, sp, vt, _OP_map_key_f64)
633
        case reflect.String  : self.compileMapOp(p, sp, vt, _OP_map_key_str)
634
        default              : panic(&json.UnmarshalTypeError{Type: vt})
635
    }
636
}
637

638
func (self *_Compiler) compileMapOp(p *_Program, sp int, vt reflect.Type, op _Op) {
639
    i := p.pc()
640
    p.add(_OP_is_null)
641
    p.tag(sp + 1)
642
    skip := self.checkIfSkip(p, vt, '{')
643
    p.add(_OP_save)
644
    p.add(_OP_map_init)
645
    p.add(_OP_save)
646
    p.add(_OP_lspace)
647
    j := p.pc()
648
    p.chr(_OP_check_char, '}')
649
    p.chr(_OP_match_char, '"')
650
    skip2 := p.pc()
651
    p.rtt(op, vt)
652

653
    /* match the value separator */
654
    p.add(_OP_lspace)
655
    p.chr(_OP_match_char, ':')
656
    self.compileOne(p, sp + 2, vt.Elem())
657
    p.pin(skip2)
658
    p.add(_OP_load)
659
    k0 := p.pc()
660
    p.add(_OP_lspace)
661
    k1 := p.pc()
662
    p.chr(_OP_check_char, '}')
663
    p.chr(_OP_match_char, ',')
664
    p.add(_OP_lspace)
665
    p.chr(_OP_match_char, '"')
666
    skip3 := p.pc()
667
    p.rtt(op, vt)
668

669
    /* match the value separator */
670
    p.add(_OP_lspace)
671
    p.chr(_OP_match_char, ':')
672
    self.compileOne(p, sp + 2, vt.Elem())
673
    p.pin(skip3)
674
    p.add(_OP_load)
675
    p.int(_OP_goto, k0)
676
    p.pin(j)
677
    p.pin(k1)
678
    p.add(_OP_drop_2)
679
    x := p.pc()
680
    p.add(_OP_goto)
681
    p.pin(i)
682
    p.add(_OP_nil_1)
683
    p.pin(skip)
684
    p.pin(x)
685
}
686

687
func (self *_Compiler) compilePtr(p *_Program, sp int, et reflect.Type) {
688
    i := p.pc()
689
    p.add(_OP_is_null)
690

691
    /* dereference all the way down */
692
    for et.Kind() == reflect.Ptr {
693
        if self.checkMarshaler(p, et) {
694
            return
695
        }
696
        et = et.Elem()
697
        p.rtt(_OP_deref, et)
698
    }
699

700
    /* check for recursive nesting */
701
    ok := self.tab[et]
702
    if ok {
703
        p.rtt(_OP_recurse, et)
704
    } else {
705
        /* enter the recursion */
706
        p.add(_OP_lspace)
707
        self.tab[et] = true
708

709
        /* not inline the pointer type
710
        * recursing the defined pointer type's elem will casue issue379.
711
        */
712
        self.compileOps(p, sp, et)
713
    }
714
    delete(self.tab, et)
715

716
    j := p.pc()
717
    p.add(_OP_goto)
718

719
    // set val pointer as nil
720
    p.pin(i)
721
    p.add(_OP_nil_1)
722

723
    // nothing todo
724
    p.pin(j)
725
}
726

727
func (self *_Compiler) compileArray(p *_Program, sp int, vt reflect.Type) {
728
    x := p.pc()
729
    p.add(_OP_is_null)
730
    p.tag(sp)
731
    skip := self.checkIfSkip(p, vt, '[')
732
    
733
    p.add(_OP_save)
734
    p.add(_OP_lspace)
735
    v := []int{p.pc()}
736
    p.chr(_OP_check_char, ']')
737

738
    /* decode every item */
739
    for i := 1; i <= vt.Len(); i++ {
740
        self.compileOne(p, sp + 1, vt.Elem())
741
        p.add(_OP_load)
742
        p.int(_OP_index, i * int(vt.Elem().Size()))
743
        p.add(_OP_lspace)
744
        v = append(v, p.pc())
745
        p.chr(_OP_check_char, ']')
746
        p.chr(_OP_match_char, ',')
747
    }
748

749
    /* drop rest of the array */
750
    p.add(_OP_array_skip)
751
    w := p.pc()
752
    p.add(_OP_goto)
753
    p.rel(v)
754

755
    /* check for pointer data */
756
    if rt.UnpackType(vt.Elem()).PtrData == 0 {
757
        p.int(_OP_array_clear, int(vt.Size()))
758
    } else {
759
        p.int(_OP_array_clear_p, int(vt.Size()))
760
    }
761

762
    /* restore the stack */
763
    p.pin(w)
764
    p.add(_OP_drop)
765

766
    p.pin(skip)
767
    p.pin(x)
768
}
769

770
func (self *_Compiler) compileSlice(p *_Program, sp int, vt reflect.Type) {
771
    if vt.Elem().Kind() == byteType.Kind() {
772
        self.compileSliceBin(p, sp, vt)
773
    } else {
774
        self.compileSliceList(p, sp, vt)
775
    }
776
}
777

778
func (self *_Compiler) compileSliceBin(p *_Program, sp int, vt reflect.Type) {
779
    i := p.pc()
780
    p.add(_OP_is_null)
781
    j := p.pc()
782
    p.chr(_OP_check_char, '[')
783
    skip := self.checkIfSkip(p, vt, '"')
784
    k := p.pc()
785
    p.chr(_OP_check_char, '"')
786
    p.add(_OP_bin)
787
    x := p.pc()
788
    p.add(_OP_goto)
789
    p.pin(j)
790
    self.compileSliceBody(p, sp, vt.Elem())
791
    y := p.pc()
792
    p.add(_OP_goto)
793
    p.pin(i)
794
    p.pin(k)
795
    p.add(_OP_nil_3)
796
    p.pin(x)
797
    p.pin(skip)
798
    p.pin(y)
799
}
800

801
func (self *_Compiler) compileSliceList(p *_Program, sp int, vt reflect.Type) {
802
    i := p.pc()
803
    p.add(_OP_is_null)
804
    p.tag(sp)
805
    skip := self.checkIfSkip(p, vt, '[')
806
    self.compileSliceBody(p, sp, vt.Elem())
807
    x := p.pc()
808
    p.add(_OP_goto)
809
    p.pin(i)
810
    p.add(_OP_nil_3)
811
    p.pin(x)
812
    p.pin(skip)
813
}
814

815
func (self *_Compiler) compileSliceBody(p *_Program, sp int, et reflect.Type) {
816
    p.add(_OP_lspace)
817
    j := p.pc()
818
    p.chr(_OP_check_empty, ']')
819
    p.rtt(_OP_slice_init, et)
820
    p.add(_OP_save)
821
    p.rtt(_OP_slice_append, et)
822
    self.compileOne(p, sp + 1, et)
823
    p.add(_OP_load)
824
    k0 := p.pc()
825
    p.add(_OP_lspace)
826
    k1 := p.pc()
827
    p.chr(_OP_check_char, ']')
828
    p.chr(_OP_match_char, ',')
829
    p.rtt(_OP_slice_append, et)
830
    self.compileOne(p, sp + 1, et)
831
    p.add(_OP_load)
832
    p.int(_OP_goto, k0)
833
    p.pin(k1)
834
    p.add(_OP_drop)
835
    p.pin(j)
836
}
837

838
func (self *_Compiler) compileString(p *_Program, vt reflect.Type) {
839
    if vt == jsonNumberType {
840
        self.compilePrimitive(vt, p, _OP_num)
841
    } else {
842
        self.compileStringBody(vt, p)
843
    }
844
}
845

846
func (self *_Compiler) compileStringBody(vt reflect.Type, p *_Program) {
847
    i := p.pc()
848
    p.add(_OP_is_null)
849
    skip := self.checkIfSkip(p, vt, '"')
850
    p.add(_OP_str)
851
    p.pin(i)
852
    p.pin(skip)
853
}
854

855
func (self *_Compiler) compileStruct(p *_Program, sp int, vt reflect.Type) {
856
    if sp >= self.opts.MaxInlineDepth || p.pc() >= _MAX_ILBUF || (sp > 0 && vt.NumField() >= _MAX_FIELDS) {
857
        p.rtt(_OP_recurse, vt)
858
        if self.opts.RecursiveDepth > 0 {
859
            self.rec[vt] = true
860
        }
861
    } else {
862
        self.compileStructBody(p, sp, vt)
863
    }
864
}
865

866
func (self *_Compiler) compileStructBody(p *_Program, sp int, vt reflect.Type) {
867
    fv := resolver.ResolveStruct(vt)
868
    fm, sw := caching.CreateFieldMap(len(fv)), make([]int, len(fv))
869

870
    /* start of object */
871
    p.tag(sp)
872
    n := p.pc()
873
    p.add(_OP_is_null)
874

875
    skip := self.checkIfSkip(p, vt, '{')
876
    
877
    p.add(_OP_save)
878
    p.add(_OP_lspace)
879
    x := p.pc()
880
    p.chr(_OP_check_char, '}')
881
    p.chr(_OP_match_char, '"')
882
    p.fmv(_OP_struct_field, fm)
883
    p.add(_OP_lspace)
884
    p.chr(_OP_match_char, ':')
885
    p.tab(_OP_switch, sw)
886
    p.add(_OP_object_next)
887
    y0 := p.pc()
888
    p.add(_OP_lspace)
889
    y1 := p.pc()
890
    p.chr(_OP_check_char, '}')
891
    p.chr(_OP_match_char, ',')
892

893
    /* special case of an empty struct */
894
    if len(fv) == 0 {
895
        p.add(_OP_object_skip)
896
        goto end_of_object
897
    }
898

899
    /* match the remaining fields */
900
    p.add(_OP_lspace)
901
    p.chr(_OP_match_char, '"')
902
    p.fmv(_OP_struct_field, fm)
903
    p.add(_OP_lspace)
904
    p.chr(_OP_match_char, ':')
905
    p.tab(_OP_switch, sw)
906
    p.add(_OP_object_next)
907
    p.int(_OP_goto, y0)
908

909
    /* process each field */
910
    for i, f := range fv {
911
        sw[i] = p.pc()
912
        fm.Set(f.Name, i)
913

914
        /* index to the field */
915
        for _, o := range f.Path {
916
            if p.int(_OP_index, int(o.Size)); o.Kind == resolver.F_deref {
917
                p.rtt(_OP_deref, o.Type)
918
            }
919
        }
920

921
        /* check for "stringnize" option */
922
        if (f.Opts & resolver.F_stringize) == 0 {
923
            self.compileOne(p, sp + 1, f.Type)
924
        } else {
925
            self.compileStructFieldStr(p, sp + 1, f.Type)
926
        }
927

928
        /* load the state, and try next field */
929
        p.add(_OP_load)
930
        p.int(_OP_goto, y0)
931
    }
932

933
end_of_object:
934
    p.pin(x)
935
    p.pin(y1)
936
    p.add(_OP_drop)
937
    p.pin(n)
938
    p.pin(skip)
939
}
940

941
func (self *_Compiler) compileStructFieldStr(p *_Program, sp int, vt reflect.Type) {
942
    n1 := -1
943
    ft := vt
944
    sv := false
945

946
    /* dereference the pointer if needed */
947
    if ft.Kind() == reflect.Ptr {
948
        ft = ft.Elem()
949
    }
950

951
    /* check if it can be stringized */
952
    switch ft.Kind() {
953
        case reflect.Bool    : sv = true
954
        case reflect.Int     : sv = true
955
        case reflect.Int8    : sv = true
956
        case reflect.Int16   : sv = true
957
        case reflect.Int32   : sv = true
958
        case reflect.Int64   : sv = true
959
        case reflect.Uint    : sv = true
960
        case reflect.Uint8   : sv = true
961
        case reflect.Uint16  : sv = true
962
        case reflect.Uint32  : sv = true
963
        case reflect.Uint64  : sv = true
964
        case reflect.Uintptr : sv = true
965
        case reflect.Float32 : sv = true
966
        case reflect.Float64 : sv = true
967
        case reflect.String  : sv = true
968
    }
969

970
    /* if it's not, ignore the "string" and follow the regular path */
971
    if !sv {
972
        self.compileOne(p, sp, vt)
973
        return
974
    }
975

976
    /* remove the leading space, and match the leading quote */
977
    vk := vt.Kind()
978
    p.add(_OP_lspace)
979
    n0 := p.pc()
980
    p.add(_OP_is_null)
981
    
982
    skip := self.checkIfSkip(p, stringType, '"')
983

984
    /* also check for inner "null" */
985
    n1 = p.pc()
986
    p.add(_OP_is_null_quote)
987

988
    /* dereference the pointer only when it is not null */
989
    if vk == reflect.Ptr {
990
        vt = vt.Elem()
991
        p.rtt(_OP_deref, vt)
992
    }
993

994
    n2 := p.pc()
995
    p.chr(_OP_check_char_0, '"')
996

997
    /* string opcode selector */
998
    _OP_string := func() _Op {
999
        if ft == jsonNumberType {
1000
            return _OP_num
1001
        } else {
1002
            return _OP_unquote
1003
        }
1004
    }
1005

1006
    /* compile for each type */
1007
    switch vt.Kind() {
1008
        case reflect.Bool    : p.add(_OP_bool)
1009
        case reflect.Int     : p.add(_OP_int())
1010
        case reflect.Int8    : p.add(_OP_i8)
1011
        case reflect.Int16   : p.add(_OP_i16)
1012
        case reflect.Int32   : p.add(_OP_i32)
1013
        case reflect.Int64   : p.add(_OP_i64)
1014
        case reflect.Uint    : p.add(_OP_uint())
1015
        case reflect.Uint8   : p.add(_OP_u8)
1016
        case reflect.Uint16  : p.add(_OP_u16)
1017
        case reflect.Uint32  : p.add(_OP_u32)
1018
        case reflect.Uint64  : p.add(_OP_u64)
1019
        case reflect.Uintptr : p.add(_OP_uintptr())
1020
        case reflect.Float32 : p.add(_OP_f32)
1021
        case reflect.Float64 : p.add(_OP_f64)
1022
        case reflect.String  : p.add(_OP_string())
1023
        default              : panic("not reachable")
1024
    }
1025

1026
    /* the closing quote is not needed when parsing a pure string */
1027
    if vt == jsonNumberType || vt.Kind() != reflect.String {
1028
        p.chr(_OP_match_char, '"')
1029
    }
1030

1031
    /* pin the `is_null_quote` jump location */
1032
    if n1 != -1 && vk != reflect.Ptr {
1033
        p.pin(n1)
1034
    }
1035

1036
    /* "null" but not a pointer, act as if the field is not present */
1037
    if vk != reflect.Ptr {
1038
        pc2 := p.pc()
1039
        p.add(_OP_goto)
1040
        p.pin(n2)
1041
        p.rtt(_OP_dismatch_err, vt)
1042
        p.int(_OP_add, 1)
1043
        p.pin(pc2)
1044
        p.pin(n0)
1045
        return
1046
    }
1047

1048
    /* the "null" case of the pointer */
1049
    pc := p.pc()
1050
    p.add(_OP_goto)
1051
    p.pin(n0) // `is_null` jump location
1052
    p.pin(n1) // `is_null_quote` jump location
1053
    p.add(_OP_nil_1)
1054
    pc2 := p.pc()
1055
    p.add(_OP_goto)
1056
    p.pin(n2)
1057
    p.rtt(_OP_dismatch_err, vt)
1058
    p.int(_OP_add, 1)
1059
    p.pin(pc)
1060
    p.pin(pc2)
1061
    p.pin(skip)
1062
}
1063

1064
func (self *_Compiler) compileInterface(p *_Program, vt reflect.Type) {
1065
    i := p.pc()
1066
    p.add(_OP_is_null)
1067

1068
    /* check for empty interface */
1069
    if vt.NumMethod() == 0 {
1070
        p.add(_OP_any)
1071
    } else {
1072
        p.rtt(_OP_dyn, vt)
1073
    }
1074

1075
    /* finish the OpCode */
1076
    j := p.pc()
1077
    p.add(_OP_goto)
1078
    p.pin(i)
1079
    p.add(_OP_nil_2)
1080
    p.pin(j)
1081
}
1082

1083
func (self *_Compiler) compilePrimitive(vt reflect.Type, p *_Program, op _Op) {
1084
    i := p.pc()
1085
    p.add(_OP_is_null)
1086
    // skip := self.checkPrimitive(p, vt)
1087
    p.add(op)
1088
    p.pin(i)
1089
    // p.pin(skip)
1090
}
1091

1092
func (self *_Compiler) compileUnmarshalEnd(p *_Program, vt reflect.Type, i int) {
1093
    j := p.pc()
1094
    k := vt.Kind()
1095

1096
    /* not a pointer */
1097
    if k != reflect.Ptr {
1098
        p.pin(i)
1099
        return
1100
    }
1101

1102
    /* it seems that in Go JSON library, "null" takes priority over any kind of unmarshaler */
1103
    p.add(_OP_goto)
1104
    p.pin(i)
1105
    p.add(_OP_nil_1)
1106
    p.pin(j)
1107
}
1108

1109
func (self *_Compiler) compileUnmarshalJson(p *_Program, vt reflect.Type) {
1110
    i := p.pc()
1111
    v := _OP_unmarshal
1112
    p.add(_OP_is_null)
1113

1114
    /* check for dynamic interface */
1115
    if vt.Kind() == reflect.Interface {
1116
        v = _OP_dyn
1117
    }
1118

1119
    /* call the unmarshaler */
1120
    p.rtt(v, vt)
1121
    self.compileUnmarshalEnd(p, vt, i)
1122
}
1123

1124
func (self *_Compiler) compileUnmarshalText(p *_Program, vt reflect.Type) {
1125
    i := p.pc()
1126
    v := _OP_unmarshal_text
1127
    p.add(_OP_is_null)
1128

1129
    /* check for dynamic interface */
1130
    if vt.Kind() == reflect.Interface {
1131
        v = _OP_dyn
1132
    } else {
1133
        p.chr(_OP_match_char, '"')
1134
    }
1135

1136
    /* call the unmarshaler */
1137
    p.rtt(v, vt)
1138
    self.compileUnmarshalEnd(p, vt, i)
1139
}
1140

1141
func (self *_Compiler) compileUnmarshalTextPtr(p *_Program, vt reflect.Type) {
1142
    i := p.pc()
1143
    p.add(_OP_is_null)
1144
    p.chr(_OP_match_char, '"')
1145
    p.rtt(_OP_unmarshal_text_p, vt)
1146
    p.pin(i)
1147
}
1148

1149
func (self *_Compiler) checkIfSkip(p *_Program, vt reflect.Type, c byte) int {
1150
    j := p.pc()
1151
    p.chr(_OP_check_char_0, c)
1152
    p.rtt(_OP_dismatch_err, vt)
1153
    s := p.pc()
1154
    p.add(_OP_go_skip)
1155
    p.pin(j)
1156
    p.int(_OP_add, 1)
1157
    return s
1158
}
1159

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

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

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

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