From 6990aa69382a36c14fbf5397c84bdf42ee71b269 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Mon, 22 Feb 2021 00:55:20 +0900 Subject: [PATCH] Add EmptyStruct operation --- encode_compile.go | 26 ++++-- encode_vm.go | 154 ++++++++++++++++++++++++++++++++ encode_vm_escaped.go | 154 ++++++++++++++++++++++++++++++++ encode_vm_escaped_indent.go | 170 +++++++++++++++++++++++++++++++++++- encode_vm_indent.go | 166 +++++++++++++++++++++++++++++++++++ 5 files changed, 661 insertions(+), 9 deletions(-) diff --git a/encode_compile.go b/encode_compile.go index 474cabf..6543b2e 100644 --- a/encode_compile.go +++ b/encode_compile.go @@ -238,6 +238,9 @@ func encodeConvertHeadOnlyCode(c *opcode, isPtrHead bool) { if strings.Contains(c.op.String(), "Map") { return } + if strings.Contains(c.op.String(), "EmptyStruct") { + return + } isPtrOp := strings.Contains(c.op.String(), "Ptr") if isPtrOp && !isPtrHead { @@ -628,6 +631,12 @@ func encodeCompileBytes(ctx *encodeCompileContext) (*opcode, error) { return code, nil } +func encodeCompileEmptyStruct(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opEmptyStruct) + ctx.incIndex() + return code, nil +} + func encodeCompileInterface(ctx *encodeCompileContext) (*opcode, error) { code := newInterfaceCode(ctx) ctx.incIndex() @@ -814,6 +823,8 @@ func encodeTypeToHeaderType(ctx *encodeCompileContext, code *opcode) opType { return opStructFieldHeadStringPtr case opBool: return opStructFieldHeadBoolPtr + case opEmptyStruct: + return opStructFieldHeadEmptyStructPtr } } case opInt: @@ -828,6 +839,8 @@ func encodeTypeToHeaderType(ctx *encodeCompileContext, code *opcode) opType { return opStructFieldHeadString case opBool: return opStructFieldHeadBool + case opEmptyStruct: + return opStructFieldHeadEmptyStruct case opMapHead: return opStructFieldHeadMap case opMapHeadLoad: @@ -836,8 +849,6 @@ func encodeTypeToHeaderType(ctx *encodeCompileContext, code *opcode) opType { return opStructFieldHeadArray case opSliceHead: return opStructFieldHeadSlice - case opStructFieldHead: - return opStructFieldHeadStruct case opMarshalJSON: return opStructFieldHeadMarshalJSON case opMarshalText: @@ -897,6 +908,8 @@ func encodeTypeToFieldType(ctx *encodeCompileContext, code *opcode) opType { return opStructFieldStringPtr case opBool: return opStructFieldBoolPtr + case opEmptyStruct: + return opStructFieldEmptyStructPtr } } case opInt: @@ -911,6 +924,8 @@ func encodeTypeToFieldType(ctx *encodeCompileContext, code *opcode) opType { return opStructFieldString case opBool: return opStructFieldBool + case opEmptyStruct: + return opStructFieldEmptyStruct case opMapHead: return opStructFieldMap case opMapHeadLoad: @@ -919,8 +934,6 @@ func encodeTypeToFieldType(ctx *encodeCompileContext, code *opcode) opType { return opStructFieldArray case opSliceHead: return opStructFieldSlice - case opStructFieldHead: - return opStructFieldStruct case opMarshalJSON: return opStructFieldMarshalJSON case opMarshalText: @@ -1220,13 +1233,16 @@ func encodeCompileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode, error) return code, nil } typ := ctx.typ + fieldNum := typ.NumField() + if fieldNum == 0 { + return encodeCompileEmptyStruct(ctx) + } typeptr := uintptr(unsafe.Pointer(typ)) compiled := &compiledCode{} ctx.structTypeToCompiledCode[typeptr] = compiled // header => code => structField => code => end // ^ | // |__________| - fieldNum := typ.NumField() fieldIdx := 0 var ( head *opcode diff --git a/encode_vm.go b/encode_vm.go index 9c3789b..9142536 100644 --- a/encode_vm.go +++ b/encode_vm.go @@ -142,6 +142,10 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco } b = encodeComma(b) code = code.next + case opEmptyStruct: + b = append(b, '{', '}') + b = encodeComma(b) + code = code.next case opInterface: ptr := load(ctxptr, code.idx) if ptr == 0 { @@ -3357,6 +3361,64 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco b = encodeComma(b) 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: p := load(ctxptr, code.idx) if p == 0 { @@ -4453,6 +4515,52 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco } b = encodeComma(b) 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: ptr := load(ctxptr, code.headIdx) b = append(b, code.key...) @@ -5215,6 +5323,52 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco b = encodeByteSlice(b, v) b = appendStructEnd(b) 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: ptr := load(ctxptr, code.headIdx) b = append(b, code.key...) diff --git a/encode_vm_escaped.go b/encode_vm_escaped.go index 2c2c6d0..3b76bc1 100644 --- a/encode_vm_escaped.go +++ b/encode_vm_escaped.go @@ -76,6 +76,10 @@ func encodeRunEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, o } b = encodeComma(b) code = code.next + case opEmptyStruct: + b = append(b, '{', '}') + b = encodeComma(b) + code = code.next case opInterface: ptr := load(ctxptr, code.idx) if ptr == 0 { @@ -3295,6 +3299,64 @@ func encodeRunEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, o b = encodeComma(b) 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: p := load(ctxptr, code.idx) if p == 0 { @@ -4387,6 +4449,52 @@ func encodeRunEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, o } b = encodeComma(b) 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: ptr := load(ctxptr, code.headIdx) b = append(b, code.escapedKey...) @@ -5158,6 +5266,52 @@ func encodeRunEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, o b = encodeByteSlice(b, v) b = appendStructEnd(b) 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: ptr := load(ctxptr, code.headIdx) b = append(b, code.escapedKey...) diff --git a/encode_vm_escaped_indent.go b/encode_vm_escaped_indent.go index 0a24438..b247e93 100644 --- a/encode_vm_escaped_indent.go +++ b/encode_vm_escaped_indent.go @@ -75,6 +75,10 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode } b = encodeIndentComma(b) code = code.next + case opEmptyStruct: + b = append(b, '{', '}') + b = encodeIndentComma(b) + code = code.next case opInterface: ptr := load(ctxptr, code.idx) if ptr == 0 { @@ -493,13 +497,11 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode case opStructFieldHead: ptr := load(ctxptr, code.idx) if ptr == 0 { - b = appendIndent(ctx, b, code.indent) b = encodeNull(b) b = encodeIndentComma(b) code = code.end.next } else if code.next == code.end { // not exists fields - b = appendIndent(ctx, b, code.indent) b = append(b, '{', '}', ',', '\n') code = code.end.next store(ctxptr, code.idx, ptr) @@ -523,12 +525,10 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode case opStructFieldHeadOmitEmpty: ptr := load(ctxptr, code.idx) if ptr == 0 { - b = appendIndent(ctx, b, code.indent) b = encodeNull(b) b = encodeIndentComma(b) code = code.end.next } else { - b = appendIndent(ctx, b, code.indent) b = append(b, '{', '\n') p := ptr + code.offset 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 } } + 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: ptr := load(ctxptr, code.idx) if ptr != 0 { @@ -4139,6 +4197,58 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode } b = encodeIndentComma(b) 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: b = appendIndent(ctx, b, code.indent) 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 = appendStructEndIndent(ctx, b, code.indent-1) 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: b = appendIndent(ctx, b, code.indent) b = append(b, code.escapedKey...) diff --git a/encode_vm_indent.go b/encode_vm_indent.go index a05bc9e..e0c9f94 100644 --- a/encode_vm_indent.go +++ b/encode_vm_indent.go @@ -75,6 +75,10 @@ func encodeRunIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, op } b = encodeIndentComma(b) code = code.next + case opEmptyStruct: + b = append(b, '{', '}') + b = encodeIndentComma(b) + code = code.next case opInterface: ptr := load(ctxptr, code.idx) if ptr == 0 { @@ -3579,6 +3583,64 @@ func encodeRunIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, op 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: ptr := load(ctxptr, code.idx) if ptr != 0 { @@ -4139,6 +4201,58 @@ func encodeRunIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, op } b = encodeIndentComma(b) 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: b = appendIndent(ctx, b, code.indent) 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 = appendStructEndIndent(ctx, b, code.indent-1) 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: b = appendIndent(ctx, b, code.indent) b = append(b, code.key...)