1
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
113 _MAX_FIELDS = 50
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
241 p unsafe.Pointer
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
375 for i, v = range self.vs() {
376 m = append(m, fmt.Sprintf("%d=L_%d", i, v))
377 }
378
379
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
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
396 sort.Slice(m, func(i, j int) bool {
397 return m[i].n < m[j].n
398 })
399
400
401 for _, v := range m {
402 r = append(r, fmt.Sprintf("%s=%d", v.n, v.i))
403 }
404
405
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
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
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
487 if tab[nb] {
488 ret = append(ret, fmt.Sprintf("L_%d:", nb))
489 }
490
491
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
534 if pt.Implements(jsonUnmarshalerType) {
535 p.rtt(_OP_unmarshal_p, pt)
536 return true
537 }
538
539
540 if vt.Implements(jsonUnmarshalerType) {
541 p.add(_OP_lspace)
542 self.compileUnmarshalJson(p, vt)
543 return true
544 }
545
546
547 if pt.Implements(encodingTextUnmarshalerType) {
548 p.add(_OP_lspace)
549 self.compileUnmarshalTextPtr(p, pt)
550 return true
551 }
552
553
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
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
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
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
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
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
701 ok := self.tab[et]
702 if ok {
703 p.rtt(_OP_recurse, et)
704 } else {
705
706 p.add(_OP_lspace)
707 self.tab[et] = true
708
709
712 self.compileOps(p, sp, et)
713 }
714 delete(self.tab, et)
715
716 j := p.pc()
717 p.add(_OP_goto)
718
719
720 p.pin(i)
721 p.add(_OP_nil_1)
722
723
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
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
750 p.add(_OP_array_skip)
751 w := p.pc()
752 p.add(_OP_goto)
753 p.rel(v)
754
755
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
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
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
894 if len(fv) == 0 {
895 p.add(_OP_object_skip)
896 goto end_of_object
897 }
898
899
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
910 for i, f := range fv {
911 sw[i] = p.pc()
912 fm.Set(f.Name, i)
913
914
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
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
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
947 if ft.Kind() == reflect.Ptr {
948 ft = ft.Elem()
949 }
950
951
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
971 if !sv {
972 self.compileOne(p, sp, vt)
973 return
974 }
975
976
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
985 n1 = p.pc()
986 p.add(_OP_is_null_quote)
987
988
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
998 _OP_string := func() _Op {
999 if ft == jsonNumberType {
1000 return _OP_num
1001 } else {
1002 return _OP_unquote
1003 }
1004 }
1005
1006
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
1027 if vt == jsonNumberType || vt.Kind() != reflect.String {
1028 p.chr(_OP_match_char, '"')
1029 }
1030
1031
1032 if n1 != -1 && vk != reflect.Ptr {
1033 p.pin(n1)
1034 }
1035
1036
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
1049 pc := p.pc()
1050 p.add(_OP_goto)
1051 p.pin(n0)
1052 p.pin(n1)
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
1069 if vt.NumMethod() == 0 {
1070 p.add(_OP_any)
1071 } else {
1072 p.rtt(_OP_dyn, vt)
1073 }
1074
1075
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
1087 p.add(op)
1088 p.pin(i)
1089
1090 }
1091
1092 func (self *_Compiler) compileUnmarshalEnd(p *_Program, vt reflect.Type, i int) {
1093 j := p.pc()
1094 k := vt.Kind()
1095
1096
1097 if k != reflect.Ptr {
1098 p.pin(i)
1099 return
1100 }
1101
1102
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
1115 if vt.Kind() == reflect.Interface {
1116 v = _OP_dyn
1117 }
1118
1119
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
1130 if vt.Kind() == reflect.Interface {
1131 v = _OP_dyn
1132 } else {
1133 p.chr(_OP_match_char, '"')
1134 }
1135
1136
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
View as plain text