github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/internal/decoder/compiler.go (about) 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/goshafaq/sonic/internal/caching" 29 "github.com/goshafaq/sonic/internal/resolver" 30 "github.com/goshafaq/sonic/internal/rt" 31 "github.com/goshafaq/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: 194 return _OP_i32 195 case 64: 196 return _OP_i64 197 default: 198 panic("unsupported int size") 199 } 200 } 201 202 func _OP_uint() _Op { 203 switch _INT_SIZE { 204 case 32: 205 return _OP_u32 206 case 64: 207 return _OP_u64 208 default: 209 panic("unsupported uint size") 210 } 211 } 212 213 func _OP_uintptr() _Op { 214 switch _PTR_SIZE { 215 case 32: 216 return _OP_u32 217 case 64: 218 return _OP_u64 219 default: 220 panic("unsupported pointer size") 221 } 222 } 223 224 func _OP_map_key_int() _Op { 225 switch _INT_SIZE { 226 case 32: 227 return _OP_map_key_i32 228 case 64: 229 return _OP_map_key_i64 230 default: 231 panic("unsupported int size") 232 } 233 } 234 235 func _OP_map_key_uint() _Op { 236 switch _INT_SIZE { 237 case 32: 238 return _OP_map_key_u32 239 case 64: 240 return _OP_map_key_u64 241 default: 242 panic("unsupported uint size") 243 } 244 } 245 246 func _OP_map_key_uintptr() _Op { 247 switch _PTR_SIZE { 248 case 32: 249 return _OP_map_key_u32 250 case 64: 251 return _OP_map_key_u64 252 default: 253 panic("unsupported pointer size") 254 } 255 } 256 257 type _Instr struct { 258 u uint64 // union {op: 8, vb: 8, vi: 48}, iv maybe int or len([]int) 259 p unsafe.Pointer // maybe GoSlice.Data, *GoType or *caching.FieldMap 260 } 261 262 func packOp(op _Op) uint64 { 263 return uint64(op) << 56 264 } 265 266 func newInsOp(op _Op) _Instr { 267 return _Instr{u: packOp(op)} 268 } 269 270 func newInsVi(op _Op, vi int) _Instr { 271 return _Instr{u: packOp(op) | rt.PackInt(vi)} 272 } 273 274 func newInsVb(op _Op, vb byte) _Instr { 275 return _Instr{u: packOp(op) | (uint64(vb) << 48)} 276 } 277 278 func newInsVs(op _Op, vs []int) _Instr { 279 return _Instr{ 280 u: packOp(op) | rt.PackInt(len(vs)), 281 p: (*rt.GoSlice)(unsafe.Pointer(&vs)).Ptr, 282 } 283 } 284 285 func newInsVt(op _Op, vt reflect.Type) _Instr { 286 return _Instr{ 287 u: packOp(op), 288 p: unsafe.Pointer(rt.UnpackType(vt)), 289 } 290 } 291 292 func newInsVf(op _Op, vf *caching.FieldMap) _Instr { 293 return _Instr{ 294 u: packOp(op), 295 p: unsafe.Pointer(vf), 296 } 297 } 298 299 func (self _Instr) op() _Op { 300 return _Op(self.u >> 56) 301 } 302 303 func (self _Instr) vi() int { 304 return rt.UnpackInt(self.u) 305 } 306 307 func (self _Instr) vb() byte { 308 return byte(self.u >> 48) 309 } 310 311 func (self _Instr) vs() (v []int) { 312 (*rt.GoSlice)(unsafe.Pointer(&v)).Ptr = self.p 313 (*rt.GoSlice)(unsafe.Pointer(&v)).Cap = self.vi() 314 (*rt.GoSlice)(unsafe.Pointer(&v)).Len = self.vi() 315 return 316 } 317 318 func (self _Instr) vf() *caching.FieldMap { 319 return (*caching.FieldMap)(self.p) 320 } 321 322 func (self _Instr) vk() reflect.Kind { 323 return (*rt.GoType)(self.p).Kind() 324 } 325 326 func (self _Instr) vt() reflect.Type { 327 return (*rt.GoType)(self.p).Pack() 328 } 329 330 func (self _Instr) i64() int64 { 331 return int64(self.vi()) 332 } 333 334 func (self _Instr) vlen() int { 335 return int((*rt.GoType)(self.p).Size) 336 } 337 338 func (self _Instr) isBranch() bool { 339 switch self.op() { 340 case _OP_goto: 341 fallthrough 342 case _OP_switch: 343 fallthrough 344 case _OP_is_null: 345 fallthrough 346 case _OP_is_null_quote: 347 fallthrough 348 case _OP_check_char: 349 return true 350 default: 351 return false 352 } 353 } 354 355 func (self _Instr) disassemble() string { 356 switch self.op() { 357 case _OP_dyn: 358 fallthrough 359 case _OP_deref: 360 fallthrough 361 case _OP_map_key_i8: 362 fallthrough 363 case _OP_map_key_i16: 364 fallthrough 365 case _OP_map_key_i32: 366 fallthrough 367 case _OP_map_key_i64: 368 fallthrough 369 case _OP_map_key_u8: 370 fallthrough 371 case _OP_map_key_u16: 372 fallthrough 373 case _OP_map_key_u32: 374 fallthrough 375 case _OP_map_key_u64: 376 fallthrough 377 case _OP_map_key_f32: 378 fallthrough 379 case _OP_map_key_f64: 380 fallthrough 381 case _OP_map_key_str: 382 fallthrough 383 case _OP_map_key_utext: 384 fallthrough 385 case _OP_map_key_utext_p: 386 fallthrough 387 case _OP_slice_init: 388 fallthrough 389 case _OP_slice_append: 390 fallthrough 391 case _OP_unmarshal: 392 fallthrough 393 case _OP_unmarshal_p: 394 fallthrough 395 case _OP_unmarshal_text: 396 fallthrough 397 case _OP_unmarshal_text_p: 398 fallthrough 399 case _OP_recurse: 400 return fmt.Sprintf("%-18s%s", self.op(), self.vt()) 401 case _OP_goto: 402 fallthrough 403 case _OP_is_null_quote: 404 fallthrough 405 case _OP_is_null: 406 return fmt.Sprintf("%-18sL_%d", self.op(), self.vi()) 407 case _OP_index: 408 fallthrough 409 case _OP_array_clear: 410 fallthrough 411 case _OP_array_clear_p: 412 return fmt.Sprintf("%-18s%d", self.op(), self.vi()) 413 case _OP_switch: 414 return fmt.Sprintf("%-18s%s", self.op(), self.formatSwitchLabels()) 415 case _OP_struct_field: 416 return fmt.Sprintf("%-18s%s", self.op(), self.formatStructFields()) 417 case _OP_match_char: 418 return fmt.Sprintf("%-18s%s", self.op(), strconv.QuoteRune(rune(self.vb()))) 419 case _OP_check_char: 420 return fmt.Sprintf("%-18sL_%d, %s", self.op(), self.vi(), strconv.QuoteRune(rune(self.vb()))) 421 default: 422 return self.op().String() 423 } 424 } 425 426 func (self _Instr) formatSwitchLabels() string { 427 var i int 428 var v int 429 var m []string 430 431 /* format each label */ 432 for i, v = range self.vs() { 433 m = append(m, fmt.Sprintf("%d=L_%d", i, v)) 434 } 435 436 /* join them with "," */ 437 return strings.Join(m, ", ") 438 } 439 440 func (self _Instr) formatStructFields() string { 441 var i uint64 442 var r []string 443 var m []struct { 444 i int 445 n string 446 } 447 448 /* extract all the fields */ 449 for i = 0; i < self.vf().N; i++ { 450 if v := self.vf().At(i); v.Hash != 0 { 451 m = append(m, struct { 452 i int 453 n string 454 }{i: v.ID, n: v.Name}) 455 } 456 } 457 458 /* sort by field name */ 459 sort.Slice(m, func(i, j int) bool { 460 return m[i].n < m[j].n 461 }) 462 463 /* format each field */ 464 for _, v := range m { 465 r = append(r, fmt.Sprintf("%s=%d", v.n, v.i)) 466 } 467 468 /* join them with "," */ 469 return strings.Join(r, ", ") 470 } 471 472 type ( 473 _Program []_Instr 474 ) 475 476 func (self _Program) pc() int { 477 return len(self) 478 } 479 480 func (self _Program) tag(n int) { 481 if n >= _MaxStack { 482 panic("type nesting too deep") 483 } 484 } 485 486 func (self _Program) pin(i int) { 487 v := &self[i] 488 v.u &= 0xffff000000000000 489 v.u |= rt.PackInt(self.pc()) 490 } 491 492 func (self _Program) rel(v []int) { 493 for _, i := range v { 494 self.pin(i) 495 } 496 } 497 498 func (self *_Program) add(op _Op) { 499 *self = append(*self, newInsOp(op)) 500 } 501 502 func (self *_Program) int(op _Op, vi int) { 503 *self = append(*self, newInsVi(op, vi)) 504 } 505 506 func (self *_Program) chr(op _Op, vb byte) { 507 *self = append(*self, newInsVb(op, vb)) 508 } 509 510 func (self *_Program) tab(op _Op, vs []int) { 511 *self = append(*self, newInsVs(op, vs)) 512 } 513 514 func (self *_Program) rtt(op _Op, vt reflect.Type) { 515 *self = append(*self, newInsVt(op, vt)) 516 } 517 518 func (self *_Program) fmv(op _Op, vf *caching.FieldMap) { 519 *self = append(*self, newInsVf(op, vf)) 520 } 521 522 func (self _Program) disassemble() string { 523 nb := len(self) 524 tab := make([]bool, nb+1) 525 ret := make([]string, 0, nb+1) 526 527 /* prescan to get all the labels */ 528 for _, ins := range self { 529 if ins.isBranch() { 530 if ins.op() != _OP_switch { 531 tab[ins.vi()] = true 532 } else { 533 for _, v := range ins.vs() { 534 tab[v] = true 535 } 536 } 537 } 538 } 539 540 /* disassemble each instruction */ 541 for i, ins := range self { 542 if !tab[i] { 543 ret = append(ret, "\t"+ins.disassemble()) 544 } else { 545 ret = append(ret, fmt.Sprintf("L_%d:\n\t%s", i, ins.disassemble())) 546 } 547 } 548 549 /* add the last label, if needed */ 550 if tab[nb] { 551 ret = append(ret, fmt.Sprintf("L_%d:", nb)) 552 } 553 554 /* add an "end" indicator, and join all the strings */ 555 return strings.Join(append(ret, "\tend"), "\n") 556 } 557 558 type _Compiler struct { 559 opts option.CompileOptions 560 tab map[reflect.Type]bool 561 rec map[reflect.Type]bool 562 } 563 564 func newCompiler() *_Compiler { 565 return &_Compiler{ 566 opts: option.DefaultCompileOptions(), 567 tab: map[reflect.Type]bool{}, 568 rec: map[reflect.Type]bool{}, 569 } 570 } 571 572 func (self *_Compiler) apply(opts option.CompileOptions) *_Compiler { 573 self.opts = opts 574 return self 575 } 576 577 func (self *_Compiler) rescue(ep *error) { 578 if val := recover(); val != nil { 579 if err, ok := val.(error); ok { 580 *ep = err 581 } else { 582 panic(val) 583 } 584 } 585 } 586 587 func (self *_Compiler) compile(vt reflect.Type) (ret _Program, err error) { 588 defer self.rescue(&err) 589 self.compileOne(&ret, 0, vt) 590 return 591 } 592 593 func (self *_Compiler) checkMarshaler(p *_Program, vt reflect.Type) bool { 594 pt := reflect.PtrTo(vt) 595 596 /* check for `json.Unmarshaler` with pointer receiver */ 597 if pt.Implements(jsonUnmarshalerType) { 598 p.rtt(_OP_unmarshal_p, pt) 599 return true 600 } 601 602 /* check for `json.Unmarshaler` */ 603 if vt.Implements(jsonUnmarshalerType) { 604 p.add(_OP_lspace) 605 self.compileUnmarshalJson(p, vt) 606 return true 607 } 608 609 /* check for `encoding.TextMarshaler` with pointer receiver */ 610 if pt.Implements(encodingTextUnmarshalerType) { 611 p.add(_OP_lspace) 612 self.compileUnmarshalTextPtr(p, pt) 613 return true 614 } 615 616 /* check for `encoding.TextUnmarshaler` */ 617 if vt.Implements(encodingTextUnmarshalerType) { 618 p.add(_OP_lspace) 619 self.compileUnmarshalText(p, vt) 620 return true 621 } 622 return false 623 } 624 625 func (self *_Compiler) compileOne(p *_Program, sp int, vt reflect.Type) { 626 /* check for recursive nesting */ 627 ok := self.tab[vt] 628 if ok { 629 p.rtt(_OP_recurse, vt) 630 return 631 } 632 633 if self.checkMarshaler(p, vt) { 634 return 635 } 636 637 /* enter the recursion */ 638 p.add(_OP_lspace) 639 self.tab[vt] = true 640 self.compileOps(p, sp, vt) 641 delete(self.tab, vt) 642 } 643 644 func (self *_Compiler) compileOps(p *_Program, sp int, vt reflect.Type) { 645 switch vt.Kind() { 646 case reflect.Bool: 647 self.compilePrimitive(vt, p, _OP_bool) 648 case reflect.Int: 649 self.compilePrimitive(vt, p, _OP_int()) 650 case reflect.Int8: 651 self.compilePrimitive(vt, p, _OP_i8) 652 case reflect.Int16: 653 self.compilePrimitive(vt, p, _OP_i16) 654 case reflect.Int32: 655 self.compilePrimitive(vt, p, _OP_i32) 656 case reflect.Int64: 657 self.compilePrimitive(vt, p, _OP_i64) 658 case reflect.Uint: 659 self.compilePrimitive(vt, p, _OP_uint()) 660 case reflect.Uint8: 661 self.compilePrimitive(vt, p, _OP_u8) 662 case reflect.Uint16: 663 self.compilePrimitive(vt, p, _OP_u16) 664 case reflect.Uint32: 665 self.compilePrimitive(vt, p, _OP_u32) 666 case reflect.Uint64: 667 self.compilePrimitive(vt, p, _OP_u64) 668 case reflect.Uintptr: 669 self.compilePrimitive(vt, p, _OP_uintptr()) 670 case reflect.Float32: 671 self.compilePrimitive(vt, p, _OP_f32) 672 case reflect.Float64: 673 self.compilePrimitive(vt, p, _OP_f64) 674 case reflect.String: 675 self.compileString(p, vt) 676 case reflect.Array: 677 self.compileArray(p, sp, vt) 678 case reflect.Interface: 679 self.compileInterface(p, vt) 680 case reflect.Map: 681 self.compileMap(p, sp, vt) 682 case reflect.Ptr: 683 self.compilePtr(p, sp, vt) 684 case reflect.Slice: 685 self.compileSlice(p, sp, vt) 686 case reflect.Struct: 687 self.compileStruct(p, sp, vt) 688 default: 689 panic(&json.UnmarshalTypeError{Type: vt}) 690 } 691 } 692 693 func (self *_Compiler) compileMap(p *_Program, sp int, vt reflect.Type) { 694 if reflect.PtrTo(vt.Key()).Implements(encodingTextUnmarshalerType) { 695 self.compileMapOp(p, sp, vt, _OP_map_key_utext_p) 696 } else if vt.Key().Implements(encodingTextUnmarshalerType) { 697 self.compileMapOp(p, sp, vt, _OP_map_key_utext) 698 } else { 699 self.compileMapUt(p, sp, vt) 700 } 701 } 702 703 func (self *_Compiler) compileMapUt(p *_Program, sp int, vt reflect.Type) { 704 switch vt.Key().Kind() { 705 case reflect.Int: 706 self.compileMapOp(p, sp, vt, _OP_map_key_int()) 707 case reflect.Int8: 708 self.compileMapOp(p, sp, vt, _OP_map_key_i8) 709 case reflect.Int16: 710 self.compileMapOp(p, sp, vt, _OP_map_key_i16) 711 case reflect.Int32: 712 self.compileMapOp(p, sp, vt, _OP_map_key_i32) 713 case reflect.Int64: 714 self.compileMapOp(p, sp, vt, _OP_map_key_i64) 715 case reflect.Uint: 716 self.compileMapOp(p, sp, vt, _OP_map_key_uint()) 717 case reflect.Uint8: 718 self.compileMapOp(p, sp, vt, _OP_map_key_u8) 719 case reflect.Uint16: 720 self.compileMapOp(p, sp, vt, _OP_map_key_u16) 721 case reflect.Uint32: 722 self.compileMapOp(p, sp, vt, _OP_map_key_u32) 723 case reflect.Uint64: 724 self.compileMapOp(p, sp, vt, _OP_map_key_u64) 725 case reflect.Uintptr: 726 self.compileMapOp(p, sp, vt, _OP_map_key_uintptr()) 727 case reflect.Float32: 728 self.compileMapOp(p, sp, vt, _OP_map_key_f32) 729 case reflect.Float64: 730 self.compileMapOp(p, sp, vt, _OP_map_key_f64) 731 case reflect.String: 732 self.compileMapOp(p, sp, vt, _OP_map_key_str) 733 default: 734 panic(&json.UnmarshalTypeError{Type: vt}) 735 } 736 } 737 738 func (self *_Compiler) compileMapOp(p *_Program, sp int, vt reflect.Type, op _Op) { 739 i := p.pc() 740 p.add(_OP_is_null) 741 p.tag(sp + 1) 742 skip := self.checkIfSkip(p, vt, '{') 743 p.add(_OP_save) 744 p.add(_OP_map_init) 745 p.add(_OP_save) 746 p.add(_OP_lspace) 747 j := p.pc() 748 p.chr(_OP_check_char, '}') 749 p.chr(_OP_match_char, '"') 750 skip2 := p.pc() 751 p.rtt(op, vt) 752 753 /* match the value separator */ 754 p.add(_OP_lspace) 755 p.chr(_OP_match_char, ':') 756 self.compileOne(p, sp+2, vt.Elem()) 757 p.pin(skip2) 758 p.add(_OP_load) 759 k0 := p.pc() 760 p.add(_OP_lspace) 761 k1 := p.pc() 762 p.chr(_OP_check_char, '}') 763 p.chr(_OP_match_char, ',') 764 p.add(_OP_lspace) 765 p.chr(_OP_match_char, '"') 766 skip3 := p.pc() 767 p.rtt(op, vt) 768 769 /* match the value separator */ 770 p.add(_OP_lspace) 771 p.chr(_OP_match_char, ':') 772 self.compileOne(p, sp+2, vt.Elem()) 773 p.pin(skip3) 774 p.add(_OP_load) 775 p.int(_OP_goto, k0) 776 p.pin(j) 777 p.pin(k1) 778 p.add(_OP_drop_2) 779 x := p.pc() 780 p.add(_OP_goto) 781 p.pin(i) 782 p.add(_OP_nil_1) 783 p.pin(skip) 784 p.pin(x) 785 } 786 787 func (self *_Compiler) compilePtr(p *_Program, sp int, et reflect.Type) { 788 i := p.pc() 789 p.add(_OP_is_null) 790 791 /* dereference all the way down */ 792 for et.Kind() == reflect.Ptr { 793 if self.checkMarshaler(p, et) { 794 return 795 } 796 et = et.Elem() 797 p.rtt(_OP_deref, et) 798 } 799 800 /* check for recursive nesting */ 801 ok := self.tab[et] 802 if ok { 803 p.rtt(_OP_recurse, et) 804 } else { 805 /* enter the recursion */ 806 p.add(_OP_lspace) 807 self.tab[et] = true 808 809 /* not inline the pointer type 810 * recursing the defined pointer type's elem will casue issue379. 811 */ 812 self.compileOps(p, sp, et) 813 } 814 delete(self.tab, et) 815 816 j := p.pc() 817 p.add(_OP_goto) 818 819 // set val pointer as nil 820 p.pin(i) 821 p.add(_OP_nil_1) 822 823 // nothing todo 824 p.pin(j) 825 } 826 827 func (self *_Compiler) compileArray(p *_Program, sp int, vt reflect.Type) { 828 x := p.pc() 829 p.add(_OP_is_null) 830 p.tag(sp) 831 skip := self.checkIfSkip(p, vt, '[') 832 833 p.add(_OP_save) 834 p.add(_OP_lspace) 835 v := []int{p.pc()} 836 p.chr(_OP_check_char, ']') 837 838 /* decode every item */ 839 for i := 1; i <= vt.Len(); i++ { 840 self.compileOne(p, sp+1, vt.Elem()) 841 p.add(_OP_load) 842 p.int(_OP_index, i*int(vt.Elem().Size())) 843 p.add(_OP_lspace) 844 v = append(v, p.pc()) 845 p.chr(_OP_check_char, ']') 846 p.chr(_OP_match_char, ',') 847 } 848 849 /* drop rest of the array */ 850 p.add(_OP_array_skip) 851 w := p.pc() 852 p.add(_OP_goto) 853 p.rel(v) 854 855 /* check for pointer data */ 856 if rt.UnpackType(vt.Elem()).PtrData == 0 { 857 p.int(_OP_array_clear, int(vt.Size())) 858 } else { 859 p.int(_OP_array_clear_p, int(vt.Size())) 860 } 861 862 /* restore the stack */ 863 p.pin(w) 864 p.add(_OP_drop) 865 866 p.pin(skip) 867 p.pin(x) 868 } 869 870 func (self *_Compiler) compileSlice(p *_Program, sp int, vt reflect.Type) { 871 if vt.Elem().Kind() == byteType.Kind() { 872 self.compileSliceBin(p, sp, vt) 873 } else { 874 self.compileSliceList(p, sp, vt) 875 } 876 } 877 878 func (self *_Compiler) compileSliceBin(p *_Program, sp int, vt reflect.Type) { 879 i := p.pc() 880 p.add(_OP_is_null) 881 j := p.pc() 882 p.chr(_OP_check_char, '[') 883 skip := self.checkIfSkip(p, vt, '"') 884 k := p.pc() 885 p.chr(_OP_check_char, '"') 886 p.add(_OP_bin) 887 x := p.pc() 888 p.add(_OP_goto) 889 p.pin(j) 890 self.compileSliceBody(p, sp, vt.Elem()) 891 y := p.pc() 892 p.add(_OP_goto) 893 p.pin(i) 894 p.pin(k) 895 p.add(_OP_nil_3) 896 p.pin(x) 897 p.pin(skip) 898 p.pin(y) 899 } 900 901 func (self *_Compiler) compileSliceList(p *_Program, sp int, vt reflect.Type) { 902 i := p.pc() 903 p.add(_OP_is_null) 904 p.tag(sp) 905 skip := self.checkIfSkip(p, vt, '[') 906 self.compileSliceBody(p, sp, vt.Elem()) 907 x := p.pc() 908 p.add(_OP_goto) 909 p.pin(i) 910 p.add(_OP_nil_3) 911 p.pin(x) 912 p.pin(skip) 913 } 914 915 func (self *_Compiler) compileSliceBody(p *_Program, sp int, et reflect.Type) { 916 p.add(_OP_lspace) 917 j := p.pc() 918 p.chr(_OP_check_empty, ']') 919 p.rtt(_OP_slice_init, et) 920 p.add(_OP_save) 921 p.rtt(_OP_slice_append, et) 922 self.compileOne(p, sp+1, et) 923 p.add(_OP_load) 924 k0 := p.pc() 925 p.add(_OP_lspace) 926 k1 := p.pc() 927 p.chr(_OP_check_char, ']') 928 p.chr(_OP_match_char, ',') 929 p.rtt(_OP_slice_append, et) 930 self.compileOne(p, sp+1, et) 931 p.add(_OP_load) 932 p.int(_OP_goto, k0) 933 p.pin(k1) 934 p.add(_OP_drop) 935 p.pin(j) 936 } 937 938 func (self *_Compiler) compileString(p *_Program, vt reflect.Type) { 939 if vt == jsonNumberType { 940 self.compilePrimitive(vt, p, _OP_num) 941 } else { 942 self.compileStringBody(vt, p) 943 } 944 } 945 946 func (self *_Compiler) compileStringBody(vt reflect.Type, p *_Program) { 947 i := p.pc() 948 p.add(_OP_is_null) 949 skip := self.checkIfSkip(p, vt, '"') 950 p.add(_OP_str) 951 p.pin(i) 952 p.pin(skip) 953 } 954 955 func (self *_Compiler) compileStruct(p *_Program, sp int, vt reflect.Type) { 956 if sp >= self.opts.MaxInlineDepth || p.pc() >= _MAX_ILBUF || (sp > 0 && vt.NumField() >= _MAX_FIELDS) { 957 p.rtt(_OP_recurse, vt) 958 if self.opts.RecursiveDepth > 0 { 959 self.rec[vt] = true 960 } 961 } else { 962 self.compileStructBody(p, sp, vt) 963 } 964 } 965 966 func (self *_Compiler) compileStructBody(p *_Program, sp int, vt reflect.Type) { 967 fv := resolver.ResolveStruct(vt) 968 fm, sw := caching.CreateFieldMap(len(fv)), make([]int, len(fv)) 969 970 /* start of object */ 971 p.tag(sp) 972 n := p.pc() 973 p.add(_OP_is_null) 974 975 skip := self.checkIfSkip(p, vt, '{') 976 977 p.add(_OP_save) 978 p.add(_OP_lspace) 979 x := p.pc() 980 p.chr(_OP_check_char, '}') 981 p.chr(_OP_match_char, '"') 982 p.fmv(_OP_struct_field, fm) 983 p.add(_OP_lspace) 984 p.chr(_OP_match_char, ':') 985 p.tab(_OP_switch, sw) 986 p.add(_OP_object_next) 987 y0 := p.pc() 988 p.add(_OP_lspace) 989 y1 := p.pc() 990 p.chr(_OP_check_char, '}') 991 p.chr(_OP_match_char, ',') 992 993 /* special case of an empty struct */ 994 if len(fv) == 0 { 995 p.add(_OP_object_skip) 996 goto end_of_object 997 } 998 999 /* match the remaining fields */ 1000 p.add(_OP_lspace) 1001 p.chr(_OP_match_char, '"') 1002 p.fmv(_OP_struct_field, fm) 1003 p.add(_OP_lspace) 1004 p.chr(_OP_match_char, ':') 1005 p.tab(_OP_switch, sw) 1006 p.add(_OP_object_next) 1007 p.int(_OP_goto, y0) 1008 1009 /* process each field */ 1010 for i, f := range fv { 1011 sw[i] = p.pc() 1012 fm.Set(f.Name, i) 1013 1014 /* index to the field */ 1015 for _, o := range f.Path { 1016 if p.int(_OP_index, int(o.Size)); o.Kind == resolver.F_deref { 1017 p.rtt(_OP_deref, o.Type) 1018 } 1019 } 1020 1021 /* check for "stringnize" option */ 1022 if (f.Opts & resolver.F_stringize) == 0 { 1023 self.compileOne(p, sp+1, f.Type) 1024 } else { 1025 self.compileStructFieldStr(p, sp+1, f.Type) 1026 } 1027 1028 /* load the state, and try next field */ 1029 p.add(_OP_load) 1030 p.int(_OP_goto, y0) 1031 } 1032 1033 end_of_object: 1034 p.pin(x) 1035 p.pin(y1) 1036 p.add(_OP_drop) 1037 p.pin(n) 1038 p.pin(skip) 1039 } 1040 1041 func (self *_Compiler) compileStructFieldStr(p *_Program, sp int, vt reflect.Type) { 1042 n1 := -1 1043 ft := vt 1044 sv := false 1045 1046 /* dereference the pointer if needed */ 1047 if ft.Kind() == reflect.Ptr { 1048 ft = ft.Elem() 1049 } 1050 1051 /* check if it can be stringized */ 1052 switch ft.Kind() { 1053 case reflect.Bool: 1054 sv = true 1055 case reflect.Int: 1056 sv = true 1057 case reflect.Int8: 1058 sv = true 1059 case reflect.Int16: 1060 sv = true 1061 case reflect.Int32: 1062 sv = true 1063 case reflect.Int64: 1064 sv = true 1065 case reflect.Uint: 1066 sv = true 1067 case reflect.Uint8: 1068 sv = true 1069 case reflect.Uint16: 1070 sv = true 1071 case reflect.Uint32: 1072 sv = true 1073 case reflect.Uint64: 1074 sv = true 1075 case reflect.Uintptr: 1076 sv = true 1077 case reflect.Float32: 1078 sv = true 1079 case reflect.Float64: 1080 sv = true 1081 case reflect.String: 1082 sv = true 1083 } 1084 1085 /* if it's not, ignore the "string" and follow the regular path */ 1086 if !sv { 1087 self.compileOne(p, sp, vt) 1088 return 1089 } 1090 1091 /* remove the leading space, and match the leading quote */ 1092 vk := vt.Kind() 1093 p.add(_OP_lspace) 1094 n0 := p.pc() 1095 p.add(_OP_is_null) 1096 1097 skip := self.checkIfSkip(p, stringType, '"') 1098 1099 /* also check for inner "null" */ 1100 n1 = p.pc() 1101 p.add(_OP_is_null_quote) 1102 1103 /* dereference the pointer only when it is not null */ 1104 if vk == reflect.Ptr { 1105 vt = vt.Elem() 1106 p.rtt(_OP_deref, vt) 1107 } 1108 1109 n2 := p.pc() 1110 p.chr(_OP_check_char_0, '"') 1111 1112 /* string opcode selector */ 1113 _OP_string := func() _Op { 1114 if ft == jsonNumberType { 1115 return _OP_num 1116 } else { 1117 return _OP_unquote 1118 } 1119 } 1120 1121 /* compile for each type */ 1122 switch vt.Kind() { 1123 case reflect.Bool: 1124 p.add(_OP_bool) 1125 case reflect.Int: 1126 p.add(_OP_int()) 1127 case reflect.Int8: 1128 p.add(_OP_i8) 1129 case reflect.Int16: 1130 p.add(_OP_i16) 1131 case reflect.Int32: 1132 p.add(_OP_i32) 1133 case reflect.Int64: 1134 p.add(_OP_i64) 1135 case reflect.Uint: 1136 p.add(_OP_uint()) 1137 case reflect.Uint8: 1138 p.add(_OP_u8) 1139 case reflect.Uint16: 1140 p.add(_OP_u16) 1141 case reflect.Uint32: 1142 p.add(_OP_u32) 1143 case reflect.Uint64: 1144 p.add(_OP_u64) 1145 case reflect.Uintptr: 1146 p.add(_OP_uintptr()) 1147 case reflect.Float32: 1148 p.add(_OP_f32) 1149 case reflect.Float64: 1150 p.add(_OP_f64) 1151 case reflect.String: 1152 p.add(_OP_string()) 1153 default: 1154 panic("not reachable") 1155 } 1156 1157 /* the closing quote is not needed when parsing a pure string */ 1158 if vt == jsonNumberType || vt.Kind() != reflect.String { 1159 p.chr(_OP_match_char, '"') 1160 } 1161 1162 /* pin the `is_null_quote` jump location */ 1163 if n1 != -1 && vk != reflect.Ptr { 1164 p.pin(n1) 1165 } 1166 1167 /* "null" but not a pointer, act as if the field is not present */ 1168 if vk != reflect.Ptr { 1169 pc2 := p.pc() 1170 p.add(_OP_goto) 1171 p.pin(n2) 1172 p.rtt(_OP_dismatch_err, vt) 1173 p.int(_OP_add, 1) 1174 p.pin(pc2) 1175 p.pin(n0) 1176 return 1177 } 1178 1179 /* the "null" case of the pointer */ 1180 pc := p.pc() 1181 p.add(_OP_goto) 1182 p.pin(n0) // `is_null` jump location 1183 p.pin(n1) // `is_null_quote` jump location 1184 p.add(_OP_nil_1) 1185 pc2 := p.pc() 1186 p.add(_OP_goto) 1187 p.pin(n2) 1188 p.rtt(_OP_dismatch_err, vt) 1189 p.int(_OP_add, 1) 1190 p.pin(pc) 1191 p.pin(pc2) 1192 p.pin(skip) 1193 } 1194 1195 func (self *_Compiler) compileInterface(p *_Program, vt reflect.Type) { 1196 i := p.pc() 1197 p.add(_OP_is_null) 1198 1199 /* check for empty interface */ 1200 if vt.NumMethod() == 0 { 1201 p.add(_OP_any) 1202 } else { 1203 p.rtt(_OP_dyn, vt) 1204 } 1205 1206 /* finish the OpCode */ 1207 j := p.pc() 1208 p.add(_OP_goto) 1209 p.pin(i) 1210 p.add(_OP_nil_2) 1211 p.pin(j) 1212 } 1213 1214 func (self *_Compiler) compilePrimitive(vt reflect.Type, p *_Program, op _Op) { 1215 i := p.pc() 1216 p.add(_OP_is_null) 1217 // skip := self.checkPrimitive(p, vt) 1218 p.add(op) 1219 p.pin(i) 1220 // p.pin(skip) 1221 } 1222 1223 func (self *_Compiler) compileUnmarshalEnd(p *_Program, vt reflect.Type, i int) { 1224 j := p.pc() 1225 k := vt.Kind() 1226 1227 /* not a pointer */ 1228 if k != reflect.Ptr { 1229 p.pin(i) 1230 return 1231 } 1232 1233 /* it seems that in Go JSON library, "null" takes priority over any kind of unmarshaler */ 1234 p.add(_OP_goto) 1235 p.pin(i) 1236 p.add(_OP_nil_1) 1237 p.pin(j) 1238 } 1239 1240 func (self *_Compiler) compileUnmarshalJson(p *_Program, vt reflect.Type) { 1241 i := p.pc() 1242 v := _OP_unmarshal 1243 p.add(_OP_is_null) 1244 1245 /* check for dynamic interface */ 1246 if vt.Kind() == reflect.Interface { 1247 v = _OP_dyn 1248 } 1249 1250 /* call the unmarshaler */ 1251 p.rtt(v, vt) 1252 self.compileUnmarshalEnd(p, vt, i) 1253 } 1254 1255 func (self *_Compiler) compileUnmarshalText(p *_Program, vt reflect.Type) { 1256 i := p.pc() 1257 v := _OP_unmarshal_text 1258 p.add(_OP_is_null) 1259 1260 /* check for dynamic interface */ 1261 if vt.Kind() == reflect.Interface { 1262 v = _OP_dyn 1263 } else { 1264 p.chr(_OP_match_char, '"') 1265 } 1266 1267 /* call the unmarshaler */ 1268 p.rtt(v, vt) 1269 self.compileUnmarshalEnd(p, vt, i) 1270 } 1271 1272 func (self *_Compiler) compileUnmarshalTextPtr(p *_Program, vt reflect.Type) { 1273 i := p.pc() 1274 p.add(_OP_is_null) 1275 p.chr(_OP_match_char, '"') 1276 p.rtt(_OP_unmarshal_text_p, vt) 1277 p.pin(i) 1278 } 1279 1280 func (self *_Compiler) checkIfSkip(p *_Program, vt reflect.Type, c byte) int { 1281 j := p.pc() 1282 p.chr(_OP_check_char_0, c) 1283 p.rtt(_OP_dismatch_err, vt) 1284 s := p.pc() 1285 p.add(_OP_go_skip) 1286 p.pin(j) 1287 p.int(_OP_add, 1) 1288 return s 1289 }