compiler.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  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. package encoder
  17. import (
  18. "reflect"
  19. "unsafe"
  20. "github.com/bytedance/sonic/internal/encoder/ir"
  21. "github.com/bytedance/sonic/internal/encoder/vars"
  22. "github.com/bytedance/sonic/internal/encoder/vm"
  23. "github.com/bytedance/sonic/internal/resolver"
  24. "github.com/bytedance/sonic/internal/rt"
  25. "github.com/bytedance/sonic/option"
  26. )
  27. func ForceUseVM() {
  28. vm.SetCompiler(makeEncoderVM)
  29. pretouchType = pretouchTypeVM
  30. encodeTypedPointer = vm.EncodeTypedPointer
  31. vars.UseVM = true
  32. }
  33. var encodeTypedPointer func(buf *[]byte, vt *rt.GoType, vp *unsafe.Pointer, sb *vars.Stack, fv uint64) error
  34. func makeEncoderVM(vt *rt.GoType, ex ...interface{}) (interface{}, error) {
  35. pp, err := NewCompiler().Compile(vt.Pack(), ex[0].(bool))
  36. if err != nil {
  37. return nil, err
  38. }
  39. return &pp, nil
  40. }
  41. var pretouchType func(_vt reflect.Type, opts option.CompileOptions, v uint8) (map[reflect.Type]uint8, error)
  42. func pretouchTypeVM(_vt reflect.Type, opts option.CompileOptions, v uint8) (map[reflect.Type]uint8, error) {
  43. /* compile function */
  44. compiler := NewCompiler().apply(opts)
  45. /* find or compile */
  46. vt := rt.UnpackType(_vt)
  47. if val := vars.GetProgram(vt); val != nil {
  48. return nil, nil
  49. } else if _, err := vars.ComputeProgram(vt, makeEncoderVM, v == 1); err == nil {
  50. return compiler.rec, nil
  51. } else {
  52. return nil, err
  53. }
  54. }
  55. func pretouchRec(vtm map[reflect.Type]uint8, opts option.CompileOptions) error {
  56. if opts.RecursiveDepth < 0 || len(vtm) == 0 {
  57. return nil
  58. }
  59. next := make(map[reflect.Type]uint8)
  60. for vt, v := range vtm {
  61. sub, err := pretouchType(vt, opts, v)
  62. if err != nil {
  63. return err
  64. }
  65. for svt, v := range sub {
  66. next[svt] = v
  67. }
  68. }
  69. opts.RecursiveDepth -= 1
  70. return pretouchRec(next, opts)
  71. }
  72. type Compiler struct {
  73. opts option.CompileOptions
  74. pv bool
  75. tab map[reflect.Type]bool
  76. rec map[reflect.Type]uint8
  77. }
  78. func NewCompiler() *Compiler {
  79. return &Compiler{
  80. opts: option.DefaultCompileOptions(),
  81. tab: map[reflect.Type]bool{},
  82. rec: map[reflect.Type]uint8{},
  83. }
  84. }
  85. func (self *Compiler) apply(opts option.CompileOptions) *Compiler {
  86. self.opts = opts
  87. if self.opts.RecursiveDepth > 0 {
  88. self.rec = map[reflect.Type]uint8{}
  89. }
  90. return self
  91. }
  92. func (self *Compiler) rescue(ep *error) {
  93. if val := recover(); val != nil {
  94. if err, ok := val.(error); ok {
  95. *ep = err
  96. } else {
  97. panic(val)
  98. }
  99. }
  100. }
  101. func (self *Compiler) Compile(vt reflect.Type, pv bool) (ret ir.Program, err error) {
  102. defer self.rescue(&err)
  103. self.compileOne(&ret, 0, vt, pv)
  104. return
  105. }
  106. func (self *Compiler) compileOne(p *ir.Program, sp int, vt reflect.Type, pv bool) {
  107. if self.tab[vt] {
  108. p.Vp(ir.OP_recurse, vt, pv)
  109. } else {
  110. self.compileRec(p, sp, vt, pv)
  111. }
  112. }
  113. func (self *Compiler) tryCompileMarshaler(p *ir.Program, vt reflect.Type, pv bool) bool {
  114. pt := reflect.PtrTo(vt)
  115. /* check for addressable `json.Marshaler` with pointer receiver */
  116. if pv && pt.Implements(vars.JsonMarshalerType) {
  117. addMarshalerOp(p, ir.OP_marshal_p, pt, vars.JsonMarshalerType)
  118. return true
  119. }
  120. /* check for `json.Marshaler` */
  121. if vt.Implements(vars.JsonMarshalerType) {
  122. self.compileMarshaler(p, ir.OP_marshal, vt, vars.JsonMarshalerType)
  123. return true
  124. }
  125. /* check for addressable `encoding.TextMarshaler` with pointer receiver */
  126. if pv && pt.Implements(vars.EncodingTextMarshalerType) {
  127. addMarshalerOp(p, ir.OP_marshal_text_p, pt, vars.EncodingTextMarshalerType)
  128. return true
  129. }
  130. /* check for `encoding.TextMarshaler` */
  131. if vt.Implements(vars.EncodingTextMarshalerType) {
  132. self.compileMarshaler(p, ir.OP_marshal_text, vt, vars.EncodingTextMarshalerType)
  133. return true
  134. }
  135. return false
  136. }
  137. func (self *Compiler) compileRec(p *ir.Program, sp int, vt reflect.Type, pv bool) {
  138. pr := self.pv
  139. if self.tryCompileMarshaler(p, vt, pv) {
  140. return
  141. }
  142. /* enter the recursion, and compile the type */
  143. self.pv = pv
  144. self.tab[vt] = true
  145. self.compileOps(p, sp, vt)
  146. /* exit the recursion */
  147. self.pv = pr
  148. delete(self.tab, vt)
  149. }
  150. func (self *Compiler) compileOps(p *ir.Program, sp int, vt reflect.Type) {
  151. switch vt.Kind() {
  152. case reflect.Bool:
  153. p.Add(ir.OP_bool)
  154. case reflect.Int:
  155. p.Add(ir.OP_int())
  156. case reflect.Int8:
  157. p.Add(ir.OP_i8)
  158. case reflect.Int16:
  159. p.Add(ir.OP_i16)
  160. case reflect.Int32:
  161. p.Add(ir.OP_i32)
  162. case reflect.Int64:
  163. p.Add(ir.OP_i64)
  164. case reflect.Uint:
  165. p.Add(ir.OP_uint())
  166. case reflect.Uint8:
  167. p.Add(ir.OP_u8)
  168. case reflect.Uint16:
  169. p.Add(ir.OP_u16)
  170. case reflect.Uint32:
  171. p.Add(ir.OP_u32)
  172. case reflect.Uint64:
  173. p.Add(ir.OP_u64)
  174. case reflect.Uintptr:
  175. p.Add(ir.OP_uintptr())
  176. case reflect.Float32:
  177. p.Add(ir.OP_f32)
  178. case reflect.Float64:
  179. p.Add(ir.OP_f64)
  180. case reflect.String:
  181. self.compileString(p, vt)
  182. case reflect.Array:
  183. self.compileArray(p, sp, vt.Elem(), vt.Len())
  184. case reflect.Interface:
  185. self.compileInterface(p, vt)
  186. case reflect.Map:
  187. self.compileMap(p, sp, vt)
  188. case reflect.Ptr:
  189. self.compilePtr(p, sp, vt.Elem())
  190. case reflect.Slice:
  191. self.compileSlice(p, sp, vt.Elem())
  192. case reflect.Struct:
  193. self.compileStruct(p, sp, vt)
  194. default:
  195. self.compileUnsupportedType(p, vt)
  196. }
  197. }
  198. func (self *Compiler) compileNil(p *ir.Program, sp int, vt reflect.Type, nil_op ir.Op, fn func(*ir.Program, int, reflect.Type)) {
  199. x := p.PC()
  200. p.Add(ir.OP_is_nil)
  201. fn(p, sp, vt)
  202. e := p.PC()
  203. p.Add(ir.OP_goto)
  204. p.Pin(x)
  205. p.Add(nil_op)
  206. p.Pin(e)
  207. }
  208. func (self *Compiler) compilePtr(p *ir.Program, sp int, vt reflect.Type) {
  209. self.compileNil(p, sp, vt, ir.OP_null, self.compilePtrBody)
  210. }
  211. func (self *Compiler) compilePtrBody(p *ir.Program, sp int, vt reflect.Type) {
  212. p.Tag(sp)
  213. p.Add(ir.OP_save)
  214. p.Add(ir.OP_deref)
  215. self.compileOne(p, sp+1, vt, true)
  216. p.Add(ir.OP_drop)
  217. }
  218. func (self *Compiler) compileMap(p *ir.Program, sp int, vt reflect.Type) {
  219. self.compileNil(p, sp, vt, ir.OP_empty_obj, self.compileMapBody)
  220. }
  221. func (self *Compiler) compileMapBody(p *ir.Program, sp int, vt reflect.Type) {
  222. p.Tag(sp + 1)
  223. p.Int(ir.OP_byte, '{')
  224. e := p.PC()
  225. p.Add(ir.OP_is_zero_map)
  226. p.Add(ir.OP_save)
  227. p.Rtt(ir.OP_map_iter, vt)
  228. p.Add(ir.OP_save)
  229. i := p.PC()
  230. p.Add(ir.OP_map_check_key)
  231. u := p.PC()
  232. p.Add(ir.OP_map_write_key)
  233. self.compileMapBodyKey(p, vt.Key())
  234. p.Pin(u)
  235. p.Int(ir.OP_byte, ':')
  236. p.Add(ir.OP_map_value_next)
  237. self.compileOne(p, sp+2, vt.Elem(), false)
  238. j := p.PC()
  239. p.Add(ir.OP_map_check_key)
  240. p.Int(ir.OP_byte, ',')
  241. v := p.PC()
  242. p.Add(ir.OP_map_write_key)
  243. self.compileMapBodyKey(p, vt.Key())
  244. p.Pin(v)
  245. p.Int(ir.OP_byte, ':')
  246. p.Add(ir.OP_map_value_next)
  247. self.compileOne(p, sp+2, vt.Elem(), false)
  248. p.Int(ir.OP_goto, j)
  249. p.Pin(i)
  250. p.Pin(j)
  251. p.Add(ir.OP_map_stop)
  252. p.Add(ir.OP_drop_2)
  253. p.Pin(e)
  254. p.Int(ir.OP_byte, '}')
  255. }
  256. func (self *Compiler) compileMapBodyKey(p *ir.Program, vk reflect.Type) {
  257. if !vk.Implements(vars.EncodingTextMarshalerType) {
  258. self.compileMapBodyTextKey(p, vk)
  259. } else {
  260. self.compileMapBodyUtextKey(p, vk)
  261. }
  262. }
  263. func (self *Compiler) compileMapBodyTextKey(p *ir.Program, vk reflect.Type) {
  264. switch vk.Kind() {
  265. case reflect.Invalid:
  266. panic("map key is nil")
  267. case reflect.Bool:
  268. p.Key(ir.OP_bool)
  269. case reflect.Int:
  270. p.Key(ir.OP_int())
  271. case reflect.Int8:
  272. p.Key(ir.OP_i8)
  273. case reflect.Int16:
  274. p.Key(ir.OP_i16)
  275. case reflect.Int32:
  276. p.Key(ir.OP_i32)
  277. case reflect.Int64:
  278. p.Key(ir.OP_i64)
  279. case reflect.Uint:
  280. p.Key(ir.OP_uint())
  281. case reflect.Uint8:
  282. p.Key(ir.OP_u8)
  283. case reflect.Uint16:
  284. p.Key(ir.OP_u16)
  285. case reflect.Uint32:
  286. p.Key(ir.OP_u32)
  287. case reflect.Uint64:
  288. p.Key(ir.OP_u64)
  289. case reflect.Uintptr:
  290. p.Key(ir.OP_uintptr())
  291. case reflect.Float32:
  292. p.Key(ir.OP_f32)
  293. case reflect.Float64:
  294. p.Key(ir.OP_f64)
  295. case reflect.String:
  296. self.compileString(p, vk)
  297. default:
  298. panic(vars.Error_type(vk))
  299. }
  300. }
  301. func (self *Compiler) compileMapBodyUtextKey(p *ir.Program, vk reflect.Type) {
  302. if vk.Kind() != reflect.Ptr {
  303. addMarshalerOp(p, ir.OP_marshal_text, vk, vars.EncodingTextMarshalerType)
  304. } else {
  305. self.compileMapBodyUtextPtr(p, vk)
  306. }
  307. }
  308. func (self *Compiler) compileMapBodyUtextPtr(p *ir.Program, vk reflect.Type) {
  309. i := p.PC()
  310. p.Add(ir.OP_is_nil)
  311. addMarshalerOp(p, ir.OP_marshal_text, vk, vars.EncodingTextMarshalerType)
  312. j := p.PC()
  313. p.Add(ir.OP_goto)
  314. p.Pin(i)
  315. p.Str(ir.OP_text, "\"\"")
  316. p.Pin(j)
  317. }
  318. func (self *Compiler) compileSlice(p *ir.Program, sp int, vt reflect.Type) {
  319. self.compileNil(p, sp, vt, ir.OP_empty_arr, self.compileSliceBody)
  320. }
  321. func (self *Compiler) compileSliceBody(p *ir.Program, sp int, vt reflect.Type) {
  322. if vars.IsSimpleByte(vt) {
  323. p.Add(ir.OP_bin)
  324. } else {
  325. self.compileSliceArray(p, sp, vt)
  326. }
  327. }
  328. func (self *Compiler) compileSliceArray(p *ir.Program, sp int, vt reflect.Type) {
  329. p.Tag(sp)
  330. p.Int(ir.OP_byte, '[')
  331. e := p.PC()
  332. p.Add(ir.OP_is_nil)
  333. p.Add(ir.OP_save)
  334. p.Add(ir.OP_slice_len)
  335. i := p.PC()
  336. p.Rtt(ir.OP_slice_next, vt)
  337. self.compileOne(p, sp+1, vt, true)
  338. j := p.PC()
  339. p.Rtt(ir.OP_slice_next, vt)
  340. p.Int(ir.OP_byte, ',')
  341. self.compileOne(p, sp+1, vt, true)
  342. p.Int(ir.OP_goto, j)
  343. p.Pin(i)
  344. p.Pin(j)
  345. p.Add(ir.OP_drop)
  346. p.Pin(e)
  347. p.Int(ir.OP_byte, ']')
  348. }
  349. func (self *Compiler) compileArray(p *ir.Program, sp int, vt reflect.Type, nb int) {
  350. p.Tag(sp)
  351. p.Int(ir.OP_byte, '[')
  352. p.Add(ir.OP_save)
  353. /* first item */
  354. if nb != 0 {
  355. self.compileOne(p, sp+1, vt, self.pv)
  356. p.Add(ir.OP_load)
  357. }
  358. /* remaining items */
  359. for i := 1; i < nb; i++ {
  360. p.Int(ir.OP_byte, ',')
  361. p.Int(ir.OP_index, i*int(vt.Size()))
  362. self.compileOne(p, sp+1, vt, self.pv)
  363. p.Add(ir.OP_load)
  364. }
  365. /* end of array */
  366. p.Add(ir.OP_drop)
  367. p.Int(ir.OP_byte, ']')
  368. }
  369. func (self *Compiler) compileString(p *ir.Program, vt reflect.Type) {
  370. if vt != vars.JsonNumberType {
  371. p.Add(ir.OP_str)
  372. } else {
  373. p.Add(ir.OP_number)
  374. }
  375. }
  376. func (self *Compiler) compileStruct(p *ir.Program, sp int, vt reflect.Type) {
  377. if sp >= self.opts.MaxInlineDepth || p.PC() >= vars.MAX_ILBUF || (sp > 0 && vt.NumField() >= vars.MAX_FIELDS) {
  378. p.Vp(ir.OP_recurse, vt, self.pv)
  379. if self.opts.RecursiveDepth > 0 {
  380. if self.pv {
  381. self.rec[vt] = 1
  382. } else {
  383. self.rec[vt] = 0
  384. }
  385. }
  386. } else {
  387. self.compileStructBody(p, sp, vt)
  388. }
  389. }
  390. func (self *Compiler) compileStructBody(p *ir.Program, sp int, vt reflect.Type) {
  391. p.Tag(sp)
  392. p.Int(ir.OP_byte, '{')
  393. p.Add(ir.OP_save)
  394. p.Add(ir.OP_cond_set)
  395. /* compile each field */
  396. fvs := resolver.ResolveStruct(vt)
  397. for i, fv := range fvs {
  398. var s []int
  399. var o resolver.Offset
  400. /* "omitempty" for arrays */
  401. if fv.Type.Kind() == reflect.Array {
  402. if fv.Type.Len() == 0 && (fv.Opts&resolver.F_omitempty) != 0 {
  403. continue
  404. }
  405. }
  406. /* index to the field */
  407. for _, o = range fv.Path {
  408. if p.Int(ir.OP_index, int(o.Size)); o.Kind == resolver.F_deref {
  409. s = append(s, p.PC())
  410. p.Add(ir.OP_is_nil)
  411. p.Add(ir.OP_deref)
  412. }
  413. }
  414. /* check for "omitempty" option */
  415. if fv.Type.Kind() != reflect.Struct && fv.Type.Kind() != reflect.Array && (fv.Opts&resolver.F_omitempty) != 0 {
  416. s = append(s, p.PC())
  417. self.compileStructFieldEmpty(p, fv.Type)
  418. }
  419. /* check for "omitzero" option */
  420. if fv.Opts&resolver.F_omitzero != 0 {
  421. s = append(s, p.PC())
  422. p.VField(ir.OP_is_zero, &fvs[i])
  423. }
  424. /* add the comma if not the first element */
  425. i := p.PC()
  426. p.Add(ir.OP_cond_testc)
  427. p.Int(ir.OP_byte, ',')
  428. p.Pin(i)
  429. /* compile the key and value */
  430. ft := fv.Type
  431. p.Str(ir.OP_text, Quote(fv.Name)+":")
  432. /* check for "stringnize" option */
  433. if (fv.Opts & resolver.F_stringize) == 0 {
  434. self.compileOne(p, sp+1, ft, self.pv)
  435. } else {
  436. self.compileStructFieldStr(p, sp+1, ft)
  437. }
  438. /* patch the skipping jumps and reload the struct pointer */
  439. p.Rel(s)
  440. p.Add(ir.OP_load)
  441. }
  442. /* end of object */
  443. p.Add(ir.OP_drop)
  444. p.Int(ir.OP_byte, '}')
  445. }
  446. func (self *Compiler) compileStructFieldStr(p *ir.Program, sp int, vt reflect.Type) {
  447. // NOTICE: according to encoding/json, Marshaler type has higher priority than string option
  448. // see issue:
  449. if self.tryCompileMarshaler(p, vt, self.pv) {
  450. return
  451. }
  452. pc := -1
  453. ft := vt
  454. sv := false
  455. /* dereference the pointer if needed */
  456. if ft.Kind() == reflect.Ptr {
  457. ft = ft.Elem()
  458. }
  459. /* check if it can be stringized */
  460. switch ft.Kind() {
  461. case reflect.Bool:
  462. sv = true
  463. case reflect.Int:
  464. sv = true
  465. case reflect.Int8:
  466. sv = true
  467. case reflect.Int16:
  468. sv = true
  469. case reflect.Int32:
  470. sv = true
  471. case reflect.Int64:
  472. sv = true
  473. case reflect.Uint:
  474. sv = true
  475. case reflect.Uint8:
  476. sv = true
  477. case reflect.Uint16:
  478. sv = true
  479. case reflect.Uint32:
  480. sv = true
  481. case reflect.Uint64:
  482. sv = true
  483. case reflect.Uintptr:
  484. sv = true
  485. case reflect.Float32:
  486. sv = true
  487. case reflect.Float64:
  488. sv = true
  489. case reflect.String:
  490. sv = true
  491. }
  492. /* if it's not, ignore the "string" and follow the regular path */
  493. if !sv {
  494. self.compileOne(p, sp, vt, self.pv)
  495. return
  496. }
  497. /* dereference the pointer */
  498. if vt.Kind() == reflect.Ptr {
  499. pc = p.PC()
  500. vt = vt.Elem()
  501. p.Add(ir.OP_is_nil)
  502. p.Add(ir.OP_deref)
  503. }
  504. /* special case of a double-quoted string */
  505. if ft != vars.JsonNumberType && ft.Kind() == reflect.String {
  506. p.Add(ir.OP_quote)
  507. } else {
  508. self.compileStructFieldQuoted(p, sp, vt)
  509. }
  510. /* the "null" case of the pointer */
  511. if pc != -1 {
  512. e := p.PC()
  513. p.Add(ir.OP_goto)
  514. p.Pin(pc)
  515. p.Add(ir.OP_null)
  516. p.Pin(e)
  517. }
  518. }
  519. func (self *Compiler) compileStructFieldEmpty(p *ir.Program, vt reflect.Type) {
  520. switch vt.Kind() {
  521. case reflect.Bool:
  522. p.Add(ir.OP_is_zero_1)
  523. case reflect.Int:
  524. p.Add(ir.OP_is_zero_ints())
  525. case reflect.Int8:
  526. p.Add(ir.OP_is_zero_1)
  527. case reflect.Int16:
  528. p.Add(ir.OP_is_zero_2)
  529. case reflect.Int32:
  530. p.Add(ir.OP_is_zero_4)
  531. case reflect.Int64:
  532. p.Add(ir.OP_is_zero_8)
  533. case reflect.Uint:
  534. p.Add(ir.OP_is_zero_ints())
  535. case reflect.Uint8:
  536. p.Add(ir.OP_is_zero_1)
  537. case reflect.Uint16:
  538. p.Add(ir.OP_is_zero_2)
  539. case reflect.Uint32:
  540. p.Add(ir.OP_is_zero_4)
  541. case reflect.Uint64:
  542. p.Add(ir.OP_is_zero_8)
  543. case reflect.Uintptr:
  544. p.Add(ir.OP_is_nil)
  545. case reflect.Float32:
  546. p.Add(ir.OP_is_zero_4)
  547. case reflect.Float64:
  548. p.Add(ir.OP_is_zero_8)
  549. case reflect.String:
  550. p.Add(ir.OP_is_nil_p1)
  551. case reflect.Interface:
  552. p.Add(ir.OP_is_nil)
  553. case reflect.Map:
  554. p.Add(ir.OP_is_zero_map)
  555. case reflect.Ptr:
  556. p.Add(ir.OP_is_nil)
  557. case reflect.Slice:
  558. p.Add(ir.OP_is_nil_p1)
  559. default:
  560. panic(vars.Error_type(vt))
  561. }
  562. }
  563. func (self *Compiler) compileStructFieldQuoted(p *ir.Program, sp int, vt reflect.Type) {
  564. p.Int(ir.OP_byte, '"')
  565. self.compileOne(p, sp, vt, self.pv)
  566. p.Int(ir.OP_byte, '"')
  567. }
  568. func (self *Compiler) compileInterface(p *ir.Program, vt reflect.Type) {
  569. /* iface and efaces are different */
  570. if vt.NumMethod() == 0 {
  571. p.Add(ir.OP_eface)
  572. return
  573. }
  574. x := p.PC()
  575. p.Add(ir.OP_is_nil_p1)
  576. p.Add(ir.OP_iface)
  577. /* the "null" value */
  578. e := p.PC()
  579. p.Add(ir.OP_goto)
  580. p.Pin(x)
  581. p.Add(ir.OP_null)
  582. p.Pin(e)
  583. }
  584. func (self *Compiler) compileUnsupportedType(p *ir.Program, vt reflect.Type) {
  585. p.Rtt(ir.OP_unsupported, vt)
  586. }
  587. func (self *Compiler) compileMarshaler(p *ir.Program, op ir.Op, vt reflect.Type, mt reflect.Type) {
  588. pc := p.PC()
  589. vk := vt.Kind()
  590. /* direct receiver */
  591. if vk != reflect.Ptr {
  592. addMarshalerOp(p, op, vt, mt)
  593. return
  594. }
  595. /* value receiver with a pointer type, check for nil before calling the marshaler */
  596. p.Add(ir.OP_is_nil)
  597. addMarshalerOp(p, op, vt, mt)
  598. i := p.PC()
  599. p.Add(ir.OP_goto)
  600. p.Pin(pc)
  601. p.Add(ir.OP_null)
  602. p.Pin(i)
  603. }
  604. func addMarshalerOp(p *ir.Program, op ir.Op, vt reflect.Type, mt reflect.Type) {
  605. if vars.UseVM {
  606. itab := rt.GetItab(rt.IfaceType(rt.UnpackType(mt)), rt.UnpackType(vt), true)
  607. p.Vtab(op, vt, itab)
  608. } else {
  609. // OPT: get itab here
  610. p.Rtt(op, vt)
  611. }
  612. }