diff --git a/internal/encoder/vm/util.go b/internal/encoder/vm/util.go new file mode 100644 index 0000000..d9c5449 --- /dev/null +++ b/internal/encoder/vm/util.go @@ -0,0 +1,78 @@ +package vm + +import ( + "encoding/json" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +func load(base uintptr, idx uintptr) uintptr { + addr := base + idx + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uintptr, p uintptr) { + addr := base + idx + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uintptr, ptrNum int) uintptr { + addr := base + idx + p := **(**uintptr)(unsafe.Pointer(&addr)) + if p == 0 { + return 0 + } + return ptrToPtr(p) +} + +func ptrToUint64(p uintptr) uint64 { return **(**uint64)(unsafe.Pointer(&p)) } +func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum int) uintptr { + for i := 0; i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func appendBool(b []byte, v bool) []byte { + if v { + return append(b, "true"...) + } + return append(b, "false"...) +} + +func appendNull(b []byte) []byte { + return append(b, "null"...) +} + +func appendComma(b []byte) []byte { + return append(b, ',') +} + +func appendStructEnd(b []byte) []byte { + return append(b, '}', ',') +} diff --git a/internal/encoder/vm/vm.go b/internal/encoder/vm/vm.go index a03459c..248cc25 100644 --- a/internal/encoder/vm/vm.go +++ b/internal/encoder/vm/vm.go @@ -21,34 +21,15 @@ import ( const uintptrSize = 4 << (^uintptr(0) >> 63) var ( - load = encoder.Load - store = encoder.Store - loadNPtr = encoder.LoadNPtr - ptrToPtr = encoder.PtrToPtr - ptrToNPtr = encoder.PtrToNPtr - ptrToUnsafePtr = encoder.PtrToUnsafePtr - ptrToInterface = encoder.PtrToInterface - ptrToUint64 = encoder.PtrToUint64 - ptrToFloat32 = encoder.PtrToFloat32 - ptrToFloat64 = encoder.PtrToFloat64 - ptrToString = encoder.PtrToString - ptrToBool = encoder.PtrToBool - ptrToBytes = encoder.PtrToBytes - ptrToNumber = encoder.PtrToNumber - ptrToSlice = encoder.PtrToSlice appendInt = encoder.AppendInt appendUint = encoder.AppendUint appendFloat32 = encoder.AppendFloat32 appendFloat64 = encoder.AppendFloat64 appendString = encoder.AppendString - appendBool = encoder.AppendBool appendByteSlice = encoder.AppendByteSlice appendNumber = encoder.AppendNumber appendMarshalJSON = encoder.AppendMarshalJSON appendMarshalText = encoder.AppendMarshalText - appendNull = encoder.AppendNull - appendComma = encoder.AppendComma - appendStructEnd = encoder.AppendStructEnd errUnsupportedValue = encoder.ErrUnsupportedValue errUnsupportedFloat = encoder.ErrUnsupportedFloat mapiterinit = encoder.MapIterInit diff --git a/internal/encoder/vm_escaped/util.go b/internal/encoder/vm_escaped/util.go new file mode 100644 index 0000000..437154e --- /dev/null +++ b/internal/encoder/vm_escaped/util.go @@ -0,0 +1,78 @@ +package vm_escaped + +import ( + "encoding/json" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +func load(base uintptr, idx uintptr) uintptr { + addr := base + idx + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uintptr, p uintptr) { + addr := base + idx + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uintptr, ptrNum int) uintptr { + addr := base + idx + p := **(**uintptr)(unsafe.Pointer(&addr)) + if p == 0 { + return 0 + } + return ptrToPtr(p) +} + +func ptrToUint64(p uintptr) uint64 { return **(**uint64)(unsafe.Pointer(&p)) } +func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum int) uintptr { + for i := 0; i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func appendBool(b []byte, v bool) []byte { + if v { + return append(b, "true"...) + } + return append(b, "false"...) +} + +func appendNull(b []byte) []byte { + return append(b, "null"...) +} + +func appendComma(b []byte) []byte { + return append(b, ',') +} + +func appendStructEnd(b []byte) []byte { + return append(b, '}', ',') +} diff --git a/internal/encoder/vm_escaped/vm.go b/internal/encoder/vm_escaped/vm.go index 59edf0e..675effb 100644 --- a/internal/encoder/vm_escaped/vm.go +++ b/internal/encoder/vm_escaped/vm.go @@ -21,34 +21,15 @@ import ( const uintptrSize = 4 << (^uintptr(0) >> 63) var ( - load = encoder.Load - store = encoder.Store - loadNPtr = encoder.LoadNPtr - ptrToPtr = encoder.PtrToPtr - ptrToNPtr = encoder.PtrToNPtr - ptrToUnsafePtr = encoder.PtrToUnsafePtr - ptrToInterface = encoder.PtrToInterface - ptrToUint64 = encoder.PtrToUint64 - ptrToFloat32 = encoder.PtrToFloat32 - ptrToFloat64 = encoder.PtrToFloat64 - ptrToString = encoder.PtrToString - ptrToBool = encoder.PtrToBool - ptrToBytes = encoder.PtrToBytes - ptrToNumber = encoder.PtrToNumber - ptrToSlice = encoder.PtrToSlice appendInt = encoder.AppendInt appendUint = encoder.AppendUint appendFloat32 = encoder.AppendFloat32 appendFloat64 = encoder.AppendFloat64 appendString = encoder.AppendEscapedString - appendBool = encoder.AppendBool appendByteSlice = encoder.AppendByteSlice appendNumber = encoder.AppendNumber appendMarshalJSON = encoder.AppendMarshalJSON appendMarshalText = encoder.AppendMarshalText - appendNull = encoder.AppendNull - appendComma = encoder.AppendComma - appendStructEnd = encoder.AppendStructEnd errUnsupportedValue = encoder.ErrUnsupportedValue errUnsupportedFloat = encoder.ErrUnsupportedFloat mapiterinit = encoder.MapIterInit diff --git a/internal/encoder/vm_escaped_indent/util.go b/internal/encoder/vm_escaped_indent/util.go new file mode 100644 index 0000000..ba004cd --- /dev/null +++ b/internal/encoder/vm_escaped_indent/util.go @@ -0,0 +1,87 @@ +package vm_escaped_indent + +import ( + "bytes" + "encoding/json" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +func load(base uintptr, idx uintptr) uintptr { + addr := base + idx + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uintptr, p uintptr) { + addr := base + idx + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uintptr, ptrNum int) uintptr { + addr := base + idx + p := **(**uintptr)(unsafe.Pointer(&addr)) + if p == 0 { + return 0 + } + return ptrToPtr(p) +} + +func ptrToUint64(p uintptr) uint64 { return **(**uint64)(unsafe.Pointer(&p)) } +func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum int) uintptr { + for i := 0; i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func appendBool(b []byte, v bool) []byte { + if v { + return append(b, "true"...) + } + return append(b, "false"...) +} + +func appendNull(b []byte) []byte { + return append(b, "null"...) +} + +func appendComma(b []byte) []byte { + return append(b, ',', '\n') +} + +func appendStructEnd(ctx *encoder.RuntimeContext, b []byte, indent int) []byte { + b = append(b, '\n') + b = append(b, ctx.Prefix...) + b = append(b, bytes.Repeat(ctx.IndentStr, ctx.BaseIndent+indent)...) + return append(b, '}', ',', '\n') +} + +func appendIndent(ctx *encoder.RuntimeContext, b []byte, indent int) []byte { + b = append(b, ctx.Prefix...) + return append(b, bytes.Repeat(ctx.IndentStr, ctx.BaseIndent+indent)...) +} diff --git a/internal/encoder/vm_escaped_indent/vm.go b/internal/encoder/vm_escaped_indent/vm.go index 992d1bc..d1cccde 100644 --- a/internal/encoder/vm_escaped_indent/vm.go +++ b/internal/encoder/vm_escaped_indent/vm.go @@ -16,35 +16,15 @@ import ( const uintptrSize = 4 << (^uintptr(0) >> 63) var ( - load = encoder.Load - store = encoder.Store - loadNPtr = encoder.LoadNPtr - ptrToPtr = encoder.PtrToPtr - ptrToNPtr = encoder.PtrToNPtr - ptrToUnsafePtr = encoder.PtrToUnsafePtr - ptrToInterface = encoder.PtrToInterface - ptrToUint64 = encoder.PtrToUint64 - ptrToFloat32 = encoder.PtrToFloat32 - ptrToFloat64 = encoder.PtrToFloat64 - ptrToString = encoder.PtrToString - ptrToBool = encoder.PtrToBool - ptrToBytes = encoder.PtrToBytes - ptrToNumber = encoder.PtrToNumber - ptrToSlice = encoder.PtrToSlice appendInt = encoder.AppendInt appendUint = encoder.AppendUint appendFloat32 = encoder.AppendFloat32 appendFloat64 = encoder.AppendFloat64 appendString = encoder.AppendEscapedString - appendBool = encoder.AppendBool appendByteSlice = encoder.AppendByteSlice appendNumber = encoder.AppendNumber appendMarshalJSON = encoder.AppendMarshalJSONIndent appendMarshalText = encoder.AppendMarshalTextIndent - appendNull = encoder.AppendNull - appendComma = encoder.AppendCommaIndent - appendIndent = encoder.AppendIndent - appendStructEnd = encoder.AppendStructEndIndent errUnsupportedValue = encoder.ErrUnsupportedValue errUnsupportedFloat = encoder.ErrUnsupportedFloat mapiterinit = encoder.MapIterInit diff --git a/internal/encoder/vm_indent/util.go b/internal/encoder/vm_indent/util.go new file mode 100644 index 0000000..dcf976e --- /dev/null +++ b/internal/encoder/vm_indent/util.go @@ -0,0 +1,87 @@ +package vm_indent + +import ( + "bytes" + "encoding/json" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +func load(base uintptr, idx uintptr) uintptr { + addr := base + idx + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uintptr, p uintptr) { + addr := base + idx + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uintptr, ptrNum int) uintptr { + addr := base + idx + p := **(**uintptr)(unsafe.Pointer(&addr)) + if p == 0 { + return 0 + } + return ptrToPtr(p) +} + +func ptrToUint64(p uintptr) uint64 { return **(**uint64)(unsafe.Pointer(&p)) } +func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum int) uintptr { + for i := 0; i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func appendBool(b []byte, v bool) []byte { + if v { + return append(b, "true"...) + } + return append(b, "false"...) +} + +func appendNull(b []byte) []byte { + return append(b, "null"...) +} + +func appendComma(b []byte) []byte { + return append(b, ',', '\n') +} + +func appendStructEnd(ctx *encoder.RuntimeContext, b []byte, indent int) []byte { + b = append(b, '\n') + b = append(b, ctx.Prefix...) + b = append(b, bytes.Repeat(ctx.IndentStr, ctx.BaseIndent+indent)...) + return append(b, '}', ',', '\n') +} + +func appendIndent(ctx *encoder.RuntimeContext, b []byte, indent int) []byte { + b = append(b, ctx.Prefix...) + return append(b, bytes.Repeat(ctx.IndentStr, ctx.BaseIndent+indent)...) +} diff --git a/internal/encoder/vm_indent/vm.go b/internal/encoder/vm_indent/vm.go index 52e7869..026bd7a 100644 --- a/internal/encoder/vm_indent/vm.go +++ b/internal/encoder/vm_indent/vm.go @@ -22,35 +22,15 @@ import ( const uintptrSize = 4 << (^uintptr(0) >> 63) var ( - load = encoder.Load - store = encoder.Store - loadNPtr = encoder.LoadNPtr - ptrToPtr = encoder.PtrToPtr - ptrToNPtr = encoder.PtrToNPtr - ptrToUnsafePtr = encoder.PtrToUnsafePtr - ptrToInterface = encoder.PtrToInterface - ptrToUint64 = encoder.PtrToUint64 - ptrToFloat32 = encoder.PtrToFloat32 - ptrToFloat64 = encoder.PtrToFloat64 - ptrToString = encoder.PtrToString - ptrToBool = encoder.PtrToBool - ptrToBytes = encoder.PtrToBytes - ptrToNumber = encoder.PtrToNumber - ptrToSlice = encoder.PtrToSlice appendInt = encoder.AppendInt appendUint = encoder.AppendUint appendFloat32 = encoder.AppendFloat32 appendFloat64 = encoder.AppendFloat64 appendString = encoder.AppendString - appendBool = encoder.AppendBool appendByteSlice = encoder.AppendByteSlice appendNumber = encoder.AppendNumber appendMarshalJSON = encoder.AppendMarshalJSONIndent appendMarshalText = encoder.AppendMarshalTextIndent - appendNull = encoder.AppendNull - appendComma = encoder.AppendCommaIndent - appendIndent = encoder.AppendIndent - appendStructEnd = encoder.AppendStructEndIndent errUnsupportedValue = encoder.ErrUnsupportedValue errUnsupportedFloat = encoder.ErrUnsupportedFloat mapiterinit = encoder.MapIterInit