util.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. package vm
  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. errUnsupportedValue = encoder.ErrUnsupportedValue
  19. errUnsupportedFloat = encoder.ErrUnsupportedFloat
  20. mapiterinit = encoder.MapIterInit
  21. mapiterkey = encoder.MapIterKey
  22. mapitervalue = encoder.MapIterValue
  23. mapiternext = encoder.MapIterNext
  24. maplen = encoder.MapLen
  25. )
  26. type emptyInterface struct {
  27. typ *runtime.Type
  28. ptr unsafe.Pointer
  29. }
  30. type nonEmptyInterface struct {
  31. itab *struct {
  32. ityp *runtime.Type // static interface type
  33. typ *runtime.Type // dynamic concrete type
  34. // unused fields...
  35. }
  36. ptr unsafe.Pointer
  37. }
  38. func errUnimplementedOp(op encoder.OpType) error {
  39. return fmt.Errorf("encoder: opcode %s has not been implemented", op)
  40. }
  41. func load(base uintptr, idx uint32) uintptr {
  42. addr := base + uintptr(idx)
  43. return **(**uintptr)(unsafe.Pointer(&addr))
  44. }
  45. func store(base uintptr, idx uint32, p uintptr) {
  46. addr := base + uintptr(idx)
  47. **(**uintptr)(unsafe.Pointer(&addr)) = p
  48. }
  49. func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr {
  50. addr := base + uintptr(idx)
  51. p := **(**uintptr)(unsafe.Pointer(&addr))
  52. for i := uint8(0); i < ptrNum; i++ {
  53. if p == 0 {
  54. return 0
  55. }
  56. p = ptrToPtr(p)
  57. }
  58. return p
  59. }
  60. func ptrToUint64(p uintptr, bitSize uint8) uint64 {
  61. switch bitSize {
  62. case 8:
  63. return (uint64)(**(**uint8)(unsafe.Pointer(&p)))
  64. case 16:
  65. return (uint64)(**(**uint16)(unsafe.Pointer(&p)))
  66. case 32:
  67. return (uint64)(**(**uint32)(unsafe.Pointer(&p)))
  68. case 64:
  69. return **(**uint64)(unsafe.Pointer(&p))
  70. }
  71. return 0
  72. }
  73. func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) }
  74. func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) }
  75. func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) }
  76. func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) }
  77. func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) }
  78. func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) }
  79. func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) }
  80. func ptrToPtr(p uintptr) uintptr {
  81. return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
  82. }
  83. func ptrToNPtr(p uintptr, ptrNum uint8) uintptr {
  84. for i := uint8(0); i < ptrNum; i++ {
  85. if p == 0 {
  86. return 0
  87. }
  88. p = ptrToPtr(p)
  89. }
  90. return p
  91. }
  92. func ptrToUnsafePtr(p uintptr) unsafe.Pointer {
  93. return *(*unsafe.Pointer)(unsafe.Pointer(&p))
  94. }
  95. func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} {
  96. return *(*interface{})(unsafe.Pointer(&emptyInterface{
  97. typ: code.Type,
  98. ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
  99. }))
  100. }
  101. func appendBool(_ *encoder.RuntimeContext, b []byte, v bool) []byte {
  102. if v {
  103. return append(b, "true"...)
  104. }
  105. return append(b, "false"...)
  106. }
  107. func appendNull(_ *encoder.RuntimeContext, b []byte) []byte {
  108. return append(b, "null"...)
  109. }
  110. func appendComma(_ *encoder.RuntimeContext, b []byte) []byte {
  111. return append(b, ',')
  112. }
  113. func appendNullComma(_ *encoder.RuntimeContext, b []byte) []byte {
  114. return append(b, "null,"...)
  115. }
  116. func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
  117. last := len(b) - 1
  118. b[last] = ':'
  119. return b
  120. }
  121. func appendMapKeyValue(_ *encoder.RuntimeContext, _ *encoder.Opcode, b, key, value []byte) []byte {
  122. b = append(b, key...)
  123. b[len(b)-1] = ':'
  124. return append(b, value...)
  125. }
  126. func appendMapEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
  127. b[len(b)-1] = '}'
  128. b = append(b, ',')
  129. return b
  130. }
  131. func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
  132. return encoder.AppendMarshalJSON(ctx, code, b, v)
  133. }
  134. func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
  135. return encoder.AppendMarshalText(ctx, code, b, v)
  136. }
  137. func appendArrayHead(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
  138. return append(b, '[')
  139. }
  140. func appendArrayEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
  141. last := len(b) - 1
  142. b[last] = ']'
  143. return append(b, ',')
  144. }
  145. func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte {
  146. return append(b, '[', ']', ',')
  147. }
  148. func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte {
  149. return append(b, '{', '}', ',')
  150. }
  151. func appendObjectEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
  152. last := len(b) - 1
  153. b[last] = '}'
  154. return append(b, ',')
  155. }
  156. func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte {
  157. return append(b, '{')
  158. }
  159. func appendStructKey(_ *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
  160. return append(b, code.Key...)
  161. }
  162. func appendStructEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
  163. return append(b, '}', ',')
  164. }
  165. func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
  166. last := len(b) - 1
  167. if b[last] == ',' {
  168. b[last] = '}'
  169. return appendComma(ctx, b)
  170. }
  171. return appendStructEnd(ctx, code, b)
  172. }
  173. func restoreIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, _ uintptr) {}
  174. func storeIndent(_ uintptr, _ *encoder.Opcode, _ uintptr) {}
  175. func appendMapKeyIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b }
  176. func appendArrayElemIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b }