util.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. package vm_indent
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "unsafe"
  6. "github.com/goccy/go-json/internal/encoder"
  7. "github.com/goccy/go-json/internal/runtime"
  8. )
  9. const uintptrSize = 4 << (^uintptr(0) >> 63)
  10. var (
  11. appendInt = encoder.AppendInt
  12. appendUint = encoder.AppendUint
  13. appendFloat32 = encoder.AppendFloat32
  14. appendFloat64 = encoder.AppendFloat64
  15. appendString = encoder.AppendString
  16. appendByteSlice = encoder.AppendByteSlice
  17. appendNumber = encoder.AppendNumber
  18. appendStructEnd = encoder.AppendStructEndIndent
  19. appendIndent = encoder.AppendIndent
  20. errUnsupportedValue = encoder.ErrUnsupportedValue
  21. errUnsupportedFloat = encoder.ErrUnsupportedFloat
  22. mapiterinit = encoder.MapIterInit
  23. mapiterkey = encoder.MapIterKey
  24. mapitervalue = encoder.MapIterValue
  25. mapiternext = encoder.MapIterNext
  26. maplen = encoder.MapLen
  27. )
  28. type emptyInterface struct {
  29. typ *runtime.Type
  30. ptr unsafe.Pointer
  31. }
  32. type nonEmptyInterface struct {
  33. itab *struct {
  34. ityp *runtime.Type // static interface type
  35. typ *runtime.Type // dynamic concrete type
  36. // unused fields...
  37. }
  38. ptr unsafe.Pointer
  39. }
  40. func errUnimplementedOp(op encoder.OpType) error {
  41. return fmt.Errorf("encoder (indent): opcode %s has not been implemented", op)
  42. }
  43. func load(base uintptr, idx uint32) uintptr {
  44. addr := base + uintptr(idx)
  45. return **(**uintptr)(unsafe.Pointer(&addr))
  46. }
  47. func store(base uintptr, idx uint32, p uintptr) {
  48. addr := base + uintptr(idx)
  49. **(**uintptr)(unsafe.Pointer(&addr)) = p
  50. }
  51. func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr {
  52. addr := base + uintptr(idx)
  53. p := **(**uintptr)(unsafe.Pointer(&addr))
  54. for i := uint8(0); i < ptrNum; i++ {
  55. if p == 0 {
  56. return 0
  57. }
  58. p = ptrToPtr(p)
  59. }
  60. return p
  61. }
  62. func ptrToUint64(p uintptr, bitSize uint8) uint64 {
  63. switch bitSize {
  64. case 8:
  65. return (uint64)(**(**uint8)(unsafe.Pointer(&p)))
  66. case 16:
  67. return (uint64)(**(**uint16)(unsafe.Pointer(&p)))
  68. case 32:
  69. return (uint64)(**(**uint32)(unsafe.Pointer(&p)))
  70. case 64:
  71. return **(**uint64)(unsafe.Pointer(&p))
  72. }
  73. return 0
  74. }
  75. func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) }
  76. func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) }
  77. func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) }
  78. func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) }
  79. func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) }
  80. func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) }
  81. func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) }
  82. func ptrToPtr(p uintptr) uintptr {
  83. return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
  84. }
  85. func ptrToNPtr(p uintptr, ptrNum uint8) uintptr {
  86. for i := uint8(0); i < ptrNum; i++ {
  87. if p == 0 {
  88. return 0
  89. }
  90. p = ptrToPtr(p)
  91. }
  92. return p
  93. }
  94. func ptrToUnsafePtr(p uintptr) unsafe.Pointer {
  95. return *(*unsafe.Pointer)(unsafe.Pointer(&p))
  96. }
  97. func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} {
  98. return *(*interface{})(unsafe.Pointer(&emptyInterface{
  99. typ: code.Type,
  100. ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
  101. }))
  102. }
  103. func appendBool(_ *encoder.RuntimeContext, b []byte, v bool) []byte {
  104. if v {
  105. return append(b, "true"...)
  106. }
  107. return append(b, "false"...)
  108. }
  109. func appendNull(_ *encoder.RuntimeContext, b []byte) []byte {
  110. return append(b, "null"...)
  111. }
  112. func appendComma(_ *encoder.RuntimeContext, b []byte) []byte {
  113. return append(b, ',', '\n')
  114. }
  115. func appendNullComma(_ *encoder.RuntimeContext, b []byte) []byte {
  116. return append(b, "null,\n"...)
  117. }
  118. func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
  119. return append(b, ':', ' ')
  120. }
  121. func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte {
  122. b = appendIndent(ctx, b, code.Indent+1)
  123. b = append(b, key...)
  124. b[len(b)-2] = ':'
  125. b[len(b)-1] = ' '
  126. return append(b, value...)
  127. }
  128. func appendMapEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
  129. b = b[:len(b)-2]
  130. b = append(b, '\n')
  131. b = appendIndent(ctx, b, code.Indent)
  132. return append(b, '}', ',', '\n')
  133. }
  134. func appendArrayHead(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
  135. b = append(b, '[', '\n')
  136. return appendIndent(ctx, b, code.Indent+1)
  137. }
  138. func appendArrayEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
  139. b = b[:len(b)-2]
  140. b = append(b, '\n')
  141. b = appendIndent(ctx, b, code.Indent)
  142. return append(b, ']', ',', '\n')
  143. }
  144. func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte {
  145. return append(b, '[', ']', ',', '\n')
  146. }
  147. func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte {
  148. return append(b, '{', '}', ',', '\n')
  149. }
  150. func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
  151. last := len(b) - 1
  152. b[last] = '\n'
  153. b = appendIndent(ctx, b, code.Indent-1)
  154. return append(b, '}', ',', '\n')
  155. }
  156. func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
  157. return encoder.AppendMarshalJSONIndent(ctx, code, b, v)
  158. }
  159. func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
  160. return encoder.AppendMarshalTextIndent(ctx, code, b, v)
  161. }
  162. func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte {
  163. return append(b, '{', '\n')
  164. }
  165. func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
  166. b = appendIndent(ctx, b, code.Indent)
  167. b = append(b, code.Key...)
  168. return append(b, ' ')
  169. }
  170. func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
  171. last := len(b) - 1
  172. if b[last-1] == '{' {
  173. b[last] = '}'
  174. } else {
  175. if b[last] == '\n' {
  176. // to remove ',' and '\n' characters
  177. b = b[:len(b)-2]
  178. }
  179. b = append(b, '\n')
  180. b = appendIndent(ctx, b, code.Indent-1)
  181. b = append(b, '}')
  182. }
  183. return appendComma(ctx, b)
  184. }
  185. func restoreIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, ctxptr uintptr) {
  186. ctx.BaseIndent = uint32(load(ctxptr, code.Length))
  187. }
  188. func storeIndent(ctxptr uintptr, code *encoder.Opcode, indent uintptr) {
  189. store(ctxptr, code.Length, indent)
  190. }
  191. func appendArrayElemIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
  192. return appendIndent(ctx, b, code.Indent+1)
  193. }
  194. func appendMapKeyIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
  195. return appendIndent(ctx, b, code.Indent)
  196. }