generic_stkabi_amd64.go 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. // +build go1.16,!go1.17
  2. /*
  3. * Copyright 2021 ByteDance Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package decoder
  18. import (
  19. `encoding/json`
  20. `fmt`
  21. `reflect`
  22. `github.com/bytedance/sonic/internal/jit`
  23. `github.com/bytedance/sonic/internal/native`
  24. `github.com/bytedance/sonic/internal/native/types`
  25. `github.com/twitchyliquid64/golang-asm/obj`
  26. )
  27. /** Crucial Registers:
  28. *
  29. * ST(BX) : ro, decoder stack
  30. * DF(R10) : ro, decoder flags
  31. * EP(R11) : wo, error pointer
  32. * IP(R12) : ro, input pointer
  33. * IL(R13) : ro, input length
  34. * IC(R14) : rw, input cursor
  35. * VP(R15) : ro, value pointer (to an interface{})
  36. */
  37. const (
  38. _VD_args = 8 // 8 bytes for passing arguments to this functions
  39. _VD_fargs = 64 // 64 bytes for passing arguments to other Go functions
  40. _VD_saves = 40 // 40 bytes for saving the registers before CALL instructions
  41. _VD_locals = 88 // 88 bytes for local variables
  42. )
  43. const (
  44. _VD_offs = _VD_fargs + _VD_saves + _VD_locals
  45. _VD_size = _VD_offs + 8 // 8 bytes for the parent frame pointer
  46. )
  47. var (
  48. _VAR_ss = _VAR_ss_Vt
  49. _VAR_df = jit.Ptr(_SP, _VD_fargs + _VD_saves)
  50. )
  51. var (
  52. _VAR_ss_Vt = jit.Ptr(_SP, _VD_fargs + _VD_saves + 8)
  53. _VAR_ss_Dv = jit.Ptr(_SP, _VD_fargs + _VD_saves + 16)
  54. _VAR_ss_Iv = jit.Ptr(_SP, _VD_fargs + _VD_saves + 24)
  55. _VAR_ss_Ep = jit.Ptr(_SP, _VD_fargs + _VD_saves + 32)
  56. _VAR_ss_Db = jit.Ptr(_SP, _VD_fargs + _VD_saves + 40)
  57. _VAR_ss_Dc = jit.Ptr(_SP, _VD_fargs + _VD_saves + 48)
  58. )
  59. var (
  60. _VAR_cs_LR = jit.Ptr(_SP, _VD_fargs + _VD_saves + 56)
  61. _VAR_cs_p = jit.Ptr(_SP, _VD_fargs + _VD_saves + 64)
  62. _VAR_cs_n = jit.Ptr(_SP, _VD_fargs + _VD_saves + 72)
  63. _VAR_cs_d = jit.Ptr(_SP, _VD_fargs + _VD_saves + 80)
  64. )
  65. type _ValueDecoder struct {
  66. jit.BaseAssembler
  67. }
  68. func (self *_ValueDecoder) build() uintptr {
  69. self.Init(self.compile)
  70. return *(*uintptr)(self.Load("decode_value", _VD_size, _VD_args, argPtrs_generic, localPtrs_generic))
  71. }
  72. /** Function Calling Helpers **/
  73. func (self *_ValueDecoder) save(r ...obj.Addr) {
  74. for i, v := range r {
  75. if i > _VD_saves / 8 - 1 {
  76. panic("too many registers to save")
  77. } else {
  78. self.Emit("MOVQ", v, jit.Ptr(_SP, _VD_fargs + int64(i) * 8))
  79. }
  80. }
  81. }
  82. func (self *_ValueDecoder) load(r ...obj.Addr) {
  83. for i, v := range r {
  84. if i > _VD_saves / 8 - 1 {
  85. panic("too many registers to load")
  86. } else {
  87. self.Emit("MOVQ", jit.Ptr(_SP, _VD_fargs + int64(i) * 8), v)
  88. }
  89. }
  90. }
  91. func (self *_ValueDecoder) call(fn obj.Addr) {
  92. self.Emit("MOVQ", fn, _AX) // MOVQ ${fn}, AX
  93. self.Rjmp("CALL", _AX) // CALL AX
  94. }
  95. func (self *_ValueDecoder) call_go(fn obj.Addr) {
  96. self.save(_REG_go...) // SAVE $REG_go
  97. self.call(fn) // CALL ${fn}
  98. self.load(_REG_go...) // LOAD $REG_go
  99. }
  100. /** Decoder Assembler **/
  101. const (
  102. _S_val = iota + 1
  103. _S_arr
  104. _S_arr_0
  105. _S_obj
  106. _S_obj_0
  107. _S_obj_delim
  108. _S_obj_sep
  109. )
  110. const (
  111. _S_omask_key = (1 << _S_obj_0) | (1 << _S_obj_sep)
  112. _S_omask_end = (1 << _S_obj_0) | (1 << _S_obj)
  113. _S_vmask = (1 << _S_val) | (1 << _S_arr_0)
  114. )
  115. const (
  116. _A_init_len = 1
  117. _A_init_cap = 16
  118. )
  119. const (
  120. _ST_Sp = 0
  121. _ST_Vt = _PtrBytes
  122. _ST_Vp = _PtrBytes * (types.MAX_RECURSE + 1)
  123. )
  124. var (
  125. _V_true = jit.Imm(int64(pbool(true)))
  126. _V_false = jit.Imm(int64(pbool(false)))
  127. _F_value = jit.Imm(int64(native.S_value))
  128. )
  129. var (
  130. _V_max = jit.Imm(int64(types.V_MAX))
  131. _E_eof = jit.Imm(int64(types.ERR_EOF))
  132. _E_invalid = jit.Imm(int64(types.ERR_INVALID_CHAR))
  133. _E_recurse = jit.Imm(int64(types.ERR_RECURSE_EXCEED_MAX))
  134. )
  135. var (
  136. _F_convTslice = jit.Func(convTslice)
  137. _F_convTstring = jit.Func(convTstring)
  138. _F_invalid_vtype = jit.Func(invalid_vtype)
  139. )
  140. var (
  141. _T_map = jit.Type(reflect.TypeOf((map[string]interface{})(nil)))
  142. _T_bool = jit.Type(reflect.TypeOf(false))
  143. _T_int64 = jit.Type(reflect.TypeOf(int64(0)))
  144. _T_eface = jit.Type(reflect.TypeOf((*interface{})(nil)).Elem())
  145. _T_slice = jit.Type(reflect.TypeOf(([]interface{})(nil)))
  146. _T_string = jit.Type(reflect.TypeOf(""))
  147. _T_number = jit.Type(reflect.TypeOf(json.Number("")))
  148. _T_float64 = jit.Type(reflect.TypeOf(float64(0)))
  149. )
  150. var _R_tab = map[int]string {
  151. '[': "_decode_V_ARRAY",
  152. '{': "_decode_V_OBJECT",
  153. ':': "_decode_V_KEY_SEP",
  154. ',': "_decode_V_ELEM_SEP",
  155. ']': "_decode_V_ARRAY_END",
  156. '}': "_decode_V_OBJECT_END",
  157. }
  158. func (self *_ValueDecoder) compile() {
  159. self.Emit("SUBQ", jit.Imm(_VD_size), _SP) // SUBQ $_VD_size, SP
  160. self.Emit("MOVQ", _BP, jit.Ptr(_SP, _VD_offs)) // MOVQ BP, _VD_offs(SP)
  161. self.Emit("LEAQ", jit.Ptr(_SP, _VD_offs), _BP) // LEAQ _VD_offs(SP), BP
  162. /* initialize the state machine */
  163. self.Emit("XORL", _CX, _CX) // XORL CX, CX
  164. self.Emit("MOVQ", _DF, _VAR_df) // MOVQ DF, df
  165. /* initialize digital buffer first */
  166. self.Emit("MOVQ", jit.Imm(_MaxDigitNums), _VAR_ss_Dc) // MOVQ $_MaxDigitNums, ss.Dcap
  167. self.Emit("LEAQ", jit.Ptr(_ST, _DbufOffset), _AX) // LEAQ _DbufOffset(ST), AX
  168. self.Emit("MOVQ", _AX, _VAR_ss_Db) // MOVQ AX, ss.Dbuf
  169. /* add ST offset */
  170. self.Emit("ADDQ", jit.Imm(_FsmOffset), _ST) // ADDQ _FsmOffset, _ST
  171. self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp
  172. self.WriteRecNotAX(0, _VP, jit.Ptr(_ST, _ST_Vp), false) // MOVQ VP, ST.Vp[0]
  173. self.Emit("MOVQ", jit.Imm(_S_val), jit.Ptr(_ST, _ST_Vt)) // MOVQ _S_val, ST.Vt[0]
  174. self.Sjmp("JMP" , "_next") // JMP _next
  175. /* set the value from previous round */
  176. self.Link("_set_value") // _set_value:
  177. self.Emit("MOVL" , jit.Imm(_S_vmask), _DX) // MOVL _S_vmask, DX
  178. self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  179. self.Emit("MOVQ" , jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
  180. self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX
  181. self.Sjmp("JNC" , "_vtype_error") // JNC _vtype_error
  182. self.Emit("XORL" , _SI, _SI) // XORL SI, SI
  183. self.Emit("SUBQ" , jit.Imm(1), jit.Ptr(_ST, _ST_Sp)) // SUBQ $1, ST.Sp
  184. self.Emit("XCHGQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // XCHGQ ST.Vp[CX], SI
  185. self.Emit("MOVQ" , _R8, jit.Ptr(_SI, 0)) // MOVQ R8, (SI)
  186. self.WriteRecNotAX(1, _R9, jit.Ptr(_SI, 8), false) // MOVQ R9, 8(SI)
  187. /* check for value stack */
  188. self.Link("_next") // _next:
  189. self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _AX) // MOVQ ST.Sp, AX
  190. self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX
  191. self.Sjmp("JS" , "_return") // JS _return
  192. /* fast path: test up to 4 characters manually */
  193. self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL
  194. self.Sjmp("JAE" , "_decode_V_EOF") // JAE _decode_V_EOF
  195. self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX
  196. self.Emit("MOVQ" , jit.Imm(_BM_space), _DX) // MOVQ _BM_space, DX
  197. self.Emit("CMPQ" , _AX, jit.Imm(' ')) // CMPQ AX, $' '
  198. self.Sjmp("JA" , "_decode_fast") // JA _decode_fast
  199. self.Emit("BTQ" , _AX, _DX) // BTQ _AX, _DX
  200. self.Sjmp("JNC" , "_decode_fast") // JNC _decode_fast
  201. self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC
  202. /* at least 1 to 3 spaces */
  203. for i := 0; i < 3; i++ {
  204. self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL
  205. self.Sjmp("JAE" , "_decode_V_EOF") // JAE _decode_V_EOF
  206. self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX
  207. self.Emit("CMPQ" , _AX, jit.Imm(' ')) // CMPQ AX, $' '
  208. self.Sjmp("JA" , "_decode_fast") // JA _decode_fast
  209. self.Emit("BTQ" , _AX, _DX) // BTQ _AX, _DX
  210. self.Sjmp("JNC" , "_decode_fast") // JNC _decode_fast
  211. self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC
  212. }
  213. /* at least 4 spaces */
  214. self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL
  215. self.Sjmp("JAE" , "_decode_V_EOF") // JAE _decode_V_EOF
  216. self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX
  217. /* fast path: use lookup table to select decoder */
  218. self.Link("_decode_fast") // _decode_fast:
  219. self.Byte(0x48, 0x8d, 0x3d) // LEAQ ?(PC), DI
  220. self.Sref("_decode_tab", 4) // .... &_decode_tab
  221. self.Emit("MOVLQSX", jit.Sib(_DI, _AX, 4, 0), _AX) // MOVLQSX (DI)(AX*4), AX
  222. self.Emit("TESTQ" , _AX, _AX) // TESTQ AX, AX
  223. self.Sjmp("JZ" , "_decode_native") // JZ _decode_native
  224. self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC
  225. self.Emit("ADDQ" , _DI, _AX) // ADDQ DI, AX
  226. self.Rjmp("JMP" , _AX) // JMP AX
  227. /* decode with native decoder */
  228. self.Link("_decode_native") // _decode_native:
  229. self.Emit("MOVQ", _IP, _DI) // MOVQ IP, DI
  230. self.Emit("MOVQ", _IL, _SI) // MOVQ IL, SI
  231. self.Emit("MOVQ", _IC, _DX) // MOVQ IC, DX
  232. self.Emit("LEAQ", _VAR_ss, _CX) // LEAQ ss, CX
  233. self.Emit("MOVQ", _VAR_df, _R8) // MOVQ $df, R8
  234. self.Emit("BTSQ", jit.Imm(_F_allow_control), _R8) // ANDQ $1<<_F_allow_control, R8
  235. self.call(_F_value) // CALL value
  236. self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC
  237. /* check for errors */
  238. self.Emit("MOVQ" , _VAR_ss_Vt, _AX) // MOVQ ss.Vt, AX
  239. self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX
  240. self.Sjmp("JS" , "_parsing_error")
  241. self.Sjmp("JZ" , "_invalid_vtype") // JZ _invalid_vtype
  242. self.Emit("CMPQ" , _AX, _V_max) // CMPQ AX, _V_max
  243. self.Sjmp("JA" , "_invalid_vtype") // JA _invalid_vtype
  244. /* jump table selector */
  245. self.Byte(0x48, 0x8d, 0x3d) // LEAQ ?(PC), DI
  246. self.Sref("_switch_table", 4) // .... &_switch_table
  247. self.Emit("MOVLQSX", jit.Sib(_DI, _AX, 4, -4), _AX) // MOVLQSX -4(DI)(AX*4), AX
  248. self.Emit("ADDQ" , _DI, _AX) // ADDQ DI, AX
  249. self.Rjmp("JMP" , _AX) // JMP AX
  250. /** V_EOF **/
  251. self.Link("_decode_V_EOF") // _decode_V_EOF:
  252. self.Emit("MOVL", _E_eof, _EP) // MOVL _E_eof, EP
  253. self.Sjmp("JMP" , "_error") // JMP _error
  254. /** V_NULL **/
  255. self.Link("_decode_V_NULL") // _decode_V_NULL:
  256. self.Emit("XORL", _R8, _R8) // XORL R8, R8
  257. self.Emit("XORL", _R9, _R9) // XORL R9, R9
  258. self.Emit("LEAQ", jit.Ptr(_IC, -4), _DI) // LEAQ -4(IC), DI
  259. self.Sjmp("JMP" , "_set_value") // JMP _set_value
  260. /** V_TRUE **/
  261. self.Link("_decode_V_TRUE") // _decode_V_TRUE:
  262. self.Emit("MOVQ", _T_bool, _R8) // MOVQ _T_bool, R8
  263. // TODO: maybe modified by users?
  264. self.Emit("MOVQ", _V_true, _R9) // MOVQ _V_true, R9
  265. self.Emit("LEAQ", jit.Ptr(_IC, -4), _DI) // LEAQ -4(IC), DI
  266. self.Sjmp("JMP" , "_set_value") // JMP _set_value
  267. /** V_FALSE **/
  268. self.Link("_decode_V_FALSE") // _decode_V_FALSE:
  269. self.Emit("MOVQ", _T_bool, _R8) // MOVQ _T_bool, R8
  270. self.Emit("MOVQ", _V_false, _R9) // MOVQ _V_false, R9
  271. self.Emit("LEAQ", jit.Ptr(_IC, -5), _DI) // LEAQ -5(IC), DI
  272. self.Sjmp("JMP" , "_set_value") // JMP _set_value
  273. /** V_ARRAY **/
  274. self.Link("_decode_V_ARRAY") // _decode_V_ARRAY
  275. self.Emit("MOVL", jit.Imm(_S_vmask), _DX) // MOVL _S_vmask, DX
  276. self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  277. self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
  278. self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX
  279. self.Sjmp("JNC" , "_invalid_char") // JNC _invalid_char
  280. /* create a new array */
  281. self.Emit("MOVQ", _T_eface, _AX) // MOVQ _T_eface, AX
  282. self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP)
  283. self.Emit("MOVQ", jit.Imm(_A_init_len), jit.Ptr(_SP, 8)) // MOVQ _A_init_len, 8(SP)
  284. self.Emit("MOVQ", jit.Imm(_A_init_cap), jit.Ptr(_SP, 16)) // MOVQ _A_init_cap, 16(SP)
  285. self.call_go(_F_makeslice) // CALL_GO runtime.makeslice
  286. self.Emit("MOVQ", jit.Ptr(_SP, 24), _DX) // MOVQ 24(SP), DX
  287. /* pack into an interface */
  288. self.Emit("MOVQ", _DX, jit.Ptr(_SP, 0)) // MOVQ DX, (SP)
  289. self.Emit("MOVQ", jit.Imm(_A_init_len), jit.Ptr(_SP, 8)) // MOVQ _A_init_len, 8(SP)
  290. self.Emit("MOVQ", jit.Imm(_A_init_cap), jit.Ptr(_SP, 16)) // MOVQ _A_init_cap, 16(SP)
  291. self.call_go(_F_convTslice) // CALL_GO runtime.convTslice
  292. self.Emit("MOVQ", jit.Ptr(_SP, 24), _R8) // MOVQ 24(SP), R8
  293. /* replace current state with an array */
  294. self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  295. self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI
  296. self.Emit("MOVQ", jit.Imm(_S_arr), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_arr, ST.Vt[CX]
  297. self.Emit("MOVQ", _T_slice, _AX) // MOVQ _T_slice, AX
  298. self.Emit("MOVQ", _AX, jit.Ptr(_SI, 0)) // MOVQ AX, (SI)
  299. self.WriteRecNotAX(2, _R8, jit.Ptr(_SI, 8), false) // MOVQ R8, 8(SI)
  300. /* add a new slot for the first element */
  301. self.Emit("ADDQ", jit.Imm(1), _CX) // ADDQ $1, CX
  302. self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE)) // CMPQ CX, ${types.MAX_RECURSE}
  303. self.Sjmp("JAE" , "_stack_overflow") // JA _stack_overflow
  304. self.Emit("MOVQ", jit.Ptr(_R8, 0), _AX) // MOVQ (R8), AX
  305. self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp
  306. self.WritePtrAX(3, jit.Sib(_ST, _CX, 8, _ST_Vp), false) // MOVQ AX, ST.Vp[CX]
  307. self.Emit("MOVQ", jit.Imm(_S_arr_0), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_arr_0, ST.Vt[CX]
  308. self.Sjmp("JMP" , "_next") // JMP _next
  309. /** V_OBJECT **/
  310. self.Link("_decode_V_OBJECT") // _decode_V_OBJECT:
  311. self.Emit("MOVL", jit.Imm(_S_vmask), _DX) // MOVL _S_vmask, DX
  312. self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  313. self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
  314. self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX
  315. self.Sjmp("JNC" , "_invalid_char") // JNC _invalid_char
  316. self.call_go(_F_makemap_small) // CALL_GO runtime.makemap_small
  317. self.Emit("MOVQ", jit.Ptr(_SP, 0), _AX) // MOVQ (SP), AX
  318. self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  319. self.Emit("MOVQ", jit.Imm(_S_obj_0), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_obj, ST.Vt[CX]
  320. self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI
  321. self.Emit("MOVQ", _T_map, _DX) // MOVQ _T_map, DX
  322. self.Emit("MOVQ", _DX, jit.Ptr(_SI, 0)) // MOVQ DX, (SI)
  323. self.WritePtrAX(4, jit.Ptr(_SI, 8), false) // MOVQ AX, 8(SI)
  324. self.Sjmp("JMP" , "_next") // JMP _next
  325. /** V_STRING **/
  326. self.Link("_decode_V_STRING") // _decode_V_STRING:
  327. self.Emit("MOVQ", _VAR_ss_Iv, _CX) // MOVQ ss.Iv, CX
  328. self.Emit("MOVQ", _IC, _AX) // MOVQ IC, AX
  329. self.Emit("SUBQ", _CX, _AX) // SUBQ CX, AX
  330. /* check for escapes */
  331. self.Emit("CMPQ", _VAR_ss_Ep, jit.Imm(-1)) // CMPQ ss.Ep, $-1
  332. self.Sjmp("JNE" , "_unquote") // JNE _unquote
  333. self.Emit("SUBQ", jit.Imm(1), _AX) // SUBQ $1, AX
  334. self.Emit("LEAQ", jit.Sib(_IP, _CX, 1, 0), _R8) // LEAQ (IP)(CX), R8
  335. self.Byte(0x48, 0x8d, 0x3d) // LEAQ (PC), DI
  336. self.Sref("_copy_string_end", 4)
  337. self.Emit("BTQ", jit.Imm(_F_copy_string), _VAR_df)
  338. self.Sjmp("JC", "copy_string")
  339. self.Link("_copy_string_end")
  340. self.Emit("XORL", _DX, _DX) // XORL DX, DX
  341. /* strings with no escape sequences */
  342. self.Link("_noescape") // _noescape:
  343. self.Emit("MOVL", jit.Imm(_S_omask_key), _DI) // MOVL _S_omask, DI
  344. self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  345. self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _SI) // MOVQ ST.Vt[CX], SI
  346. self.Emit("BTQ" , _SI, _DI) // BTQ SI, DI
  347. self.Sjmp("JC" , "_object_key") // JC _object_key
  348. /* check for pre-packed strings, avoid 1 allocation */
  349. self.Emit("TESTQ", _DX, _DX) // TESTQ DX, DX
  350. self.Sjmp("JNZ" , "_packed_str") // JNZ _packed_str
  351. self.Emit("MOVQ" , _R8, jit.Ptr(_SP, 0)) // MOVQ R8, (SP)
  352. self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 8)) // MOVQ AX, 8(SP)
  353. self.call_go(_F_convTstring) // CALL_GO runtime.convTstring
  354. self.Emit("MOVQ" , jit.Ptr(_SP, 16), _R9) // MOVQ 16(SP), R9
  355. /* packed string already in R9 */
  356. self.Link("_packed_str") // _packed_str:
  357. self.Emit("MOVQ", _T_string, _R8) // MOVQ _T_string, R8
  358. self.Emit("MOVQ", _VAR_ss_Iv, _DI) // MOVQ ss.Iv, DI
  359. self.Emit("SUBQ", jit.Imm(1), _DI) // SUBQ $1, DI
  360. self.Sjmp("JMP" , "_set_value") // JMP _set_value
  361. /* the string is an object key, get the map */
  362. self.Link("_object_key")
  363. self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  364. self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI
  365. self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI
  366. /* add a new delimiter */
  367. self.Emit("ADDQ", jit.Imm(1), _CX) // ADDQ $1, CX
  368. self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE)) // CMPQ CX, ${types.MAX_RECURSE}
  369. self.Sjmp("JAE" , "_stack_overflow") // JA _stack_overflow
  370. self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp
  371. self.Emit("MOVQ", jit.Imm(_S_obj_delim), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_obj_delim, ST.Vt[CX]
  372. /* add a new slot int the map */
  373. self.Emit("MOVQ", _T_map, _DX) // MOVQ _T_map, DX
  374. self.Emit("MOVQ", _DX, jit.Ptr(_SP, 0)) // MOVQ DX, (SP)
  375. self.Emit("MOVQ", _SI, jit.Ptr(_SP, 8)) // MOVQ SI, 8(SP)
  376. self.Emit("MOVQ", _R8, jit.Ptr(_SP, 16)) // MOVQ R9, 16(SP)
  377. self.Emit("MOVQ", _AX, jit.Ptr(_SP, 24)) // MOVQ AX, 24(SP)
  378. self.call_go(_F_mapassign_faststr) // CALL_GO runtime.mapassign_faststr
  379. self.Emit("MOVQ", jit.Ptr(_SP, 32), _AX) // MOVQ 32(SP), AX
  380. /* add to the pointer stack */
  381. self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  382. self.WritePtrAX(6, jit.Sib(_ST, _CX, 8, _ST_Vp), false) // MOVQ AX, ST.Vp[CX]
  383. self.Sjmp("JMP" , "_next") // JMP _next
  384. /* allocate memory to store the string header and unquoted result */
  385. self.Link("_unquote") // _unquote:
  386. self.Emit("ADDQ", jit.Imm(15), _AX) // ADDQ $15, AX
  387. self.Emit("MOVQ", _T_byte, _CX) // MOVQ _T_byte, CX
  388. self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP)
  389. self.Emit("MOVQ", _CX, jit.Ptr(_SP, 8)) // MOVQ CX, 8(SP)
  390. self.Emit("MOVB", jit.Imm(0), jit.Ptr(_SP, 16)) // MOVB $0, 16(SP)
  391. self.call_go(_F_mallocgc) // CALL_GO runtime.mallocgc
  392. self.Emit("MOVQ", jit.Ptr(_SP, 24), _R9) // MOVQ 24(SP), R9
  393. /* prepare the unquoting parameters */
  394. self.Emit("MOVQ" , _VAR_ss_Iv, _CX) // MOVQ ss.Iv, CX
  395. self.Emit("LEAQ" , jit.Sib(_IP, _CX, 1, 0), _DI) // LEAQ (IP)(CX), DI
  396. self.Emit("NEGQ" , _CX) // NEGQ CX
  397. self.Emit("LEAQ" , jit.Sib(_IC, _CX, 1, -1), _SI) // LEAQ -1(IC)(CX), SI
  398. self.Emit("LEAQ" , jit.Ptr(_R9, 16), _DX) // LEAQ 16(R8), DX
  399. self.Emit("LEAQ" , _VAR_ss_Ep, _CX) // LEAQ ss.Ep, CX
  400. self.Emit("XORL" , _R8, _R8) // XORL R8, R8
  401. self.Emit("BTQ" , jit.Imm(_F_disable_urc), _VAR_df) // BTQ ${_F_disable_urc}, fv
  402. self.Emit("SETCC", _R8) // SETCC R8
  403. self.Emit("SHLQ" , jit.Imm(types.B_UNICODE_REPLACE), _R8) // SHLQ ${types.B_UNICODE_REPLACE}, R8
  404. /* unquote the string, with R9 been preserved */
  405. self.save(_R9) // SAVE R9
  406. self.call(_F_unquote) // CALL unquote
  407. self.load(_R9) // LOAD R9
  408. /* check for errors */
  409. self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX
  410. self.Sjmp("JS" , "_unquote_error") // JS _unquote_error
  411. self.Emit("MOVL" , jit.Imm(1), _DX) // MOVL $1, DX
  412. self.Emit("LEAQ" , jit.Ptr(_R9, 16), _R8) // ADDQ $16, R8
  413. self.Emit("MOVQ" , _R8, jit.Ptr(_R9, 0)) // MOVQ R8, (R9)
  414. self.Emit("MOVQ" , _AX, jit.Ptr(_R9, 8)) // MOVQ AX, 8(R9)
  415. self.Sjmp("JMP" , "_noescape") // JMP _noescape
  416. /** V_DOUBLE **/
  417. self.Link("_decode_V_DOUBLE") // _decode_V_DOUBLE:
  418. self.Emit("BTQ" , jit.Imm(_F_use_number), _VAR_df) // BTQ _F_use_number, df
  419. self.Sjmp("JC" , "_use_number") // JC _use_number
  420. self.Emit("MOVSD", _VAR_ss_Dv, _X0) // MOVSD ss.Dv, X0
  421. self.Sjmp("JMP" , "_use_float64") // JMP _use_float64
  422. /** V_INTEGER **/
  423. self.Link("_decode_V_INTEGER") // _decode_V_INTEGER:
  424. self.Emit("BTQ" , jit.Imm(_F_use_number), _VAR_df) // BTQ _F_use_number, df
  425. self.Sjmp("JC" , "_use_number") // JC _use_number
  426. self.Emit("BTQ" , jit.Imm(_F_use_int64), _VAR_df) // BTQ _F_use_int64, df
  427. self.Sjmp("JC" , "_use_int64") // JC _use_int64
  428. self.Emit("MOVQ" , _VAR_ss_Iv, _AX) // MOVQ ss.Iv, AX
  429. self.Emit("CVTSQ2SD", _AX, _X0) // CVTSQ2SD AX, X0
  430. /* represent numbers as `float64` */
  431. self.Link("_use_float64") // _use_float64:
  432. self.Emit("MOVSD", _X0, jit.Ptr(_SP, 0)) // MOVSD X0, (SP)
  433. self.call_go(_F_convT64) // CALL_GO runtime.convT64
  434. self.Emit("MOVQ" , _T_float64, _R8) // MOVQ _T_float64, R8
  435. self.Emit("MOVQ" , jit.Ptr(_SP, 8), _R9) // MOVQ 8(SP), R9
  436. self.Emit("MOVQ" , _VAR_ss_Ep, _DI) // MOVQ ss.Ep, DI
  437. self.Sjmp("JMP" , "_set_value") // JMP _set_value
  438. /* represent numbers as `json.Number` */
  439. self.Link("_use_number") // _use_number
  440. self.Emit("MOVQ", _VAR_ss_Ep, _AX) // MOVQ ss.Ep, AX
  441. self.Emit("LEAQ", jit.Sib(_IP, _AX, 1, 0), _SI) // LEAQ (IP)(AX), SI
  442. self.Emit("MOVQ", _IC, _CX) // MOVQ IC, CX
  443. self.Emit("SUBQ", _AX, _CX) // SUBQ AX, CX
  444. self.Emit("MOVQ", _SI, jit.Ptr(_SP, 0)) // MOVQ SI, (SP)
  445. self.Emit("MOVQ", _CX, jit.Ptr(_SP, 8)) // MOVQ CX, 8(SP)
  446. self.call_go(_F_convTstring) // CALL_GO runtime.convTstring
  447. self.Emit("MOVQ", _T_number, _R8) // MOVQ _T_number, R8
  448. self.Emit("MOVQ", jit.Ptr(_SP, 16), _R9) // MOVQ 16(SP), R9
  449. self.Emit("MOVQ", _VAR_ss_Ep, _DI) // MOVQ ss.Ep, DI
  450. self.Sjmp("JMP" , "_set_value") // JMP _set_value
  451. /* represent numbers as `int64` */
  452. self.Link("_use_int64") // _use_int64:
  453. self.Emit("MOVQ", _VAR_ss_Iv, _AX) // MOVQ ss.Iv, AX
  454. self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP)
  455. self.call_go(_F_convT64) // CALL_GO runtime.convT64
  456. self.Emit("MOVQ", _T_int64, _R8) // MOVQ _T_int64, R8
  457. self.Emit("MOVQ", jit.Ptr(_SP, 8), _R9) // MOVQ 8(SP), R9
  458. self.Emit("MOVQ", _VAR_ss_Ep, _DI) // MOVQ ss.Ep, DI
  459. self.Sjmp("JMP" , "_set_value") // JMP _set_value
  460. /** V_KEY_SEP **/
  461. self.Link("_decode_V_KEY_SEP") // _decode_V_KEY_SEP:
  462. // self.Byte(0xcc)
  463. self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  464. self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
  465. self.Emit("CMPQ", _AX, jit.Imm(_S_obj_delim)) // CMPQ AX, _S_obj_delim
  466. self.Sjmp("JNE" , "_invalid_char") // JNE _invalid_char
  467. self.Emit("MOVQ", jit.Imm(_S_val), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_val, ST.Vt[CX]
  468. self.Emit("MOVQ", jit.Imm(_S_obj), jit.Sib(_ST, _CX, 8, _ST_Vt - 8)) // MOVQ _S_obj, ST.Vt[CX - 1]
  469. self.Sjmp("JMP" , "_next") // JMP _next
  470. /** V_ELEM_SEP **/
  471. self.Link("_decode_V_ELEM_SEP") // _decode_V_ELEM_SEP:
  472. self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  473. self.Emit("MOVQ" , jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
  474. self.Emit("CMPQ" , _AX, jit.Imm(_S_arr)) // CMPQ _AX, _S_arr
  475. self.Sjmp("JE" , "_array_sep") // JZ _next
  476. self.Emit("CMPQ" , _AX, jit.Imm(_S_obj)) // CMPQ _AX, _S_arr
  477. self.Sjmp("JNE" , "_invalid_char") // JNE _invalid_char
  478. self.Emit("MOVQ" , jit.Imm(_S_obj_sep), jit.Sib(_ST, _CX, 8, _ST_Vt))
  479. self.Sjmp("JMP" , "_next") // JMP _next
  480. /* arrays */
  481. self.Link("_array_sep")
  482. self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI
  483. self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI
  484. self.Emit("MOVQ", jit.Ptr(_SI, 8), _DX) // MOVQ 8(SI), DX
  485. self.Emit("CMPQ", _DX, jit.Ptr(_SI, 16)) // CMPQ DX, 16(SI)
  486. self.Sjmp("JAE" , "_array_more") // JAE _array_more
  487. /* add a slot for the new element */
  488. self.Link("_array_append") // _array_append:
  489. self.Emit("ADDQ", jit.Imm(1), jit.Ptr(_SI, 8)) // ADDQ $1, 8(SI)
  490. self.Emit("MOVQ", jit.Ptr(_SI, 0), _SI) // MOVQ (SI), SI
  491. self.Emit("ADDQ", jit.Imm(1), _CX) // ADDQ $1, CX
  492. self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE)) // CMPQ CX, ${types.MAX_RECURSE}
  493. self.Sjmp("JAE" , "_stack_overflow")
  494. self.Emit("SHLQ", jit.Imm(1), _DX) // SHLQ $1, DX
  495. self.Emit("LEAQ", jit.Sib(_SI, _DX, 8, 0), _SI) // LEAQ (SI)(DX*8), SI
  496. self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp
  497. self.WriteRecNotAX(7 , _SI, jit.Sib(_ST, _CX, 8, _ST_Vp), false) // MOVQ SI, ST.Vp[CX]
  498. self.Emit("MOVQ", jit.Imm(_S_val), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_val, ST.Vt[CX}
  499. self.Sjmp("JMP" , "_next") // JMP _next
  500. /** V_ARRAY_END **/
  501. self.Link("_decode_V_ARRAY_END") // _decode_V_ARRAY_END:
  502. self.Emit("XORL", _DX, _DX) // XORL DX, DX
  503. self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  504. self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
  505. self.Emit("CMPQ", _AX, jit.Imm(_S_arr_0)) // CMPQ AX, _S_arr_0
  506. self.Sjmp("JE" , "_first_item") // JE _first_item
  507. self.Emit("CMPQ", _AX, jit.Imm(_S_arr)) // CMPQ AX, _S_arr
  508. self.Sjmp("JNE" , "_invalid_char") // JNE _invalid_char
  509. self.Emit("SUBQ", jit.Imm(1), jit.Ptr(_ST, _ST_Sp)) // SUBQ $1, ST.Sp
  510. self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp)) // MOVQ DX, ST.Vp[CX]
  511. self.Sjmp("JMP" , "_next") // JMP _next
  512. /* first element of an array */
  513. self.Link("_first_item") // _first_item:
  514. self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  515. self.Emit("SUBQ", jit.Imm(2), jit.Ptr(_ST, _ST_Sp)) // SUBQ $2, ST.Sp
  516. self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp - 8), _SI) // MOVQ ST.Vp[CX - 1], SI
  517. self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI
  518. self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp - 8)) // MOVQ DX, ST.Vp[CX - 1]
  519. self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp)) // MOVQ DX, ST.Vp[CX]
  520. self.Emit("MOVQ", _DX, jit.Ptr(_SI, 8)) // MOVQ DX, 8(SI)
  521. self.Sjmp("JMP" , "_next") // JMP _next
  522. /** V_OBJECT_END **/
  523. self.Link("_decode_V_OBJECT_END") // _decode_V_OBJECT_END:
  524. self.Emit("MOVL", jit.Imm(_S_omask_end), _DX) // MOVL _S_omask, DI
  525. self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  526. self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX
  527. self.Emit("BTQ" , _AX, _DX)
  528. self.Sjmp("JNC" , "_invalid_char") // JNE _invalid_char
  529. self.Emit("XORL", _AX, _AX) // XORL AX, AX
  530. self.Emit("SUBQ", jit.Imm(1), jit.Ptr(_ST, _ST_Sp)) // SUBQ $1, ST.Sp
  531. self.Emit("MOVQ", _AX, jit.Sib(_ST, _CX, 8, _ST_Vp)) // MOVQ AX, ST.Vp[CX]
  532. self.Sjmp("JMP" , "_next") // JMP _next
  533. /* return from decoder */
  534. self.Link("_return") // _return:
  535. self.Emit("XORL", _EP, _EP) // XORL EP, EP
  536. self.Emit("MOVQ", _EP, jit.Ptr(_ST, _ST_Vp)) // MOVQ EP, ST.Vp[0]
  537. self.Link("_epilogue") // _epilogue:
  538. self.Emit("SUBQ", jit.Imm(_FsmOffset), _ST) // SUBQ _FsmOffset, _ST
  539. self.Emit("MOVQ", jit.Ptr(_SP, _VD_offs), _BP) // MOVQ _VD_offs(SP), BP
  540. self.Emit("ADDQ", jit.Imm(_VD_size), _SP) // ADDQ $_VD_size, SP
  541. self.Emit("RET") // RET
  542. /* array expand */
  543. self.Link("_array_more") // _array_more:
  544. self.Emit("MOVQ" , _T_eface, _AX) // MOVQ _T_eface, AX
  545. self.Emit("MOVOU", jit.Ptr(_SI, 0), _X0) // MOVOU (SI), X0
  546. self.Emit("MOVQ" , jit.Ptr(_SI, 16), _DX) // MOVQ 16(SI), DX
  547. self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP)
  548. self.Emit("MOVOU", _X0, jit.Ptr(_SP, 8)) // MOVOU X0, 8(SP)
  549. self.Emit("MOVQ" , _DX, jit.Ptr(_SP, 24)) // MOVQ DX, 24(SP)
  550. self.Emit("SHLQ" , jit.Imm(1), _DX) // SHLQ $1, DX
  551. self.Emit("MOVQ" , _DX, jit.Ptr(_SP, 32)) // MOVQ DX, 32(SP)
  552. self.call_go(_F_growslice) // CALL_GO runtime.growslice
  553. self.Emit("MOVQ" , jit.Ptr(_SP, 40), _DI) // MOVOU 40(SP), DI
  554. self.Emit("MOVQ" , jit.Ptr(_SP, 48), _DX) // MOVOU 48(SP), DX
  555. self.Emit("MOVQ" , jit.Ptr(_SP, 56), _AX) // MOVQ 56(SP), AX
  556. /* update the slice */
  557. self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX
  558. self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI
  559. self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI
  560. self.Emit("MOVQ", _DX, jit.Ptr(_SI, 8)) // MOVQ DX, 8(SI)
  561. self.Emit("MOVQ", _AX, jit.Ptr(_SI, 16)) // MOVQ AX, 16(AX)
  562. self.WriteRecNotAX(8 , _DI, jit.Ptr(_SI, 0), false) // MOVQ R10, (SI)
  563. self.Sjmp("JMP" , "_array_append") // JMP _array_append
  564. /* copy string */
  565. self.Link("copy_string") // pointer: R8, length: AX, return addr: DI
  566. // self.Byte(0xcc)
  567. self.Emit("MOVQ", _R8, _VAR_cs_p)
  568. self.Emit("MOVQ", _AX, _VAR_cs_n)
  569. self.Emit("MOVQ", _DI, _VAR_cs_LR)
  570. self.Emit("MOVQ", _T_byte, _R8)
  571. self.Emit("MOVQ", _R8, jit.Ptr(_SP, 0))
  572. self.Emit("MOVQ", _AX, jit.Ptr(_SP, 8))
  573. self.Emit("MOVQ", _AX, jit.Ptr(_SP, 16))
  574. self.call_go(_F_makeslice)
  575. self.Emit("MOVQ", jit.Ptr(_SP, 24), _R8)
  576. self.Emit("MOVQ", _R8, _VAR_cs_d)
  577. self.Emit("MOVQ", _R8, jit.Ptr(_SP, 0))
  578. self.Emit("MOVQ", _VAR_cs_p, _R8)
  579. self.Emit("MOVQ", _R8, jit.Ptr(_SP, 8))
  580. self.Emit("MOVQ", _VAR_cs_n, _AX)
  581. self.Emit("MOVQ", _AX, jit.Ptr(_SP, 16))
  582. self.call_go(_F_memmove)
  583. self.Emit("MOVQ", _VAR_cs_d, _R8)
  584. self.Emit("MOVQ", _VAR_cs_n, _AX)
  585. self.Emit("MOVQ", _VAR_cs_LR, _DI)
  586. // self.Byte(0xcc)
  587. self.Rjmp("JMP", _DI)
  588. /* error handlers */
  589. self.Link("_stack_overflow")
  590. self.Emit("MOVL" , _E_recurse, _EP) // MOVQ _E_recurse, EP
  591. self.Sjmp("JMP" , "_error") // JMP _error
  592. self.Link("_vtype_error") // _vtype_error:
  593. self.Emit("MOVQ" , _DI, _IC) // MOVQ DI, IC
  594. self.Emit("MOVL" , _E_invalid, _EP) // MOVL _E_invalid, EP
  595. self.Sjmp("JMP" , "_error") // JMP _error
  596. self.Link("_invalid_char") // _invalid_char:
  597. self.Emit("SUBQ" , jit.Imm(1), _IC) // SUBQ $1, IC
  598. self.Emit("MOVL" , _E_invalid, _EP) // MOVL _E_invalid, EP
  599. self.Sjmp("JMP" , "_error") // JMP _error
  600. self.Link("_unquote_error") // _unquote_error:
  601. self.Emit("MOVQ" , _VAR_ss_Iv, _IC) // MOVQ ss.Iv, IC
  602. self.Emit("SUBQ" , jit.Imm(1), _IC) // SUBQ $1, IC
  603. self.Link("_parsing_error") // _parsing_error:
  604. self.Emit("NEGQ" , _AX) // NEGQ AX
  605. self.Emit("MOVQ" , _AX, _EP) // MOVQ AX, EP
  606. self.Link("_error") // _error:
  607. self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0
  608. self.Emit("MOVOU", _X0, jit.Ptr(_VP, 0)) // MOVOU X0, (VP)
  609. self.Sjmp("JMP" , "_epilogue") // JMP _epilogue
  610. /* invalid value type, never returns */
  611. self.Link("_invalid_vtype")
  612. self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP)
  613. self.call(_F_invalid_vtype) // CALL invalid_type
  614. self.Emit("UD2") // UD2
  615. /* switch jump table */
  616. self.Link("_switch_table") // _switch_table:
  617. self.Sref("_decode_V_EOF", 0) // SREF &_decode_V_EOF, $0
  618. self.Sref("_decode_V_NULL", -4) // SREF &_decode_V_NULL, $-4
  619. self.Sref("_decode_V_TRUE", -8) // SREF &_decode_V_TRUE, $-8
  620. self.Sref("_decode_V_FALSE", -12) // SREF &_decode_V_FALSE, $-12
  621. self.Sref("_decode_V_ARRAY", -16) // SREF &_decode_V_ARRAY, $-16
  622. self.Sref("_decode_V_OBJECT", -20) // SREF &_decode_V_OBJECT, $-20
  623. self.Sref("_decode_V_STRING", -24) // SREF &_decode_V_STRING, $-24
  624. self.Sref("_decode_V_DOUBLE", -28) // SREF &_decode_V_DOUBLE, $-28
  625. self.Sref("_decode_V_INTEGER", -32) // SREF &_decode_V_INTEGER, $-32
  626. self.Sref("_decode_V_KEY_SEP", -36) // SREF &_decode_V_KEY_SEP, $-36
  627. self.Sref("_decode_V_ELEM_SEP", -40) // SREF &_decode_V_ELEM_SEP, $-40
  628. self.Sref("_decode_V_ARRAY_END", -44) // SREF &_decode_V_ARRAY_END, $-44
  629. self.Sref("_decode_V_OBJECT_END", -48) // SREF &_decode_V_OBJECT_END, $-48
  630. /* fast character lookup table */
  631. self.Link("_decode_tab") // _decode_tab:
  632. self.Sref("_decode_V_EOF", 0) // SREF &_decode_V_EOF, $0
  633. /* generate rest of the tabs */
  634. for i := 1; i < 256; i++ {
  635. if to, ok := _R_tab[i]; ok {
  636. self.Sref(to, -int64(i) * 4)
  637. } else {
  638. self.Byte(0x00, 0x00, 0x00, 0x00)
  639. }
  640. }
  641. }
  642. /** Generic Decoder **/
  643. var (
  644. _subr_decode_value = new(_ValueDecoder).build()
  645. )
  646. //go:nosplit
  647. func invalid_vtype(vt types.ValueType) {
  648. throw(fmt.Sprintf("invalid value type: %d", vt))
  649. }