Add EmptyStruct operation

This commit is contained in:
Masaaki Goshima 2021-02-22 00:55:20 +09:00
parent ef165af9cd
commit 6990aa6938
5 changed files with 661 additions and 9 deletions

View File

@ -238,6 +238,9 @@ func encodeConvertHeadOnlyCode(c *opcode, isPtrHead bool) {
if strings.Contains(c.op.String(), "Map") { if strings.Contains(c.op.String(), "Map") {
return return
} }
if strings.Contains(c.op.String(), "EmptyStruct") {
return
}
isPtrOp := strings.Contains(c.op.String(), "Ptr") isPtrOp := strings.Contains(c.op.String(), "Ptr")
if isPtrOp && !isPtrHead { if isPtrOp && !isPtrHead {
@ -628,6 +631,12 @@ func encodeCompileBytes(ctx *encodeCompileContext) (*opcode, error) {
return code, nil return code, nil
} }
func encodeCompileEmptyStruct(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opEmptyStruct)
ctx.incIndex()
return code, nil
}
func encodeCompileInterface(ctx *encodeCompileContext) (*opcode, error) { func encodeCompileInterface(ctx *encodeCompileContext) (*opcode, error) {
code := newInterfaceCode(ctx) code := newInterfaceCode(ctx)
ctx.incIndex() ctx.incIndex()
@ -814,6 +823,8 @@ func encodeTypeToHeaderType(ctx *encodeCompileContext, code *opcode) opType {
return opStructFieldHeadStringPtr return opStructFieldHeadStringPtr
case opBool: case opBool:
return opStructFieldHeadBoolPtr return opStructFieldHeadBoolPtr
case opEmptyStruct:
return opStructFieldHeadEmptyStructPtr
} }
} }
case opInt: case opInt:
@ -828,6 +839,8 @@ func encodeTypeToHeaderType(ctx *encodeCompileContext, code *opcode) opType {
return opStructFieldHeadString return opStructFieldHeadString
case opBool: case opBool:
return opStructFieldHeadBool return opStructFieldHeadBool
case opEmptyStruct:
return opStructFieldHeadEmptyStruct
case opMapHead: case opMapHead:
return opStructFieldHeadMap return opStructFieldHeadMap
case opMapHeadLoad: case opMapHeadLoad:
@ -836,8 +849,6 @@ func encodeTypeToHeaderType(ctx *encodeCompileContext, code *opcode) opType {
return opStructFieldHeadArray return opStructFieldHeadArray
case opSliceHead: case opSliceHead:
return opStructFieldHeadSlice return opStructFieldHeadSlice
case opStructFieldHead:
return opStructFieldHeadStruct
case opMarshalJSON: case opMarshalJSON:
return opStructFieldHeadMarshalJSON return opStructFieldHeadMarshalJSON
case opMarshalText: case opMarshalText:
@ -897,6 +908,8 @@ func encodeTypeToFieldType(ctx *encodeCompileContext, code *opcode) opType {
return opStructFieldStringPtr return opStructFieldStringPtr
case opBool: case opBool:
return opStructFieldBoolPtr return opStructFieldBoolPtr
case opEmptyStruct:
return opStructFieldEmptyStructPtr
} }
} }
case opInt: case opInt:
@ -911,6 +924,8 @@ func encodeTypeToFieldType(ctx *encodeCompileContext, code *opcode) opType {
return opStructFieldString return opStructFieldString
case opBool: case opBool:
return opStructFieldBool return opStructFieldBool
case opEmptyStruct:
return opStructFieldEmptyStruct
case opMapHead: case opMapHead:
return opStructFieldMap return opStructFieldMap
case opMapHeadLoad: case opMapHeadLoad:
@ -919,8 +934,6 @@ func encodeTypeToFieldType(ctx *encodeCompileContext, code *opcode) opType {
return opStructFieldArray return opStructFieldArray
case opSliceHead: case opSliceHead:
return opStructFieldSlice return opStructFieldSlice
case opStructFieldHead:
return opStructFieldStruct
case opMarshalJSON: case opMarshalJSON:
return opStructFieldMarshalJSON return opStructFieldMarshalJSON
case opMarshalText: case opMarshalText:
@ -1220,13 +1233,16 @@ func encodeCompileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode, error)
return code, nil return code, nil
} }
typ := ctx.typ typ := ctx.typ
fieldNum := typ.NumField()
if fieldNum == 0 {
return encodeCompileEmptyStruct(ctx)
}
typeptr := uintptr(unsafe.Pointer(typ)) typeptr := uintptr(unsafe.Pointer(typ))
compiled := &compiledCode{} compiled := &compiledCode{}
ctx.structTypeToCompiledCode[typeptr] = compiled ctx.structTypeToCompiledCode[typeptr] = compiled
// header => code => structField => code => end // header => code => structField => code => end
// ^ | // ^ |
// |__________| // |__________|
fieldNum := typ.NumField()
fieldIdx := 0 fieldIdx := 0
var ( var (
head *opcode head *opcode

View File

@ -142,6 +142,10 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco
} }
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opEmptyStruct:
b = append(b, '{', '}')
b = encodeComma(b)
code = code.next
case opInterface: case opInterface:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
if ptr == 0 { if ptr == 0 {
@ -3357,6 +3361,64 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
} }
case opStructFieldPtrHeadEmptyStruct:
p := load(ctxptr, code.idx)
if p == 0 {
b = encodeNull(b)
b = encodeComma(b)
code = code.end.next
break
}
store(ctxptr, code.idx, ptrToPtr(p))
fallthrough
case opStructFieldHeadEmptyStruct:
b = append(b, '{')
b = append(b, code.key...)
b = append(b, '{', '}')
b = encodeComma(b)
code = code.next
case opStructFieldPtrHeadEmptyStructPtr:
store(ctxptr, code.idx, ptrToPtr(load(ctxptr, code.idx)))
fallthrough
case opStructFieldHeadEmptyStructPtr:
p := load(ctxptr, code.idx)
if p == 0 {
b = encodeNull(b)
b = encodeComma(b)
code = code.end.next
break
} else {
b = append(b, '{')
b = append(b, code.key...)
p = ptrToPtr(p)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, '{', '}')
}
}
b = encodeComma(b)
code = code.next
case opStructFieldPtrHeadOmitEmptyEmptyStructPtr:
store(ctxptr, code.idx, ptrToPtr(load(ctxptr, code.idx)))
fallthrough
case opStructFieldHeadOmitEmptyEmptyStructPtr:
p := load(ctxptr, code.idx)
if p == 0 {
b = encodeNull(b)
b = encodeComma(b)
code = code.end.next
break
} else {
p = ptrToPtr(p)
b = append(b, '{')
if p != 0 {
b = append(b, code.key...)
b = append(b, '{', '}')
}
}
b = encodeComma(b)
code = code.next
case opStructFieldPtrHeadArray: case opStructFieldPtrHeadArray:
p := load(ctxptr, code.idx) p := load(ctxptr, code.idx)
if p == 0 { if p == 0 {
@ -4453,6 +4515,52 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco
} }
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opStructFieldEmptyStruct:
b = append(b, code.key...)
b = append(b, '{', '}')
b = encodeComma(b)
code = code.next
case opStructFieldOmitEmptyEmptyStruct:
b = append(b, code.key...)
b = append(b, '{', '}')
b = encodeComma(b)
code = code.next
case opStructFieldStringTagEmptyStruct:
b = append(b, code.key...)
b = append(b, `"{}"`...)
b = encodeComma(b)
code = code.next
case opStructFieldEmptyStructPtr:
b = append(b, code.key...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, '{', '}')
}
b = encodeComma(b)
code = code.next
case opStructFieldOmitEmptyEmptyStructPtr:
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p != 0 {
b = append(b, code.key...)
b = append(b, '{', '}')
b = encodeComma(b)
}
code = code.next
case opStructFieldStringTagEmptyStructPtr:
b = append(b, code.key...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, `"{}"`...)
}
b = encodeComma(b)
code = code.next
case opStructFieldMarshalJSON: case opStructFieldMarshalJSON:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
b = append(b, code.key...) b = append(b, code.key...)
@ -5215,6 +5323,52 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco
b = encodeByteSlice(b, v) b = encodeByteSlice(b, v)
b = appendStructEnd(b) b = appendStructEnd(b)
code = code.next code = code.next
case opStructEndEmptyStruct:
b = append(b, code.key...)
b = append(b, '{', '}')
b = appendStructEnd(b)
code = code.next
case opStructEndOmitEmptyEmptyStruct:
b = append(b, code.key...)
b = append(b, '{', '}')
b = appendStructEnd(b)
code = code.next
case opStructEndStringTagEmptyStruct:
b = append(b, code.key...)
b = append(b, `"{}"`...)
b = appendStructEnd(b)
code = code.next
case opStructEndEmptyStructPtr:
b = append(b, code.key...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, '{', '}')
}
b = appendStructEnd(b)
code = code.next
case opStructEndOmitEmptyEmptyStructPtr:
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p != 0 {
b = append(b, code.key...)
b = append(b, '{', '}')
b = appendStructEnd(b)
}
code = code.next
case opStructEndStringTagEmptyStructPtr:
b = append(b, code.key...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, `"{}"`...)
}
b = appendStructEnd(b)
code = code.next
case opStructEndMarshalJSON: case opStructEndMarshalJSON:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
b = append(b, code.key...) b = append(b, code.key...)

View File

@ -76,6 +76,10 @@ func encodeRunEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, o
} }
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opEmptyStruct:
b = append(b, '{', '}')
b = encodeComma(b)
code = code.next
case opInterface: case opInterface:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
if ptr == 0 { if ptr == 0 {
@ -3295,6 +3299,64 @@ func encodeRunEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, o
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
} }
case opStructFieldPtrHeadEmptyStruct:
p := load(ctxptr, code.idx)
if p == 0 {
b = encodeNull(b)
b = encodeComma(b)
code = code.end.next
break
}
store(ctxptr, code.idx, ptrToPtr(p))
fallthrough
case opStructFieldHeadEmptyStruct:
b = append(b, '{')
b = append(b, code.escapedKey...)
b = append(b, '{', '}')
b = encodeComma(b)
code = code.next
case opStructFieldPtrHeadEmptyStructPtr:
store(ctxptr, code.idx, ptrToPtr(load(ctxptr, code.idx)))
fallthrough
case opStructFieldHeadEmptyStructPtr:
p := load(ctxptr, code.idx)
if p == 0 {
b = encodeNull(b)
b = encodeComma(b)
code = code.end.next
break
} else {
b = append(b, '{')
b = append(b, code.escapedKey...)
p = ptrToPtr(p)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, '{', '}')
}
}
b = encodeComma(b)
code = code.next
case opStructFieldPtrHeadOmitEmptyEmptyStructPtr:
store(ctxptr, code.idx, ptrToPtr(load(ctxptr, code.idx)))
fallthrough
case opStructFieldHeadOmitEmptyEmptyStructPtr:
p := load(ctxptr, code.idx)
if p == 0 {
b = encodeNull(b)
b = encodeComma(b)
code = code.end.next
break
} else {
p = ptrToPtr(p)
b = append(b, '{')
if p != 0 {
b = append(b, code.escapedKey...)
b = append(b, '{', '}')
}
}
b = encodeComma(b)
code = code.next
case opStructFieldPtrHeadArray: case opStructFieldPtrHeadArray:
p := load(ctxptr, code.idx) p := load(ctxptr, code.idx)
if p == 0 { if p == 0 {
@ -4387,6 +4449,52 @@ func encodeRunEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, o
} }
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opStructFieldEmptyStruct:
b = append(b, code.escapedKey...)
b = append(b, '{', '}')
b = encodeComma(b)
code = code.next
case opStructFieldOmitEmptyEmptyStruct:
b = append(b, code.escapedKey...)
b = append(b, '{', '}')
b = encodeComma(b)
code = code.next
case opStructFieldStringTagEmptyStruct:
b = append(b, code.escapedKey...)
b = append(b, `"{}"`...)
b = encodeComma(b)
code = code.next
case opStructFieldEmptyStructPtr:
b = append(b, code.escapedKey...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, '{', '}')
}
b = encodeComma(b)
code = code.next
case opStructFieldOmitEmptyEmptyStructPtr:
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p != 0 {
b = append(b, code.escapedKey...)
b = append(b, '{', '}')
b = encodeComma(b)
}
code = code.next
case opStructFieldStringTagEmptyStructPtr:
b = append(b, code.escapedKey...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, `"{}"`...)
}
b = encodeComma(b)
code = code.next
case opStructFieldMarshalJSON: case opStructFieldMarshalJSON:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
b = append(b, code.escapedKey...) b = append(b, code.escapedKey...)
@ -5158,6 +5266,52 @@ func encodeRunEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, o
b = encodeByteSlice(b, v) b = encodeByteSlice(b, v)
b = appendStructEnd(b) b = appendStructEnd(b)
code = code.next code = code.next
case opStructEndEmptyStruct:
b = append(b, code.escapedKey...)
b = append(b, '{', '}')
b = appendStructEnd(b)
code = code.next
case opStructEndOmitEmptyEmptyStruct:
b = append(b, code.escapedKey...)
b = append(b, '{', '}')
b = appendStructEnd(b)
code = code.next
case opStructEndStringTagEmptyStruct:
b = append(b, code.escapedKey...)
b = append(b, `"{}"`...)
b = appendStructEnd(b)
code = code.next
case opStructEndEmptyStructPtr:
b = append(b, code.escapedKey...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, '{', '}')
}
b = appendStructEnd(b)
code = code.next
case opStructEndOmitEmptyEmptyStructPtr:
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p != 0 {
b = append(b, code.escapedKey...)
b = append(b, '{', '}')
b = appendStructEnd(b)
}
code = code.next
case opStructEndStringTagEmptyStructPtr:
b = append(b, code.escapedKey...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, `"{}"`...)
}
b = appendStructEnd(b)
code = code.next
case opStructEndMarshalJSON: case opStructEndMarshalJSON:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
b = append(b, code.escapedKey...) b = append(b, code.escapedKey...)

View File

@ -75,6 +75,10 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
} }
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opEmptyStruct:
b = append(b, '{', '}')
b = encodeIndentComma(b)
code = code.next
case opInterface: case opInterface:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
if ptr == 0 { if ptr == 0 {
@ -493,13 +497,11 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
case opStructFieldHead: case opStructFieldHead:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
if ptr == 0 { if ptr == 0 {
b = appendIndent(ctx, b, code.indent)
b = encodeNull(b) b = encodeNull(b)
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.end.next code = code.end.next
} else if code.next == code.end { } else if code.next == code.end {
// not exists fields // not exists fields
b = appendIndent(ctx, b, code.indent)
b = append(b, '{', '}', ',', '\n') b = append(b, '{', '}', ',', '\n')
code = code.end.next code = code.end.next
store(ctxptr, code.idx, ptr) store(ctxptr, code.idx, ptr)
@ -523,12 +525,10 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
case opStructFieldHeadOmitEmpty: case opStructFieldHeadOmitEmpty:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
if ptr == 0 { if ptr == 0 {
b = appendIndent(ctx, b, code.indent)
b = encodeNull(b) b = encodeNull(b)
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.end.next code = code.end.next
} else { } else {
b = appendIndent(ctx, b, code.indent)
b = append(b, '{', '\n') b = append(b, '{', '\n')
p := ptr + code.offset p := ptr + code.offset
if p == 0 || *(*uintptr)(*(*unsafe.Pointer)(unsafe.Pointer(&p))) == 0 { if p == 0 || *(*uintptr)(*(*unsafe.Pointer)(unsafe.Pointer(&p))) == 0 {
@ -3579,6 +3579,64 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
code = code.next code = code.next
} }
} }
case opStructFieldPtrHeadEmptyStruct:
p := load(ctxptr, code.idx)
if p == 0 {
b = encodeNull(b)
b = encodeIndentComma(b)
code = code.end.next
break
}
store(ctxptr, code.idx, ptrToPtr(p))
fallthrough
case opStructFieldHeadEmptyStruct:
b = append(b, '{')
b = append(b, code.escapedKey...)
b = append(b, ' ', '{', '}')
b = encodeIndentComma(b)
code = code.next
case opStructFieldPtrHeadEmptyStructPtr:
store(ctxptr, code.idx, ptrToPtr(load(ctxptr, code.idx)))
fallthrough
case opStructFieldHeadEmptyStructPtr:
p := load(ctxptr, code.idx)
if p == 0 {
b = encodeNull(b)
b = encodeIndentComma(b)
code = code.end.next
break
} else {
b = append(b, '{')
b = append(b, code.escapedKey...)
p = ptrToPtr(p)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, '{', '}')
}
}
b = encodeIndentComma(b)
code = code.next
case opStructFieldPtrHeadOmitEmptyEmptyStructPtr:
store(ctxptr, code.idx, ptrToPtr(load(ctxptr, code.idx)))
fallthrough
case opStructFieldHeadOmitEmptyEmptyStructPtr:
p := load(ctxptr, code.idx)
if p == 0 {
b = encodeNull(b)
b = encodeIndentComma(b)
code = code.end.next
break
} else {
p = ptrToPtr(p)
b = append(b, '{')
if p != 0 {
b = append(b, code.escapedKey...)
b = append(b, ' ', '{', '}')
}
}
b = encodeIndentComma(b)
code = code.next
case opStructFieldPtrHeadStringTag: case opStructFieldPtrHeadStringTag:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
if ptr != 0 { if ptr != 0 {
@ -4139,6 +4197,58 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
} }
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opStructFieldEmptyStruct:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
b = append(b, ' ', '{', '}')
b = encodeIndentComma(b)
code = code.next
case opStructFieldOmitEmptyEmptyStruct:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
b = append(b, ' ', '{', '}')
b = encodeIndentComma(b)
code = code.next
case opStructFieldStringTagEmptyStruct:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
b = append(b, ` "{}"`...)
b = encodeIndentComma(b)
code = code.next
case opStructFieldEmptyStructPtr:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, ' ', '{', '}')
}
b = encodeIndentComma(b)
code = code.next
case opStructFieldOmitEmptyEmptyStructPtr:
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p != 0 {
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
b = append(b, ' ', '{', '}')
b = encodeIndentComma(b)
}
code = code.next
case opStructFieldStringTagEmptyStructPtr:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, ` "{}"`...)
}
b = encodeIndentComma(b)
code = code.next
case opStructFieldMarshalJSON: case opStructFieldMarshalJSON:
b = appendIndent(ctx, b, code.indent) b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...) b = append(b, code.escapedKey...)
@ -5023,6 +5133,58 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
b = encodeByteSlice(b, ptrToBytes(ptr+code.offset)) b = encodeByteSlice(b, ptrToBytes(ptr+code.offset))
b = appendStructEndIndent(ctx, b, code.indent-1) b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next code = code.next
case opStructEndEmptyStruct:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
b = append(b, ' ', '{', '}')
b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next
case opStructEndOmitEmptyEmptyStruct:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
b = append(b, ' ', '{', '}')
b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next
case opStructEndStringTagEmptyStruct:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
b = append(b, ` "{}"`...)
b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next
case opStructEndEmptyStructPtr:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, ' ', '{', '}')
}
b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next
case opStructEndOmitEmptyEmptyStructPtr:
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p != 0 {
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
b = append(b, ' ', '{', '}')
b = appendStructEndIndent(ctx, b, code.indent-1)
}
code = code.next
case opStructEndStringTagEmptyStructPtr:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, ` "{}"`...)
}
b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next
case opStructEndMarshalJSON: case opStructEndMarshalJSON:
b = appendIndent(ctx, b, code.indent) b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...) b = append(b, code.escapedKey...)

View File

@ -75,6 +75,10 @@ func encodeRunIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, op
} }
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opEmptyStruct:
b = append(b, '{', '}')
b = encodeIndentComma(b)
code = code.next
case opInterface: case opInterface:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
if ptr == 0 { if ptr == 0 {
@ -3579,6 +3583,64 @@ func encodeRunIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, op
code = code.next code = code.next
} }
} }
case opStructFieldPtrHeadEmptyStruct:
p := load(ctxptr, code.idx)
if p == 0 {
b = encodeNull(b)
b = encodeIndentComma(b)
code = code.end.next
break
}
store(ctxptr, code.idx, ptrToPtr(p))
fallthrough
case opStructFieldHeadEmptyStruct:
b = append(b, '{')
b = append(b, code.key...)
b = append(b, ' ', '{', '}')
b = encodeIndentComma(b)
code = code.next
case opStructFieldPtrHeadEmptyStructPtr:
store(ctxptr, code.idx, ptrToPtr(load(ctxptr, code.idx)))
fallthrough
case opStructFieldHeadEmptyStructPtr:
p := load(ctxptr, code.idx)
if p == 0 {
b = encodeNull(b)
b = encodeIndentComma(b)
code = code.end.next
break
} else {
b = append(b, '{')
b = append(b, code.key...)
p = ptrToPtr(p)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, '{', '}')
}
}
b = encodeIndentComma(b)
code = code.next
case opStructFieldPtrHeadOmitEmptyEmptyStructPtr:
store(ctxptr, code.idx, ptrToPtr(load(ctxptr, code.idx)))
fallthrough
case opStructFieldHeadOmitEmptyEmptyStructPtr:
p := load(ctxptr, code.idx)
if p == 0 {
b = encodeNull(b)
b = encodeIndentComma(b)
code = code.end.next
break
} else {
p = ptrToPtr(p)
b = append(b, '{')
if p != 0 {
b = append(b, code.key...)
b = append(b, ' ', '{', '}')
}
}
b = encodeIndentComma(b)
code = code.next
case opStructFieldPtrHeadStringTag: case opStructFieldPtrHeadStringTag:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
if ptr != 0 { if ptr != 0 {
@ -4139,6 +4201,58 @@ func encodeRunIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, op
} }
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opStructFieldEmptyStruct:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...)
b = append(b, ' ', '{', '}')
b = encodeIndentComma(b)
code = code.next
case opStructFieldOmitEmptyEmptyStruct:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...)
b = append(b, ' ', '{', '}')
b = encodeIndentComma(b)
code = code.next
case opStructFieldStringTagEmptyStruct:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...)
b = append(b, ` "{}"`...)
b = encodeIndentComma(b)
code = code.next
case opStructFieldEmptyStructPtr:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, ' ', '{', '}')
}
b = encodeIndentComma(b)
code = code.next
case opStructFieldOmitEmptyEmptyStructPtr:
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p != 0 {
b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...)
b = append(b, ' ', '{', '}')
b = encodeIndentComma(b)
}
code = code.next
case opStructFieldStringTagEmptyStructPtr:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, ` "{}"`...)
}
b = encodeIndentComma(b)
code = code.next
case opStructFieldMarshalJSON: case opStructFieldMarshalJSON:
b = appendIndent(ctx, b, code.indent) b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...) b = append(b, code.key...)
@ -5022,6 +5136,58 @@ func encodeRunIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, op
b = encodeByteSlice(b, ptrToBytes(ptr+code.offset)) b = encodeByteSlice(b, ptrToBytes(ptr+code.offset))
b = appendStructEndIndent(ctx, b, code.indent-1) b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next code = code.next
case opStructEndEmptyStruct:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...)
b = append(b, ' ', '{', '}')
b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next
case opStructEndOmitEmptyEmptyStruct:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...)
b = append(b, ' ', '{', '}')
b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next
case opStructEndStringTagEmptyStruct:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...)
b = append(b, ` "{}"`...)
b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next
case opStructEndEmptyStructPtr:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, ' ', '{', '}')
}
b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next
case opStructEndOmitEmptyEmptyStructPtr:
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p != 0 {
b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...)
b = append(b, ' ', '{', '}')
b = appendStructEndIndent(ctx, b, code.indent-1)
}
code = code.next
case opStructEndStringTagEmptyStructPtr:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...)
ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset)
if p == 0 {
b = encodeNull(b)
} else {
b = append(b, ` "{}"`...)
}
b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next
case opStructEndMarshalJSON: case opStructEndMarshalJSON:
b = appendIndent(ctx, b, code.indent) b = appendIndent(ctx, b, code.indent)
b = append(b, code.key...) b = append(b, code.key...)