From c75b9e57e21204e971dbf0d45f99694ed58ab7d2 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Mon, 15 Mar 2021 13:29:08 +0900 Subject: [PATCH] Fix encoding of nested map --- cover_map_test.go | 4 ++++ encode_compile.go | 12 ++++++++++-- encode_vm_escaped_indent.go | 10 ++++++++++ encode_vm_indent.go | 10 ++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/cover_map_test.go b/cover_map_test.go index 92efd82..cc4f0e7 100644 --- a/cover_map_test.go +++ b/cover_map_test.go @@ -50,6 +50,10 @@ func TestCoverMap(t *testing.T) { name string data interface{} }{ + { + name: "NestedMap", + data: map[string]map[string]int{"a": {"b": 1}}, + }, // HeadMapZero { name: "HeadMapZero", diff --git a/encode_compile.go b/encode_compile.go index a152b44..fcb89cb 100644 --- a/encode_compile.go +++ b/encode_compile.go @@ -726,8 +726,7 @@ func encodeCompileMap(ctx *encodeCompileContext) (*opcode, error) { value := newMapValueCode(ctx, header) ctx.incIndex() - valueType := typ.Elem() - valueCode, err := encodeCompile(ctx.withType(valueType), false) + valueCode, err := encodeCompileMapValue(ctx.withType(typ.Elem())) if err != nil { return nil, err } @@ -756,6 +755,15 @@ func encodeCompileMap(ctx *encodeCompileContext) (*opcode, error) { return (*opcode)(unsafe.Pointer(header)), nil } +func encodeCompileMapValue(ctx *encodeCompileContext) (*opcode, error) { + switch ctx.typ.Kind() { + case reflect.Map: + return encodeCompilePtr(ctx.withType(rtype_ptrTo(ctx.typ))) + default: + return encodeCompile(ctx, false) + } +} + func encodeTypeToHeaderType(code *opcode) opType { switch code.op { case opInt: diff --git a/encode_vm_escaped_indent.go b/encode_vm_escaped_indent.go index 78d86e7..64b15b6 100644 --- a/encode_vm_escaped_indent.go +++ b/encode_vm_escaped_indent.go @@ -278,6 +278,16 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode b = append(b, ']', ',', '\n') code = code.end.next } + case opMapPtr: + 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 opMap: ptr := load(ctxptr, code.idx) if ptr == 0 { diff --git a/encode_vm_indent.go b/encode_vm_indent.go index 1f47970..39230e4 100644 --- a/encode_vm_indent.go +++ b/encode_vm_indent.go @@ -278,6 +278,16 @@ func encodeRunIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, op b = append(b, ']', ',', '\n') code = code.end.next } + case opMapPtr: + 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 opMap: ptr := load(ctxptr, code.idx) if ptr == 0 {