1 package vm_color
2
3 import (
4 "encoding/json"
5 "fmt"
6 "unsafe"
7
8 "github.com/goccy/go-json/internal/encoder"
9 "github.com/goccy/go-json/internal/runtime"
10 )
11
12 const uintptrSize = 4 << (^uintptr(0) >> 63)
13
14 var (
15 errUnsupportedValue = encoder.ErrUnsupportedValue
16 errUnsupportedFloat = encoder.ErrUnsupportedFloat
17 mapiterinit = encoder.MapIterInit
18 mapiterkey = encoder.MapIterKey
19 mapitervalue = encoder.MapIterValue
20 mapiternext = encoder.MapIterNext
21 maplen = encoder.MapLen
22 )
23
24 type emptyInterface struct {
25 typ *runtime.Type
26 ptr unsafe.Pointer
27 }
28
29 type nonEmptyInterface struct {
30 itab *struct {
31 ityp *runtime.Type
32 typ *runtime.Type
33
34 }
35 ptr unsafe.Pointer
36 }
37
38 func errUnimplementedOp(op encoder.OpType) error {
39 return fmt.Errorf("encoder: opcode %s has not been implemented", op)
40 }
41
42 func load(base uintptr, idx uint32) uintptr {
43 addr := base + uintptr(idx)
44 return **(**uintptr)(unsafe.Pointer(&addr))
45 }
46
47 func store(base uintptr, idx uint32, p uintptr) {
48 addr := base + uintptr(idx)
49 **(**uintptr)(unsafe.Pointer(&addr)) = p
50 }
51
52 func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr {
53 addr := base + uintptr(idx)
54 p := **(**uintptr)(unsafe.Pointer(&addr))
55 for i := uint8(0); i < ptrNum; i++ {
56 if p == 0 {
57 return 0
58 }
59 p = ptrToPtr(p)
60 }
61 return p
62 }
63
64 func ptrToUint64(p uintptr, bitSize uint8) uint64 {
65 switch bitSize {
66 case 8:
67 return (uint64)(**(**uint8)(unsafe.Pointer(&p)))
68 case 16:
69 return (uint64)(**(**uint16)(unsafe.Pointer(&p)))
70 case 32:
71 return (uint64)(**(**uint32)(unsafe.Pointer(&p)))
72 case 64:
73 return **(**uint64)(unsafe.Pointer(&p))
74 }
75 return 0
76 }
77 func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) }
78 func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) }
79 func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) }
80 func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) }
81 func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) }
82 func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) }
83 func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) }
84 func ptrToPtr(p uintptr) uintptr {
85 return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
86 }
87 func ptrToNPtr(p uintptr, ptrNum uint8) uintptr {
88 for i := uint8(0); i < ptrNum; i++ {
89 if p == 0 {
90 return 0
91 }
92 p = ptrToPtr(p)
93 }
94 return p
95 }
96
97 func ptrToUnsafePtr(p uintptr) unsafe.Pointer {
98 return *(*unsafe.Pointer)(unsafe.Pointer(&p))
99 }
100 func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} {
101 return *(*interface{})(unsafe.Pointer(&emptyInterface{
102 typ: code.Type,
103 ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
104 }))
105 }
106
107 func appendInt(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte {
108 format := ctx.Option.ColorScheme.Int
109 b = append(b, format.Header...)
110 b = encoder.AppendInt(ctx, b, p, code)
111 return append(b, format.Footer...)
112 }
113
114 func appendUint(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte {
115 format := ctx.Option.ColorScheme.Uint
116 b = append(b, format.Header...)
117 b = encoder.AppendUint(ctx, b, p, code)
118 return append(b, format.Footer...)
119 }
120
121 func appendFloat32(ctx *encoder.RuntimeContext, b []byte, v float32) []byte {
122 format := ctx.Option.ColorScheme.Float
123 b = append(b, format.Header...)
124 b = encoder.AppendFloat32(ctx, b, v)
125 return append(b, format.Footer...)
126 }
127
128 func appendFloat64(ctx *encoder.RuntimeContext, b []byte, v float64) []byte {
129 format := ctx.Option.ColorScheme.Float
130 b = append(b, format.Header...)
131 b = encoder.AppendFloat64(ctx, b, v)
132 return append(b, format.Footer...)
133 }
134
135 func appendString(ctx *encoder.RuntimeContext, b []byte, v string) []byte {
136 format := ctx.Option.ColorScheme.String
137 b = append(b, format.Header...)
138 b = encoder.AppendString(ctx, b, v)
139 return append(b, format.Footer...)
140 }
141
142 func appendByteSlice(ctx *encoder.RuntimeContext, b []byte, src []byte) []byte {
143 format := ctx.Option.ColorScheme.Binary
144 b = append(b, format.Header...)
145 b = encoder.AppendByteSlice(ctx, b, src)
146 return append(b, format.Footer...)
147 }
148
149 func appendNumber(ctx *encoder.RuntimeContext, b []byte, n json.Number) ([]byte, error) {
150 format := ctx.Option.ColorScheme.Int
151 b = append(b, format.Header...)
152 bb, err := encoder.AppendNumber(ctx, b, n)
153 if err != nil {
154 return nil, err
155 }
156 return append(bb, format.Footer...), nil
157 }
158
159 func appendBool(ctx *encoder.RuntimeContext, b []byte, v bool) []byte {
160 format := ctx.Option.ColorScheme.Bool
161 b = append(b, format.Header...)
162 if v {
163 b = append(b, "true"...)
164 } else {
165 b = append(b, "false"...)
166 }
167 return append(b, format.Footer...)
168 }
169
170 func appendNull(ctx *encoder.RuntimeContext, b []byte) []byte {
171 format := ctx.Option.ColorScheme.Null
172 b = append(b, format.Header...)
173 b = append(b, "null"...)
174 return append(b, format.Footer...)
175 }
176
177 func appendComma(_ *encoder.RuntimeContext, b []byte) []byte {
178 return append(b, ',')
179 }
180
181 func appendNullComma(ctx *encoder.RuntimeContext, b []byte) []byte {
182 format := ctx.Option.ColorScheme.Null
183 b = append(b, format.Header...)
184 b = append(b, "null"...)
185 return append(append(b, format.Footer...), ',')
186 }
187
188 func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
189 last := len(b) - 1
190 b[last] = ':'
191 return b
192 }
193
194 func appendMapKeyValue(_ *encoder.RuntimeContext, _ *encoder.Opcode, b, key, value []byte) []byte {
195 b = append(b, key[:len(key)-1]...)
196 b = append(b, ':')
197 return append(b, value...)
198 }
199
200 func appendMapEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
201 last := len(b) - 1
202 b[last] = '}'
203 b = append(b, ',')
204 return b
205 }
206
207 func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
208 return encoder.AppendMarshalJSON(ctx, code, b, v)
209 }
210
211 func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
212 format := ctx.Option.ColorScheme.String
213 b = append(b, format.Header...)
214 bb, err := encoder.AppendMarshalText(ctx, code, b, v)
215 if err != nil {
216 return nil, err
217 }
218 return append(bb, format.Footer...), nil
219 }
220
221 func appendArrayHead(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
222 return append(b, '[')
223 }
224
225 func appendArrayEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
226 last := len(b) - 1
227 b[last] = ']'
228 return append(b, ',')
229 }
230
231 func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte {
232 return append(b, '[', ']', ',')
233 }
234
235 func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte {
236 return append(b, '{', '}', ',')
237 }
238
239 func appendObjectEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
240 last := len(b) - 1
241 b[last] = '}'
242 return append(b, ',')
243 }
244
245 func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte {
246 return append(b, '{')
247 }
248
249 func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
250 format := ctx.Option.ColorScheme.ObjectKey
251 b = append(b, format.Header...)
252 b = append(b, code.Key[:len(code.Key)-1]...)
253 b = append(b, format.Footer...)
254
255 return append(b, ':')
256 }
257
258 func appendStructEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
259 return append(b, '}', ',')
260 }
261
262 func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
263 last := len(b) - 1
264 if b[last] == ',' {
265 b[last] = '}'
266 return appendComma(ctx, b)
267 }
268 return appendStructEnd(ctx, code, b)
269 }
270
271 func restoreIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, _ uintptr) {}
272 func storeIndent(_ uintptr, _ *encoder.Opcode, _ uintptr) {}
273 func appendMapKeyIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b }
274 func appendArrayElemIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b }
275
View as plain text