diff --git a/decoder/assembler_amd64.go b/decoder/assembler_amd64.go index af4b89a..f0614a0 100644 --- a/decoder/assembler_amd64.go +++ b/decoder/assembler_amd64.go @@ -1176,7 +1176,7 @@ func (self *_Assembler) _asm_OP_array_clear_p(p *_Instr) { func (self *_Assembler) _asm_OP_slice_init(p *_Instr) { self.Emit("XORL" , _AX, _AX) // XORL AX, AX self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 8)) // MOVQ AX, 8(VP) - self.Emit("MOVQ" , jit.Ptr(_VP, 0), _AX) // MOVQ (VP), AX + self.Emit("MOVQ" , jit.Ptr(_VP, 16), _AX) // MOVQ 16(VP), AX self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX self.Sjmp("JNZ" , "_done_{n}") // JNZ _done_{n} self.Emit("MOVQ" , jit.Imm(_MinSlice), _CX) // MOVQ ${_MinSlice}, CX @@ -1189,6 +1189,8 @@ func (self *_Assembler) _asm_OP_slice_init(p *_Instr) { self.Emit("MOVQ" , jit.Ptr(_SP, 24), _AX) // MOVQ 24(SP), AX self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 0)) // MOVQ AX, (VP) self.Link("_done_{n}") // _done_{n}: + self.Emit("XORL" , _AX, _AX) // XORL AX, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 8)) // MOVQ AX, 8(VP) } func (self *_Assembler) _asm_OP_slice_append(p *_Instr) { diff --git a/issue27_test.go b/issue27_test.go new file mode 100644 index 0000000..17e7e83 --- /dev/null +++ b/issue27_test.go @@ -0,0 +1,41 @@ +/* + * 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 ( + `reflect` + `sync` + `testing` + + `github.com/stretchr/testify/require` +) + +func TestIssue27_EmptySlice(t *testing.T) { + _ = Pretouch(reflect.TypeOf([]*int{})) + wg := sync.WaitGroup{} + for i := 0; i < 1000; i++ { + go func() { + defer wg.Done() + v := make([]*int, 16) + err := UnmarshalString(`[null, null]`, &v) + require.NoError(t, err) + require.Equal(t, []*int{nil, nil}, v) + }() + wg.Add(1) + } + wg.Wait() +}