Fix stream decoder for slice

This commit is contained in:
Masaaki Goshima 2020-07-31 18:52:22 +09:00
parent daec57244d
commit c14253089e
1 changed files with 18 additions and 14 deletions

View File

@ -65,34 +65,38 @@ func (d *sliceDecoder) decodeStream(s *stream, p uintptr) error {
case '[': case '[':
idx := 0 idx := 0
slice := d.newSlice() slice := d.newSlice()
cap := slice.Cap cap := slice.cap
data := slice.Data data := slice.data
for { for {
s.cursor++ s.cursor++
if cap <= idx { if cap <= idx {
src := reflect.SliceHeader{Data: data, Len: idx, Cap: cap} src := reflect.SliceHeader{Data: uintptr(data), Len: idx, Cap: cap}
cap *= 2 cap *= 2
data = uintptr(newArray(d.elemType, cap)) data = newArray(d.elemType, cap)
dst := reflect.SliceHeader{Data: data, Len: idx, Cap: cap} dst := reflect.SliceHeader{Data: uintptr(data), Len: idx, Cap: cap}
copySlice(d.elemType, dst, src) copySlice(d.elemType, dst, src)
} }
if err := d.valueDecoder.decodeStream(s, data+uintptr(idx)*d.size); err != nil { if err := d.valueDecoder.decodeStream(s, uintptr(data)+uintptr(idx)*d.size); err != nil {
return err return err
} }
s.skipWhiteSpace() s.skipWhiteSpace()
RETRY: RETRY:
switch s.char() { switch s.char() {
case ']': case ']':
slice.Cap = cap slice.cap = cap
slice.Len = idx + 1 slice.len = idx + 1
slice.Data = data slice.data = data
dstCap := idx + 1 dstCap := idx + 1
dst := reflect.SliceHeader{ dst := reflect.SliceHeader{
Data: uintptr(newArray(d.elemType, dstCap)), Data: uintptr(newArray(d.elemType, dstCap)),
Len: idx + 1, Len: idx + 1,
Cap: dstCap, Cap: dstCap,
} }
copySlice(d.elemType, dst, *slice) copySlice(d.elemType, dst, reflect.SliceHeader{
Data: uintptr(slice.data),
Len: slice.len,
Cap: slice.cap,
})
*(*reflect.SliceHeader)(unsafe.Pointer(p)) = dst *(*reflect.SliceHeader)(unsafe.Pointer(p)) = dst
d.releaseSlice(slice) d.releaseSlice(slice)
s.cursor++ s.cursor++
@ -104,13 +108,13 @@ func (d *sliceDecoder) decodeStream(s *stream, p uintptr) error {
if s.read() { if s.read() {
goto RETRY goto RETRY
} }
slice.Cap = cap slice.cap = cap
slice.Data = data slice.data = data
d.releaseSlice(slice) d.releaseSlice(slice)
goto ERROR goto ERROR
default: default:
slice.Cap = cap slice.cap = cap
slice.Data = data slice.data = data
d.releaseSlice(slice) d.releaseSlice(slice)
goto ERROR goto ERROR
} }