WIP: Integrate int/uint operation

This commit is contained in:
Masaaki Goshima 2021-02-19 03:06:21 +09:00
parent 58a761643a
commit 0272fd00f4
7 changed files with 650 additions and 20452 deletions

View File

@ -3,6 +3,7 @@ package json
import (
"encoding"
"fmt"
"math"
"reflect"
"strings"
"unsafe"
@ -52,6 +53,24 @@ func encodeCompileToGetCodeSetSlowPath(typeptr uintptr) (*opcodeSet, error) {
return codeSet, nil
}
func isIntOrUintType(typ *rtype) bool {
switch typ.Kind() {
case reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64,
reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Uintptr:
return true
}
return false
}
func encodeCompileHead(ctx *encodeCompileContext) (*opcode, error) {
typ := ctx.typ
switch {
@ -85,6 +104,8 @@ func encodeCompileHead(ctx *encodeCompileContext) (*opcode, error) {
typ = orgType
} else if isPtr && typ.Implements(marshalJSONType) {
typ = orgType
} else if isPtr && isIntOrUintType(typ) {
//typ = orgType
}
code, err := encodeCompile(ctx.withType(typ))
if err != nil {
@ -393,62 +414,96 @@ func encodeCompileMarshalTextPtr(ctx *encodeCompileContext) (*opcode, error) {
return code, nil
}
const intSize = 32 << (^uint(0) >> 63)
func encodeCompileInt(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opInt)
switch intSize {
case 32:
code.mask = math.MaxUint32
code.rshiftNum = 31
default:
code.mask = math.MaxUint64
code.rshiftNum = 63
}
ctx.incIndex()
return code, nil
}
func encodeCompileInt8(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opInt8)
code := newOpCode(ctx, opInt)
code.mask = math.MaxUint8
code.rshiftNum = 7
ctx.incIndex()
return code, nil
}
func encodeCompileInt16(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opInt16)
code := newOpCode(ctx, opInt)
code.mask = math.MaxUint16
code.rshiftNum = 15
ctx.incIndex()
return code, nil
}
func encodeCompileInt32(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opInt32)
code := newOpCode(ctx, opInt)
code.mask = math.MaxUint32
code.rshiftNum = 31
ctx.incIndex()
return code, nil
}
func encodeCompileInt64(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opInt64)
code := newOpCode(ctx, opInt)
code.mask = math.MaxUint64
code.rshiftNum = 63
ctx.incIndex()
return code, nil
}
func encodeCompileUint(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opUint)
switch intSize {
case 32:
code.mask = math.MaxUint32
code.rshiftNum = 31
default:
code.mask = math.MaxUint64
code.rshiftNum = 63
}
ctx.incIndex()
return code, nil
}
func encodeCompileUint8(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opUint8)
code := newOpCode(ctx, opUint)
code.mask = math.MaxUint8
code.rshiftNum = 7
ctx.incIndex()
return code, nil
}
func encodeCompileUint16(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opUint16)
code := newOpCode(ctx, opUint)
code.mask = math.MaxUint16
code.rshiftNum = 15
ctx.incIndex()
return code, nil
}
func encodeCompileUint32(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opUint32)
code := newOpCode(ctx, opUint)
code.mask = math.MaxUint32
code.rshiftNum = 31
ctx.incIndex()
return code, nil
}
func encodeCompileUint64(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opUint64)
code := newOpCode(ctx, opUint)
code.mask = math.MaxUint64
code.rshiftNum = 63
ctx.incIndex()
return code, nil
}
@ -460,19 +515,19 @@ func encodeCompileIntString(ctx *encodeCompileContext) (*opcode, error) {
}
func encodeCompileInt8String(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opInt8String)
code := newOpCode(ctx, opIntString)
ctx.incIndex()
return code, nil
}
func encodeCompileInt16String(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opInt16String)
code := newOpCode(ctx, opIntString)
ctx.incIndex()
return code, nil
}
func encodeCompileInt32String(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opInt32String)
code := newOpCode(ctx, opIntString)
ctx.incIndex()
return code, nil
}
@ -490,25 +545,25 @@ func encodeCompileUintString(ctx *encodeCompileContext) (*opcode, error) {
}
func encodeCompileUint8String(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opUint8String)
code := newOpCode(ctx, opUintString)
ctx.incIndex()
return code, nil
}
func encodeCompileUint16String(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opUint16String)
code := newOpCode(ctx, opUintString)
ctx.incIndex()
return code, nil
}
func encodeCompileUint32String(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opUint32String)
code := newOpCode(ctx, opUintString)
ctx.incIndex()
return code, nil
}
func encodeCompileUint64String(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opUint64String)
code := newOpCode(ctx, opUintString)
ctx.incIndex()
return code, nil
}
@ -697,25 +752,12 @@ func encodeTypeToHeaderType(ctx *encodeCompileContext, code *opcode) opType {
if ptrNum > 1 {
switch code.next.op {
case opInt:
c.mask = code.next.mask
c.rshiftNum = code.next.rshiftNum
return opStructFieldHeadIntNPtr
case opInt8:
return opStructFieldHeadInt8NPtr
case opInt16:
return opStructFieldHeadInt16NPtr
case opInt32:
return opStructFieldHeadInt32NPtr
case opInt64:
return opStructFieldHeadInt64NPtr
case opUint:
c.mask = code.next.mask
return opStructFieldHeadUintNPtr
case opUint8:
return opStructFieldHeadUint8NPtr
case opUint16:
return opStructFieldHeadUint16NPtr
case opUint32:
return opStructFieldHeadUint32NPtr
case opUint64:
return opStructFieldHeadUint64NPtr
case opFloat32:
return opStructFieldHeadFloat32NPtr
case opFloat64:
@ -728,25 +770,12 @@ func encodeTypeToHeaderType(ctx *encodeCompileContext, code *opcode) opType {
} else {
switch code.next.op {
case opInt:
c.mask = code.next.mask
c.rshiftNum = code.next.rshiftNum
return opStructFieldHeadIntPtr
case opInt8:
return opStructFieldHeadInt8Ptr
case opInt16:
return opStructFieldHeadInt16Ptr
case opInt32:
return opStructFieldHeadInt32Ptr
case opInt64:
return opStructFieldHeadInt64Ptr
case opUint:
c.mask = code.next.mask
return opStructFieldHeadUintPtr
case opUint8:
return opStructFieldHeadUint8Ptr
case opUint16:
return opStructFieldHeadUint16Ptr
case opUint32:
return opStructFieldHeadUint32Ptr
case opUint64:
return opStructFieldHeadUint64Ptr
case opFloat32:
return opStructFieldHeadFloat32Ptr
case opFloat64:
@ -759,24 +788,8 @@ func encodeTypeToHeaderType(ctx *encodeCompileContext, code *opcode) opType {
}
case opInt:
return opStructFieldHeadInt
case opInt8:
return opStructFieldHeadInt8
case opInt16:
return opStructFieldHeadInt16
case opInt32:
return opStructFieldHeadInt32
case opInt64:
return opStructFieldHeadInt64
case opUint:
return opStructFieldHeadUint
case opUint8:
return opStructFieldHeadUint8
case opUint16:
return opStructFieldHeadUint16
case opUint32:
return opStructFieldHeadUint32
case opUint64:
return opStructFieldHeadUint64
case opFloat32:
return opStructFieldHeadFloat32
case opFloat64:
@ -822,25 +835,12 @@ func encodeTypeToFieldType(ctx *encodeCompileContext, code *opcode) opType {
if ptrNum > 1 {
switch code.next.op {
case opInt:
c.mask = code.next.mask
c.rshiftNum = code.next.rshiftNum
return opStructFieldIntNPtr
case opInt8:
return opStructFieldInt8NPtr
case opInt16:
return opStructFieldInt16NPtr
case opInt32:
return opStructFieldInt32NPtr
case opInt64:
return opStructFieldInt64NPtr
case opUint:
c.mask = code.next.mask
return opStructFieldUintNPtr
case opUint8:
return opStructFieldUint8NPtr
case opUint16:
return opStructFieldUint16NPtr
case opUint32:
return opStructFieldUint32NPtr
case opUint64:
return opStructFieldUint64NPtr
case opFloat32:
return opStructFieldFloat32NPtr
case opFloat64:
@ -853,25 +853,12 @@ func encodeTypeToFieldType(ctx *encodeCompileContext, code *opcode) opType {
} else {
switch code.next.op {
case opInt:
c.mask = code.next.mask
c.rshiftNum = code.next.rshiftNum
return opStructFieldIntPtr
case opInt8:
return opStructFieldInt8Ptr
case opInt16:
return opStructFieldInt16Ptr
case opInt32:
return opStructFieldInt32Ptr
case opInt64:
return opStructFieldInt64Ptr
case opUint:
c.mask = code.next.mask
return opStructFieldUintPtr
case opUint8:
return opStructFieldUint8Ptr
case opUint16:
return opStructFieldUint16Ptr
case opUint32:
return opStructFieldUint32Ptr
case opUint64:
return opStructFieldUint64Ptr
case opFloat32:
return opStructFieldFloat32Ptr
case opFloat64:
@ -884,24 +871,8 @@ func encodeTypeToFieldType(ctx *encodeCompileContext, code *opcode) opType {
}
case opInt:
return opStructFieldInt
case opInt8:
return opStructFieldInt8
case opInt16:
return opStructFieldInt16
case opInt32:
return opStructFieldInt32
case opInt64:
return opStructFieldInt64
case opUint:
return opStructFieldUint
case opUint8:
return opStructFieldUint8
case opUint16:
return opStructFieldUint16
case opUint32:
return opStructFieldUint32
case opUint64:
return opStructFieldUint64
case opFloat32:
return opStructFieldFloat32
case opFloat64:
@ -969,6 +940,8 @@ func encodeStructHeader(ctx *encodeCompileContext, fieldCode *opcode, valueCode
fieldCode.indent--
op := encodeOptimizeStructHeader(ctx, valueCode, tag)
fieldCode.op = op
fieldCode.mask = valueCode.mask
fieldCode.rshiftNum = valueCode.rshiftNum
fieldCode.ptrNum = valueCode.ptrNum
switch op {
case opStructFieldHead,
@ -995,6 +968,8 @@ func encodeStructField(ctx *encodeCompileContext, fieldCode *opcode, valueCode *
op := encodeOptimizeStructField(ctx, valueCode, tag)
fieldCode.op = op
fieldCode.ptrNum = valueCode.ptrNum
fieldCode.mask = valueCode.mask
fieldCode.rshiftNum = valueCode.rshiftNum
switch op {
case opStructField,
opStructFieldSlice,

View File

@ -49,9 +49,7 @@ var intBELookup = [100]uint16{
var intLookup = [2]*[100]uint16{&intLELookup, &intBELookup}
func appendInt(b []byte, n int64) []byte {
return formatInteger(b, uint64(n), n < 0)
}
var appendInt = formatInteger
func appendUint(b []byte, n uint64) []byte {
return formatInteger(b, n, false)

View File

@ -20,6 +20,8 @@ type opcode struct {
anonymousKey bool // whether anonymous key
root bool // whether root
indent int // indent number
rshiftNum uint8 // use to take bit for judging whether negative integer or not
mask uint64 // mask for number
idx uintptr // offset to access ptr
headIdx uintptr // offset to access slice/struct head
@ -84,6 +86,8 @@ func (c *opcode) copy(codeMap map[uintptr]*opcode) *opcode {
escapedKey: c.escapedKey,
displayKey: c.displayKey,
ptrNum: c.ptrNum,
mask: c.mask,
rshiftNum: c.rshiftNum,
isTaggedKey: c.isTaggedKey,
anonymousKey: c.anonymousKey,
root: c.root,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff