From ade38b26c44d3dcb6c8eea2a5ead727a282ec758 Mon Sep 17 00:00:00 2001 From: chenzhuoyu Date: Wed, 18 Aug 2021 13:29:57 +0800 Subject: [PATCH] fix: check flags for indirection --- encoder/assembler_amd64.go | 2 +- encoder/compiler.go | 4 +++ issue76_test.go | 51 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 issue76_test.go diff --git a/encoder/assembler_amd64.go b/encoder/assembler_amd64.go index c6b1bee..2c8c107 100644 --- a/encoder/assembler_amd64.go +++ b/encoder/assembler_amd64.go @@ -1022,7 +1022,7 @@ func (self *_Assembler) _asm_OP_recurse(p *_Instr) { self.Emit("MOVQ", _AX, jit.Ptr(_SP, 8)) // MOVQ AX, 8(SP) /* check for indirection */ - if p.vk() == reflect.Ptr { + if (p.vf() & rt.F_direct) != 0 { self.Emit("MOVQ", _SP_p, _AX) // MOVQ SP.p, AX } else { self.Emit("MOVQ", _SP_p, jit.Ptr(_SP, 48)) // MOVQ SP.p, 48(SP) diff --git a/encoder/compiler.go b/encoder/compiler.go index d758a01..775e98e 100644 --- a/encoder/compiler.go +++ b/encoder/compiler.go @@ -224,6 +224,10 @@ func (self _Instr) vi() int { return rt.UnpackInt(self.u) } +func (self _Instr) vf() uint8 { + return (*rt.GoType)(self.p).KindFlags +} + func (self _Instr) vs() (v string) { (*rt.GoString)(unsafe.Pointer(&v)).Ptr = self.p (*rt.GoString)(unsafe.Pointer(&v)).Len = self.vi() diff --git a/issue76_test.go b/issue76_test.go new file mode 100644 index 0000000..2186ec2 --- /dev/null +++ b/issue76_test.go @@ -0,0 +1,51 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sonic + +import ( + `encoding/json` + `fmt` + `testing` + + `github.com/davecgh/go-spew/spew` +) + +type SingleMapField struct { + Z *int +} + +type SingleMapFieldOuter struct { + Y *SingleMapField +} + +type SingleMapFieldOuterContainer struct { + X *SingleMapFieldOuter +} + +func TestIssue76_MarshalSingleMapField(t *testing.T) { + data := `{"X": {"Y": {"Z": 1}}}` + obj := new(SingleMapFieldOuterContainer) + if err := json.Unmarshal([]byte(data), obj); err != nil { + t.Fatal(err) + } + spew.Dump(obj) + buf, err := Marshal(obj) + if err != nil { + t.Fatal(err) + } + fmt.Println(string(buf)) +} \ No newline at end of file