compiler.go (31062B)
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) compileOne(p *_Program, sp int, vt reflect.Type) { 531 /* check for recursive nesting */ 532 ok := self.tab[vt] 533 if ok { 534 p.rtt(_OP_recurse, vt) 535 return 536 } 537 538 pt := reflect.PtrTo(vt) 539 540 /* check for `json.Unmarshaler` with pointer receiver */ 541 if pt.Implements(jsonUnmarshalerType) { 542 p.rtt(_OP_unmarshal_p, pt) 543 return 544 } 545 546 /* check for `json.Unmarshaler` */ 547 if vt.Implements(jsonUnmarshalerType) { 548 p.add(_OP_lspace) 549 self.compileUnmarshalJson(p, vt) 550 return 551 } 552 553 /* check for `encoding.TextMarshaler` with pointer receiver */ 554 if pt.Implements(encodingTextUnmarshalerType) { 555 p.add(_OP_lspace) 556 self.compileUnmarshalTextPtr(p, pt) 557 return 558 } 559 560 /* check for `encoding.TextUnmarshaler` */ 561 if vt.Implements(encodingTextUnmarshalerType) { 562 p.add(_OP_lspace) 563 self.compileUnmarshalText(p, vt) 564 return 565 } 566 567 /* enter the recursion */ 568 p.add(_OP_lspace) 569 self.tab[vt] = true 570 self.compileOps(p, sp, vt) 571 delete(self.tab, vt) 572 } 573 574 func (self *_Compiler) compileOps(p *_Program, sp int, vt reflect.Type) { 575 switch vt.Kind() { 576 case reflect.Bool : self.compilePrimitive (vt, p, _OP_bool) 577 case reflect.Int : self.compilePrimitive (vt, p, _OP_int()) 578 case reflect.Int8 : self.compilePrimitive (vt, p, _OP_i8) 579 case reflect.Int16 : self.compilePrimitive (vt, p, _OP_i16) 580 case reflect.Int32 : self.compilePrimitive (vt, p, _OP_i32) 581 case reflect.Int64 : self.compilePrimitive (vt, p, _OP_i64) 582 case reflect.Uint : self.compilePrimitive (vt, p, _OP_uint()) 583 case reflect.Uint8 : self.compilePrimitive (vt, p, _OP_u8) 584 case reflect.Uint16 : self.compilePrimitive (vt, p, _OP_u16) 585 case reflect.Uint32 : self.compilePrimitive (vt, p, _OP_u32) 586 case reflect.Uint64 : self.compilePrimitive (vt, p, _OP_u64) 587 case reflect.Uintptr : self.compilePrimitive (vt, p, _OP_uintptr()) 588 case reflect.Float32 : self.compilePrimitive (vt, p, _OP_f32) 589 case reflect.Float64 : self.compilePrimitive (vt, p, _OP_f64) 590 case reflect.String : self.compileString (p, vt) 591 case reflect.Array : self.compileArray (p, sp, vt) 592 case reflect.Interface : self.compileInterface (p, vt) 593 case reflect.Map : self.compileMap (p, sp, vt) 594 case reflect.Ptr : self.compilePtr (p, sp, vt) 595 case reflect.Slice : self.compileSlice (p, sp, vt) 596 case reflect.Struct : self.compileStruct (p, sp, vt) 597 default : panic (&json.UnmarshalTypeError{Type: vt}) 598 } 599 } 600 601 func (self *_Compiler) compileMap(p *_Program, sp int, vt reflect.Type) { 602 if reflect.PtrTo(vt.Key()).Implements(encodingTextUnmarshalerType) { 603 self.compileMapOp(p, sp, vt, _OP_map_key_utext_p) 604 } else if vt.Key().Implements(encodingTextUnmarshalerType) { 605 self.compileMapOp(p, sp, vt, _OP_map_key_utext) 606 } else { 607 self.compileMapUt(p, sp, vt) 608 } 609 } 610 611 func (self *_Compiler) compileMapUt(p *_Program, sp int, vt reflect.Type) { 612 switch vt.Key().Kind() { 613 case reflect.Int : self.compileMapOp(p, sp, vt, _OP_map_key_int()) 614 case reflect.Int8 : self.compileMapOp(p, sp, vt, _OP_map_key_i8) 615 case reflect.Int16 : self.compileMapOp(p, sp, vt, _OP_map_key_i16) 616 case reflect.Int32 : self.compileMapOp(p, sp, vt, _OP_map_key_i32) 617 case reflect.Int64 : self.compileMapOp(p, sp, vt, _OP_map_key_i64) 618 case reflect.Uint : self.compileMapOp(p, sp, vt, _OP_map_key_uint()) 619 case reflect.Uint8 : self.compileMapOp(p, sp, vt, _OP_map_key_u8) 620 case reflect.Uint16 : self.compileMapOp(p, sp, vt, _OP_map_key_u16) 621 case reflect.Uint32 : self.compileMapOp(p, sp, vt, _OP_map_key_u32) 622 case reflect.Uint64 : self.compileMapOp(p, sp, vt, _OP_map_key_u64) 623 case reflect.Uintptr : self.compileMapOp(p, sp, vt, _OP_map_key_uintptr()) 624 case reflect.Float32 : self.compileMapOp(p, sp, vt, _OP_map_key_f32) 625 case reflect.Float64 : self.compileMapOp(p, sp, vt, _OP_map_key_f64) 626 case reflect.String : self.compileMapOp(p, sp, vt, _OP_map_key_str) 627 default : panic(&json.UnmarshalTypeError{Type: vt}) 628 } 629 } 630 631 func (self *_Compiler) compileMapOp(p *_Program, sp int, vt reflect.Type, op _Op) { 632 i := p.pc() 633 p.add(_OP_is_null) 634 p.tag(sp + 1) 635 skip := self.checkIfSkip(p, vt, '{') 636 p.add(_OP_save) 637 p.add(_OP_map_init) 638 p.add(_OP_save) 639 p.add(_OP_lspace) 640 j := p.pc() 641 p.chr(_OP_check_char, '}') 642 p.chr(_OP_match_char, '"') 643 skip2 := p.pc() 644 p.rtt(op, vt) 645 646 /* match the value separator */ 647 p.add(_OP_lspace) 648 p.chr(_OP_match_char, ':') 649 self.compileOne(p, sp + 2, vt.Elem()) 650 p.pin(skip2) 651 p.add(_OP_load) 652 k0 := p.pc() 653 p.add(_OP_lspace) 654 k1 := p.pc() 655 p.chr(_OP_check_char, '}') 656 p.chr(_OP_match_char, ',') 657 p.add(_OP_lspace) 658 p.chr(_OP_match_char, '"') 659 skip3 := p.pc() 660 p.rtt(op, vt) 661 662 /* match the value separator */ 663 p.add(_OP_lspace) 664 p.chr(_OP_match_char, ':') 665 self.compileOne(p, sp + 2, vt.Elem()) 666 p.pin(skip3) 667 p.add(_OP_load) 668 p.int(_OP_goto, k0) 669 p.pin(j) 670 p.pin(k1) 671 p.add(_OP_drop_2) 672 x := p.pc() 673 p.add(_OP_goto) 674 p.pin(i) 675 p.add(_OP_nil_1) 676 p.pin(skip) 677 p.pin(x) 678 } 679 680 func (self *_Compiler) compilePtr(p *_Program, sp int, et reflect.Type) { 681 i := p.pc() 682 p.add(_OP_is_null) 683 684 /* dereference all the way down */ 685 for et.Kind() == reflect.Ptr { 686 if et.Implements(jsonUnmarshalerType) { 687 p.rtt(_OP_unmarshal_p, et) 688 return 689 } 690 691 if et.Implements(encodingTextUnmarshalerType) { 692 p.add(_OP_lspace) 693 self.compileUnmarshalTextPtr(p, et) 694 return 695 } 696 697 et = et.Elem() 698 p.rtt(_OP_deref, et) 699 } 700 701 /* check for recursive nesting */ 702 ok := self.tab[et] 703 if ok { 704 p.rtt(_OP_recurse, et) 705 } else { 706 /* enter the recursion */ 707 p.add(_OP_lspace) 708 self.tab[et] = true 709 710 /* not inline the pointer type 711 * recursing the defined pointer type's elem will casue issue379. 712 */ 713 self.compileOps(p, sp, et) 714 } 715 delete(self.tab, et) 716 717 j := p.pc() 718 p.add(_OP_goto) 719 p.pin(i) 720 p.add(_OP_nil_1) 721 p.pin(j) 722 } 723 724 func (self *_Compiler) compileArray(p *_Program, sp int, vt reflect.Type) { 725 x := p.pc() 726 p.add(_OP_is_null) 727 p.tag(sp) 728 skip := self.checkIfSkip(p, vt, '[') 729 730 p.add(_OP_save) 731 p.add(_OP_lspace) 732 v := []int{p.pc()} 733 p.chr(_OP_check_char, ']') 734 735 /* decode every item */ 736 for i := 1; i <= vt.Len(); i++ { 737 self.compileOne(p, sp + 1, vt.Elem()) 738 p.add(_OP_load) 739 p.int(_OP_index, i * int(vt.Elem().Size())) 740 p.add(_OP_lspace) 741 v = append(v, p.pc()) 742 p.chr(_OP_check_char, ']') 743 p.chr(_OP_match_char, ',') 744 } 745 746 /* drop rest of the array */ 747 p.add(_OP_array_skip) 748 w := p.pc() 749 p.add(_OP_goto) 750 p.rel(v) 751 752 /* check for pointer data */ 753 if rt.UnpackType(vt.Elem()).PtrData == 0 { 754 p.int(_OP_array_clear, int(vt.Size())) 755 } else { 756 p.int(_OP_array_clear_p, int(vt.Size())) 757 } 758 759 /* restore the stack */ 760 p.pin(w) 761 p.add(_OP_drop) 762 763 p.pin(skip) 764 p.pin(x) 765 } 766 767 func (self *_Compiler) compileSlice(p *_Program, sp int, vt reflect.Type) { 768 if vt.Elem().Kind() == byteType.Kind() { 769 self.compileSliceBin(p, sp, vt) 770 } else { 771 self.compileSliceList(p, sp, vt) 772 } 773 } 774 775 func (self *_Compiler) compileSliceBin(p *_Program, sp int, vt reflect.Type) { 776 i := p.pc() 777 p.add(_OP_is_null) 778 j := p.pc() 779 p.chr(_OP_check_char, '[') 780 skip := self.checkIfSkip(p, vt, '"') 781 k := p.pc() 782 p.chr(_OP_check_char, '"') 783 p.add(_OP_bin) 784 x := p.pc() 785 p.add(_OP_goto) 786 p.pin(j) 787 self.compileSliceBody(p, sp, vt.Elem()) 788 y := p.pc() 789 p.add(_OP_goto) 790 p.pin(i) 791 p.pin(k) 792 p.add(_OP_nil_3) 793 p.pin(x) 794 p.pin(skip) 795 p.pin(y) 796 } 797 798 func (self *_Compiler) compileSliceList(p *_Program, sp int, vt reflect.Type) { 799 i := p.pc() 800 p.add(_OP_is_null) 801 p.tag(sp) 802 skip := self.checkIfSkip(p, vt, '[') 803 self.compileSliceBody(p, sp, vt.Elem()) 804 x := p.pc() 805 p.add(_OP_goto) 806 p.pin(i) 807 p.add(_OP_nil_3) 808 p.pin(x) 809 p.pin(skip) 810 } 811 812 func (self *_Compiler) compileSliceBody(p *_Program, sp int, et reflect.Type) { 813 p.add(_OP_lspace) 814 j := p.pc() 815 p.chr(_OP_check_empty, ']') 816 p.rtt(_OP_slice_init, et) 817 p.add(_OP_save) 818 p.rtt(_OP_slice_append, et) 819 self.compileOne(p, sp + 1, et) 820 p.add(_OP_load) 821 k0 := p.pc() 822 p.add(_OP_lspace) 823 k1 := p.pc() 824 p.chr(_OP_check_char, ']') 825 p.chr(_OP_match_char, ',') 826 p.rtt(_OP_slice_append, et) 827 self.compileOne(p, sp + 1, et) 828 p.add(_OP_load) 829 p.int(_OP_goto, k0) 830 p.pin(k1) 831 p.add(_OP_drop) 832 p.pin(j) 833 } 834 835 func (self *_Compiler) compileString(p *_Program, vt reflect.Type) { 836 if vt == jsonNumberType { 837 self.compilePrimitive(vt, p, _OP_num) 838 } else { 839 self.compileStringBody(vt, p) 840 } 841 } 842 843 func (self *_Compiler) compileStringBody(vt reflect.Type, p *_Program) { 844 i := p.pc() 845 p.add(_OP_is_null) 846 skip := self.checkIfSkip(p, vt, '"') 847 p.add(_OP_str) 848 p.pin(i) 849 p.pin(skip) 850 } 851 852 func (self *_Compiler) compileStruct(p *_Program, sp int, vt reflect.Type) { 853 if sp >= self.opts.MaxInlineDepth || p.pc() >= _MAX_ILBUF || (sp > 0 && vt.NumField() >= _MAX_FIELDS) { 854 p.rtt(_OP_recurse, vt) 855 if self.opts.RecursiveDepth > 0 { 856 self.rec[vt] = true 857 } 858 } else { 859 self.compileStructBody(p, sp, vt) 860 } 861 } 862 863 func (self *_Compiler) compileStructBody(p *_Program, sp int, vt reflect.Type) { 864 fv := resolver.ResolveStruct(vt) 865 fm, sw := caching.CreateFieldMap(len(fv)), make([]int, len(fv)) 866 867 /* start of object */ 868 p.tag(sp) 869 n := p.pc() 870 p.add(_OP_is_null) 871 872 skip := self.checkIfSkip(p, vt, '{') 873 874 p.add(_OP_save) 875 p.add(_OP_lspace) 876 x := p.pc() 877 p.chr(_OP_check_char, '}') 878 p.chr(_OP_match_char, '"') 879 p.fmv(_OP_struct_field, fm) 880 p.add(_OP_lspace) 881 p.chr(_OP_match_char, ':') 882 p.tab(_OP_switch, sw) 883 p.add(_OP_object_next) 884 y0 := p.pc() 885 p.add(_OP_lspace) 886 y1 := p.pc() 887 p.chr(_OP_check_char, '}') 888 p.chr(_OP_match_char, ',') 889 890 /* special case of an empty struct */ 891 if len(fv) == 0 { 892 p.add(_OP_object_skip) 893 goto end_of_object 894 } 895 896 /* match the remaining fields */ 897 p.add(_OP_lspace) 898 p.chr(_OP_match_char, '"') 899 p.fmv(_OP_struct_field, fm) 900 p.add(_OP_lspace) 901 p.chr(_OP_match_char, ':') 902 p.tab(_OP_switch, sw) 903 p.add(_OP_object_next) 904 p.int(_OP_goto, y0) 905 906 /* process each field */ 907 for i, f := range fv { 908 sw[i] = p.pc() 909 fm.Set(f.Name, i) 910 911 /* index to the field */ 912 for _, o := range f.Path { 913 if p.int(_OP_index, int(o.Size)); o.Kind == resolver.F_deref { 914 p.rtt(_OP_deref, o.Type) 915 } 916 } 917 918 /* check for "stringnize" option */ 919 if (f.Opts & resolver.F_stringize) == 0 { 920 self.compileOne(p, sp + 1, f.Type) 921 } else { 922 self.compileStructFieldStr(p, sp + 1, f.Type) 923 } 924 925 /* load the state, and try next field */ 926 p.add(_OP_load) 927 p.int(_OP_goto, y0) 928 } 929 930 end_of_object: 931 p.pin(x) 932 p.pin(y1) 933 p.add(_OP_drop) 934 p.pin(n) 935 p.pin(skip) 936 } 937 938 func (self *_Compiler) compileStructFieldStr(p *_Program, sp int, vt reflect.Type) { 939 n1 := -1 940 ft := vt 941 sv := false 942 943 /* dereference the pointer if needed */ 944 if ft.Kind() == reflect.Ptr { 945 ft = ft.Elem() 946 } 947 948 /* check if it can be stringized */ 949 switch ft.Kind() { 950 case reflect.Bool : sv = true 951 case reflect.Int : sv = true 952 case reflect.Int8 : sv = true 953 case reflect.Int16 : sv = true 954 case reflect.Int32 : sv = true 955 case reflect.Int64 : sv = true 956 case reflect.Uint : sv = true 957 case reflect.Uint8 : sv = true 958 case reflect.Uint16 : sv = true 959 case reflect.Uint32 : sv = true 960 case reflect.Uint64 : sv = true 961 case reflect.Uintptr : sv = true 962 case reflect.Float32 : sv = true 963 case reflect.Float64 : sv = true 964 case reflect.String : sv = true 965 } 966 967 /* if it's not, ignore the "string" and follow the regular path */ 968 if !sv { 969 self.compileOne(p, sp, vt) 970 return 971 } 972 973 /* remove the leading space, and match the leading quote */ 974 vk := vt.Kind() 975 p.add(_OP_lspace) 976 n0 := p.pc() 977 p.add(_OP_is_null) 978 979 skip := self.checkIfSkip(p, stringType, '"') 980 981 /* also check for inner "null" */ 982 n1 = p.pc() 983 p.add(_OP_is_null_quote) 984 985 /* dereference the pointer only when it is not null */ 986 if vk == reflect.Ptr { 987 vt = vt.Elem() 988 p.rtt(_OP_deref, vt) 989 } 990 991 n2 := p.pc() 992 p.chr(_OP_check_char_0, '"') 993 994 /* string opcode selector */ 995 _OP_string := func() _Op { 996 if ft == jsonNumberType { 997 return _OP_num 998 } else { 999 return _OP_unquote 1000 } 1001 } 1002 1003 /* compile for each type */ 1004 switch vt.Kind() { 1005 case reflect.Bool : p.add(_OP_bool) 1006 case reflect.Int : p.add(_OP_int()) 1007 case reflect.Int8 : p.add(_OP_i8) 1008 case reflect.Int16 : p.add(_OP_i16) 1009 case reflect.Int32 : p.add(_OP_i32) 1010 case reflect.Int64 : p.add(_OP_i64) 1011 case reflect.Uint : p.add(_OP_uint()) 1012 case reflect.Uint8 : p.add(_OP_u8) 1013 case reflect.Uint16 : p.add(_OP_u16) 1014 case reflect.Uint32 : p.add(_OP_u32) 1015 case reflect.Uint64 : p.add(_OP_u64) 1016 case reflect.Uintptr : p.add(_OP_uintptr()) 1017 case reflect.Float32 : p.add(_OP_f32) 1018 case reflect.Float64 : p.add(_OP_f64) 1019 case reflect.String : p.add(_OP_string()) 1020 default : panic("not reachable") 1021 } 1022 1023 /* the closing quote is not needed when parsing a pure string */ 1024 if vt == jsonNumberType || vt.Kind() != reflect.String { 1025 p.chr(_OP_match_char, '"') 1026 } 1027 1028 /* pin the `is_null_quote` jump location */ 1029 if n1 != -1 && vk != reflect.Ptr { 1030 p.pin(n1) 1031 } 1032 1033 /* "null" but not a pointer, act as if the field is not present */ 1034 if vk != reflect.Ptr { 1035 pc2 := p.pc() 1036 p.add(_OP_goto) 1037 p.pin(n2) 1038 p.rtt(_OP_dismatch_err, vt) 1039 p.int(_OP_add, 1) 1040 p.pin(pc2) 1041 p.pin(n0) 1042 return 1043 } 1044 1045 /* the "null" case of the pointer */ 1046 pc := p.pc() 1047 p.add(_OP_goto) 1048 p.pin(n0) // `is_null` jump location 1049 p.pin(n1) // `is_null_quote` jump location 1050 p.add(_OP_nil_1) 1051 pc2 := p.pc() 1052 p.add(_OP_goto) 1053 p.pin(n2) 1054 p.rtt(_OP_dismatch_err, vt) 1055 p.int(_OP_add, 1) 1056 p.pin(pc) 1057 p.pin(pc2) 1058 p.pin(skip) 1059 } 1060 1061 func (self *_Compiler) compileInterface(p *_Program, vt reflect.Type) { 1062 i := p.pc() 1063 p.add(_OP_is_null) 1064 1065 /* check for empty interface */ 1066 if vt.NumMethod() == 0 { 1067 p.add(_OP_any) 1068 } else { 1069 p.rtt(_OP_dyn, vt) 1070 } 1071 1072 /* finish the OpCode */ 1073 j := p.pc() 1074 p.add(_OP_goto) 1075 p.pin(i) 1076 p.add(_OP_nil_2) 1077 p.pin(j) 1078 } 1079 1080 func (self *_Compiler) compilePrimitive(vt reflect.Type, p *_Program, op _Op) { 1081 i := p.pc() 1082 p.add(_OP_is_null) 1083 // skip := self.checkPrimitive(p, vt) 1084 p.add(op) 1085 p.pin(i) 1086 // p.pin(skip) 1087 } 1088 1089 func (self *_Compiler) compileUnmarshalEnd(p *_Program, vt reflect.Type, i int) { 1090 j := p.pc() 1091 k := vt.Kind() 1092 1093 /* not a pointer */ 1094 if k != reflect.Ptr { 1095 p.pin(i) 1096 return 1097 } 1098 1099 /* it seems that in Go JSON library, "null" takes priority over any kind of unmarshaler */ 1100 p.add(_OP_goto) 1101 p.pin(i) 1102 p.add(_OP_nil_1) 1103 p.pin(j) 1104 } 1105 1106 func (self *_Compiler) compileUnmarshalJson(p *_Program, vt reflect.Type) { 1107 i := p.pc() 1108 v := _OP_unmarshal 1109 p.add(_OP_is_null) 1110 1111 /* check for dynamic interface */ 1112 if vt.Kind() == reflect.Interface { 1113 v = _OP_dyn 1114 } 1115 1116 /* call the unmarshaler */ 1117 p.rtt(v, vt) 1118 self.compileUnmarshalEnd(p, vt, i) 1119 } 1120 1121 func (self *_Compiler) compileUnmarshalText(p *_Program, vt reflect.Type) { 1122 i := p.pc() 1123 v := _OP_unmarshal_text 1124 p.add(_OP_is_null) 1125 1126 /* check for dynamic interface */ 1127 if vt.Kind() == reflect.Interface { 1128 v = _OP_dyn 1129 } else { 1130 p.chr(_OP_match_char, '"') 1131 } 1132 1133 /* call the unmarshaler */ 1134 p.rtt(v, vt) 1135 self.compileUnmarshalEnd(p, vt, i) 1136 } 1137 1138 func (self *_Compiler) compileUnmarshalTextPtr(p *_Program, vt reflect.Type) { 1139 i := p.pc() 1140 p.add(_OP_is_null) 1141 p.chr(_OP_match_char, '"') 1142 p.rtt(_OP_unmarshal_text_p, vt) 1143 p.pin(i) 1144 } 1145 1146 func (self *_Compiler) checkIfSkip(p *_Program, vt reflect.Type, c byte) int { 1147 j := p.pc() 1148 p.chr(_OP_check_char_0, c) 1149 p.rtt(_OP_dismatch_err, vt) 1150 s := p.pc() 1151 p.add(_OP_go_skip) 1152 p.pin(j) 1153 p.int(_OP_add, 1) 1154 return s 1155 }