From e58b1eabaf45d4f64ea73afa72730ac1ae8aaaeb Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Sun, 15 Nov 2020 01:24:34 +0700 Subject: [PATCH 1/2] Remove all usages of reflect.SliceHeader There're some problem with current usage of reflect.SliceHeader. First, it violates the unsafe pointer conversion (rule 6th), that said, reflect.SliceHeader must not used as plain struct. Second, the lowest version that go-json supports, go1.12, reflect package did not use SliceHeader in typedslicecopy, but use the safety version. There's no reason that go-json continue using them. See: - https://golang.org/pkg/unsafe/#Pointer - https://github.com/golang/go/blob/release-branch.go1.12/src/reflect/value.go#L2702 --- decode_slice.go | 63 +++++++++++++++++++++++------------------------ encode_context.go | 5 ++-- encode_vm.go | 60 ++++++++++++++++++++++---------------------- 3 files changed, 63 insertions(+), 65 deletions(-) diff --git a/decode_slice.go b/decode_slice.go index 411350f..de10f25 100644 --- a/decode_slice.go +++ b/decode_slice.go @@ -1,7 +1,6 @@ package json import ( - "reflect" "sync" "unsafe" ) @@ -51,7 +50,7 @@ func (d *sliceDecoder) releaseSlice(p *sliceHeader) { } //go:linkname copySlice reflect.typedslicecopy -func copySlice(elemType *rtype, dst, src reflect.SliceHeader) int +func copySlice(elemType *rtype, dst, src sliceHeader) int //go:linkname newArray reflect.unsafe_NewArray func newArray(*rtype, int) unsafe.Pointer @@ -71,10 +70,10 @@ func (d *sliceDecoder) decodeStream(s *stream, p uintptr) error { s.cursor++ s.skipWhiteSpace() if s.char() == ']' { - *(*reflect.SliceHeader)(unsafe.Pointer(p)) = reflect.SliceHeader{ - Data: uintptr(newArray(d.elemType, 0)), - Len: 0, - Cap: 0, + *(*sliceHeader)(unsafe.Pointer(p)) = sliceHeader{ + data: newArray(d.elemType, 0), + len: 0, + cap: 0, } s.cursor++ return nil @@ -85,10 +84,10 @@ func (d *sliceDecoder) decodeStream(s *stream, p uintptr) error { data := slice.data for { if cap <= idx { - src := reflect.SliceHeader{Data: uintptr(data), Len: idx, Cap: cap} + src := sliceHeader{data: data, len: idx, cap: cap} cap *= 2 data = newArray(d.elemType, cap) - dst := reflect.SliceHeader{Data: uintptr(data), Len: idx, Cap: cap} + dst := sliceHeader{data: data, len: idx, cap: cap} copySlice(d.elemType, dst, src) } if err := d.valueDecoder.decodeStream(s, uintptr(data)+uintptr(idx)*d.size); err != nil { @@ -102,17 +101,17 @@ func (d *sliceDecoder) decodeStream(s *stream, p uintptr) error { slice.len = idx + 1 slice.data = data dstCap := idx + 1 - dst := reflect.SliceHeader{ - Data: uintptr(newArray(d.elemType, dstCap)), - Len: idx + 1, - Cap: dstCap, + dst := sliceHeader{ + data: newArray(d.elemType, dstCap), + len: idx + 1, + cap: dstCap, } - copySlice(d.elemType, dst, reflect.SliceHeader{ - Data: uintptr(slice.data), - Len: slice.len, - Cap: slice.cap, + copySlice(d.elemType, dst, sliceHeader{ + data: slice.data, + len: slice.len, + cap: slice.cap, }) - *(*reflect.SliceHeader)(unsafe.Pointer(p)) = dst + *(*sliceHeader)(unsafe.Pointer(p)) = dst d.releaseSlice(slice) s.cursor++ return nil @@ -171,10 +170,10 @@ func (d *sliceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error cursor++ cursor = skipWhiteSpace(buf, cursor) if buf[cursor] == ']' { - *(*reflect.SliceHeader)(unsafe.Pointer(p)) = reflect.SliceHeader{ - Data: uintptr(newArray(d.elemType, 0)), - Len: 0, - Cap: 0, + *(*sliceHeader)(unsafe.Pointer(p)) = sliceHeader{ + data: newArray(d.elemType, 0), + len: 0, + cap: 0, } cursor++ return cursor, nil @@ -185,10 +184,10 @@ func (d *sliceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error data := slice.data for { if cap <= idx { - src := reflect.SliceHeader{Data: uintptr(data), Len: idx, Cap: cap} + src := sliceHeader{data: data, len: idx, cap: cap} cap *= 2 data = newArray(d.elemType, cap) - dst := reflect.SliceHeader{Data: uintptr(data), Len: idx, Cap: cap} + dst := sliceHeader{data: data, len: idx, cap: cap} copySlice(d.elemType, dst, src) } c, err := d.valueDecoder.decode(buf, cursor, uintptr(data)+uintptr(idx)*d.size) @@ -203,17 +202,17 @@ func (d *sliceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error slice.len = idx + 1 slice.data = data dstCap := idx + 1 - dst := reflect.SliceHeader{ - Data: uintptr(newArray(d.elemType, dstCap)), - Len: idx + 1, - Cap: dstCap, + dst := sliceHeader{ + data: newArray(d.elemType, dstCap), + len: idx + 1, + cap: dstCap, } - copySlice(d.elemType, dst, reflect.SliceHeader{ - Data: uintptr(slice.data), - Len: slice.len, - Cap: slice.cap, + copySlice(d.elemType, dst, sliceHeader{ + data: slice.data, + len: slice.len, + cap: slice.cap, }) - *(*reflect.SliceHeader)(unsafe.Pointer(p)) = dst + *(*sliceHeader)(unsafe.Pointer(p)) = dst d.releaseSlice(slice) cursor++ return cursor, nil diff --git a/encode_context.go b/encode_context.go index ce52702..7a241ff 100644 --- a/encode_context.go +++ b/encode_context.go @@ -1,7 +1,6 @@ package json import ( - "reflect" "unsafe" ) @@ -95,6 +94,6 @@ func (c *encodeRuntimeContext) init(p uintptr) { } func (c *encodeRuntimeContext) ptr() uintptr { - header := (*reflect.SliceHeader)(unsafe.Pointer(&c.ptrs)) - return header.Data + header := (*sliceHeader)(unsafe.Pointer(&c.ptrs)) + return uintptr(header.data) } diff --git a/encode_vm.go b/encode_vm.go index 973bb62..c926812 100644 --- a/encode_vm.go +++ b/encode_vm.go @@ -175,8 +175,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.next case opBytes: ptr := load(ctxptr, code.idx) - header := (*reflect.SliceHeader)(unsafe.Pointer(ptr)) - if ptr == 0 || header.Data == 0 { + header := (*sliceHeader)(unsafe.Pointer(ptr)) + if ptr == 0 || uintptr(header.data) == 0 { e.encodeNull() } else { e.encodeByteSlice(e.ptrToBytes(ptr)) @@ -498,19 +498,19 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.next case opSliceHead: p := load(ctxptr, code.idx) - header := (*reflect.SliceHeader)(unsafe.Pointer(p)) - if p == 0 || header.Data == 0 { + header := (*sliceHeader)(unsafe.Pointer(p)) + if p == 0 || uintptr(header.data) == 0 { e.encodeNull() e.encodeByte(',') code = code.end.next } else { store(ctxptr, code.elemIdx, 0) - store(ctxptr, code.length, uintptr(header.Len)) - store(ctxptr, code.idx, header.Data) - if header.Len > 0 { + store(ctxptr, code.length, uintptr(header.len)) + store(ctxptr, code.idx, uintptr(header.data)) + if header.len > 0 { e.encodeByte('[') code = code.next - store(ctxptr, code.idx, header.Data) + store(ctxptr, code.idx, uintptr(header.data)) } else { e.encodeBytes([]byte{'[', ']', ','}) code = code.end.next @@ -540,15 +540,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) code = code.end.next } else { - header := (*reflect.SliceHeader)(unsafe.Pointer(p)) + header := (*sliceHeader)(unsafe.Pointer(p)) store(ctxptr, code.elemIdx, 0) - store(ctxptr, code.length, uintptr(header.Len)) - store(ctxptr, code.idx, header.Data) - if header.Len > 0 { + store(ctxptr, code.length, uintptr(header.len)) + store(ctxptr, code.idx, uintptr(header.data)) + if header.len > 0 { e.encodeBytes([]byte{'[', '\n'}) e.encodeIndent(code.indent + 1) code = code.next - store(ctxptr, code.idx, header.Data) + store(ctxptr, code.idx, uintptr(header.data)) } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'[', ']', '\n'}) @@ -563,15 +563,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) code = code.end.next } else { - header := (*reflect.SliceHeader)(unsafe.Pointer(p)) + header := (*sliceHeader)(unsafe.Pointer(p)) store(ctxptr, code.elemIdx, 0) - store(ctxptr, code.length, uintptr(header.Len)) - store(ctxptr, code.idx, header.Data) - if header.Len > 0 { + store(ctxptr, code.length, uintptr(header.len)) + store(ctxptr, code.idx, uintptr(header.data)) + if header.len > 0 { e.encodeBytes([]byte{'[', '\n'}) e.encodeIndent(code.indent + 1) code = code.next - store(ctxptr, code.idx, header.Data) + store(ctxptr, code.idx, uintptr(header.data)) } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'[', ']', ',', '\n'}) @@ -5229,8 +5229,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - header := (*reflect.SliceHeader)(unsafe.Pointer(p)) - if p == 0 || header.Data == 0 { + header := (*sliceHeader)(unsafe.Pointer(p)) + if p == 0 || uintptr(header.data) == 0 { e.encodeNull() e.encodeBytes([]byte{',', '\n'}) code = code.nextField @@ -5243,8 +5243,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - header := (*reflect.SliceHeader)(unsafe.Pointer(p)) - if p == 0 || header.Data == 0 { + header := (*sliceHeader)(unsafe.Pointer(p)) + if p == 0 || uintptr(header.data) == 0 { e.encodeNull() e.encodeBytes([]byte{',', '\n'}) code = code.nextField @@ -5509,8 +5509,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { case opStructFieldOmitEmptyArray: ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - header := (*reflect.SliceHeader)(unsafe.Pointer(p)) - if p == 0 || header.Data == 0 { + header := (*sliceHeader)(unsafe.Pointer(p)) + if p == 0 || uintptr(header.data) == 0 { code = code.nextField } else { code = code.next @@ -5518,8 +5518,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { case opStructFieldOmitEmptySlice: ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - header := (*reflect.SliceHeader)(unsafe.Pointer(p)) - if p == 0 || header.Data == 0 { + header := (*sliceHeader)(unsafe.Pointer(p)) + if p == 0 || uintptr(header.data) == 0 { code = code.nextField } else { code = code.next @@ -5740,8 +5740,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { case opStructFieldOmitEmptyArrayIndent: ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - header := (*reflect.SliceHeader)(unsafe.Pointer(p)) - if p == 0 || header.Data == 0 { + header := (*sliceHeader)(unsafe.Pointer(p)) + if p == 0 || uintptr(header.data) == 0 { code = code.nextField } else { e.encodeIndent(code.indent) @@ -5752,8 +5752,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { case opStructFieldOmitEmptySliceIndent: ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - header := (*reflect.SliceHeader)(unsafe.Pointer(p)) - if p == 0 || header.Data == 0 { + header := (*sliceHeader)(unsafe.Pointer(p)) + if p == 0 || uintptr(header.data) == 0 { code = code.nextField } else { e.encodeIndent(code.indent) From 6b1d701387077a61dadc929782195a3cbd3867a9 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Sun, 15 Nov 2020 03:27:15 +0700 Subject: [PATCH 2/2] Fix all invalid usages of unsafe.Pointer Most of the invalid usages due to the conversion from uintptr to unsafe.Pointer. In general, unsafe.Pointer(p) where p of type uintptr is considered unsafe. To fix that, use &p instead of p, then introduce another dereference. Example, the invalid usage: *(*int)(unsafe.Pointer(p)) = int(v) wil become: **(**int)(unsafe.Pointer(&p)) = int(v) Closes #53 --- decode.go | 4 +- decode_bool.go | 8 +- decode_compile.go | 24 ++--- decode_interface.go | 30 +++--- decode_map.go | 8 +- decode_ptr.go | 4 +- decode_slice.go | 8 +- decode_string.go | 4 +- decode_unmarshal_json.go | 4 +- decode_unmarshal_text.go | 4 +- encode.go | 2 +- encode_vm.go | 216 ++++++++++++++++++++++----------------- 12 files changed, 173 insertions(+), 143 deletions(-) diff --git a/decode.go b/decode.go index 56b9c24..71c7d1b 100644 --- a/decode.go +++ b/decode.go @@ -85,7 +85,7 @@ func (d *Decoder) decode(src []byte, header *interfaceHeader) error { typeptr := uintptr(unsafe.Pointer(typ)) // noescape trick for header.typ ( reflect.*rtype ) - copiedType := (*rtype)(unsafe.Pointer(typeptr)) + copiedType := *(**rtype)(unsafe.Pointer(&typeptr)) ptr := uintptr(header.ptr) if err := d.validateType(copiedType, ptr); err != nil { @@ -150,7 +150,7 @@ func (d *Decoder) Decode(v interface{}) error { ptr := uintptr(header.ptr) typeptr := uintptr(unsafe.Pointer(typ)) // noescape trick for header.typ ( reflect.*rtype ) - copiedType := (*rtype)(unsafe.Pointer(typeptr)) + copiedType := *(**rtype)(unsafe.Pointer(&typeptr)) if err := d.validateType(copiedType, ptr); err != nil { return err diff --git a/decode_bool.go b/decode_bool.go index 84d7f4e..a1a3b7c 100644 --- a/decode_bool.go +++ b/decode_bool.go @@ -66,13 +66,13 @@ func (d *boolDecoder) decodeStream(s *stream, p uintptr) error { if err := trueBytes(s); err != nil { return err } - *(*bool)(unsafe.Pointer(p)) = true + **(**bool)(unsafe.Pointer(&p)) = true return nil case 'f': if err := falseBytes(s); err != nil { return err } - *(*bool)(unsafe.Pointer(p)) = false + **(**bool)(unsafe.Pointer(&p)) = false return nil case nul: if s.read() { @@ -104,7 +104,7 @@ func (d *boolDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) return 0, errInvalidCharacter(buf[cursor+3], "bool(true)", cursor) } cursor += 4 - *(*bool)(unsafe.Pointer(p)) = true + **(**bool)(unsafe.Pointer(&p)) = true return cursor, nil case 'f': if cursor+4 >= buflen { @@ -123,7 +123,7 @@ func (d *boolDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) return 0, errInvalidCharacter(buf[cursor+4], "bool(false)", cursor) } cursor += 5 - *(*bool)(unsafe.Pointer(p)) = false + **(**bool)(unsafe.Pointer(&p)) = false return cursor, nil } return 0, errUnexpectedEndOfJSON("bool", cursor) diff --git a/decode_compile.go b/decode_compile.go index 1ed11aa..9cfe731 100644 --- a/decode_compile.go +++ b/decode_compile.go @@ -89,73 +89,73 @@ func (d *Decoder) compilePtr(typ *rtype) (decoder, error) { func (d *Decoder) compileInt() (decoder, error) { return newIntDecoder(func(p uintptr, v int64) { - *(*int)(unsafe.Pointer(p)) = int(v) + **(**int)(unsafe.Pointer(&p)) = int(v) }), nil } func (d *Decoder) compileInt8() (decoder, error) { return newIntDecoder(func(p uintptr, v int64) { - *(*int8)(unsafe.Pointer(p)) = int8(v) + **(**int8)(unsafe.Pointer(&p)) = int8(v) }), nil } func (d *Decoder) compileInt16() (decoder, error) { return newIntDecoder(func(p uintptr, v int64) { - *(*int16)(unsafe.Pointer(p)) = int16(v) + **(**int16)(unsafe.Pointer(&p)) = int16(v) }), nil } func (d *Decoder) compileInt32() (decoder, error) { return newIntDecoder(func(p uintptr, v int64) { - *(*int32)(unsafe.Pointer(p)) = int32(v) + **(**int32)(unsafe.Pointer(&p)) = int32(v) }), nil } func (d *Decoder) compileInt64() (decoder, error) { return newIntDecoder(func(p uintptr, v int64) { - *(*int64)(unsafe.Pointer(p)) = v + **(**int64)(unsafe.Pointer(&p)) = v }), nil } func (d *Decoder) compileUint() (decoder, error) { return newUintDecoder(func(p uintptr, v uint64) { - *(*uint)(unsafe.Pointer(p)) = uint(v) + **(**uint)(unsafe.Pointer(&p)) = uint(v) }), nil } func (d *Decoder) compileUint8() (decoder, error) { return newUintDecoder(func(p uintptr, v uint64) { - *(*uint8)(unsafe.Pointer(p)) = uint8(v) + **(**uint8)(unsafe.Pointer(&p)) = uint8(v) }), nil } func (d *Decoder) compileUint16() (decoder, error) { return newUintDecoder(func(p uintptr, v uint64) { - *(*uint16)(unsafe.Pointer(p)) = uint16(v) + **(**uint16)(unsafe.Pointer(&p)) = uint16(v) }), nil } func (d *Decoder) compileUint32() (decoder, error) { return newUintDecoder(func(p uintptr, v uint64) { - *(*uint32)(unsafe.Pointer(p)) = uint32(v) + **(**uint32)(unsafe.Pointer(&p)) = uint32(v) }), nil } func (d *Decoder) compileUint64() (decoder, error) { return newUintDecoder(func(p uintptr, v uint64) { - *(*uint64)(unsafe.Pointer(p)) = v + **(**uint64)(unsafe.Pointer(&p)) = v }), nil } func (d *Decoder) compileFloat32() (decoder, error) { return newFloatDecoder(func(p uintptr, v float64) { - *(*float32)(unsafe.Pointer(p)) = float32(v) + **(**float32)(unsafe.Pointer(&p)) = float32(v) }), nil } func (d *Decoder) compileFloat64() (decoder, error) { return newFloatDecoder(func(p uintptr, v float64) { - *(*float64)(unsafe.Pointer(p)) = v + **(**float64)(unsafe.Pointer(&p)) = v }), nil } diff --git a/decode_interface.go b/decode_interface.go index aa08daa..de6fd8d 100644 --- a/decode_interface.go +++ b/decode_interface.go @@ -19,11 +19,11 @@ func newInterfaceDecoder(typ *rtype) *interfaceDecoder { func (d *interfaceDecoder) numDecoder(s *stream) decoder { if s.useNumber { return newNumberDecoder(func(p uintptr, v Number) { - *(*interface{})(unsafe.Pointer(p)) = v + **(**interface{})(unsafe.Pointer(&p)) = v }) } return newFloatDecoder(func(p uintptr, v float64) { - *(*interface{})(unsafe.Pointer(p)) = v + **(**interface{})(unsafe.Pointer(&p)) = v }) } @@ -48,7 +48,7 @@ func (d *interfaceDecoder) decodeStream(s *stream, p uintptr) error { ).decodeStream(s, uintptr(ptr)); err != nil { return err } - *(*interface{})(unsafe.Pointer(p)) = v + **(**interface{})(unsafe.Pointer(&p)) = v return nil case '[': var v []interface{} @@ -61,7 +61,7 @@ func (d *interfaceDecoder) decodeStream(s *stream, p uintptr) error { ).decodeStream(s, uintptr(ptr)); err != nil { return err } - *(*interface{})(unsafe.Pointer(p)) = v + **(**interface{})(unsafe.Pointer(&p)) = v return nil case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': return d.numDecoder(s).decodeStream(s, p) @@ -77,7 +77,7 @@ func (d *interfaceDecoder) decodeStream(s *stream, p uintptr) error { case '"': literal := s.buf[start:s.cursor] s.cursor++ - *(*interface{})(unsafe.Pointer(p)) = *(*string)(unsafe.Pointer(&literal)) + **(**interface{})(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&literal)) return nil case nul: if s.read() { @@ -92,19 +92,19 @@ func (d *interfaceDecoder) decodeStream(s *stream, p uintptr) error { if err := trueBytes(s); err != nil { return err } - *(*interface{})(unsafe.Pointer(p)) = true + **(**interface{})(unsafe.Pointer(&p)) = true return nil case 'f': if err := falseBytes(s); err != nil { return err } - *(*interface{})(unsafe.Pointer(p)) = false + **(**interface{})(unsafe.Pointer(&p)) = false return nil case 'n': if err := nullBytes(s); err != nil { return err } - *(*interface{})(unsafe.Pointer(p)) = nil + **(**interface{})(unsafe.Pointer(&p)) = nil return nil case nul: if s.read() { @@ -132,7 +132,7 @@ func (d *interfaceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, e if err != nil { return 0, err } - *(*interface{})(unsafe.Pointer(p)) = v + **(**interface{})(unsafe.Pointer(&p)) = v return cursor, nil case '[': var v []interface{} @@ -147,11 +147,11 @@ func (d *interfaceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, e if err != nil { return 0, err } - *(*interface{})(unsafe.Pointer(p)) = v + **(**interface{})(unsafe.Pointer(&p)) = v return cursor, nil case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': return newFloatDecoder(func(p uintptr, v float64) { - *(*interface{})(unsafe.Pointer(p)) = v + **(**interface{})(unsafe.Pointer(&p)) = v }).decode(buf, cursor, p) case '"': cursor++ @@ -163,7 +163,7 @@ func (d *interfaceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, e case '"': literal := buf[start:cursor] cursor++ - *(*interface{})(unsafe.Pointer(p)) = *(*string)(unsafe.Pointer(&literal)) + **(**interface{})(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&literal)) return cursor, nil case nul: return 0, errUnexpectedEndOfJSON("string", cursor) @@ -185,7 +185,7 @@ func (d *interfaceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, e return 0, errInvalidCharacter(buf[cursor+3], "bool(true)", cursor) } cursor += 4 - *(*interface{})(unsafe.Pointer(p)) = true + **(**interface{})(unsafe.Pointer(&p)) = true return cursor, nil case 'f': if cursor+4 >= int64(len(buf)) { @@ -204,7 +204,7 @@ func (d *interfaceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, e return 0, errInvalidCharacter(buf[cursor+4], "bool(false)", cursor) } cursor += 5 - *(*interface{})(unsafe.Pointer(p)) = false + **(**interface{})(unsafe.Pointer(&p)) = false return cursor, nil case 'n': if cursor+3 >= int64(len(buf)) { @@ -220,7 +220,7 @@ func (d *interfaceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, e return 0, errInvalidCharacter(buf[cursor+3], "null", cursor) } cursor += 4 - *(*interface{})(unsafe.Pointer(p)) = nil + **(**interface{})(unsafe.Pointer(&p)) = nil return cursor, nil } return cursor, errNotAtBeginningOfValue(cursor) diff --git a/decode_map.go b/decode_map.go index 01bca0a..0c334f2 100644 --- a/decode_map.go +++ b/decode_map.go @@ -65,7 +65,7 @@ func (d *mapDecoder) decodeStream(s *stream, p uintptr) error { s.skipWhiteSpace() mapValue := makemap(d.mapType, 0) if s.buf[s.cursor+1] == '}' { - *(*unsafe.Pointer)(unsafe.Pointer(p)) = mapValue + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue s.cursor++ return nil } @@ -96,7 +96,7 @@ func (d *mapDecoder) decodeStream(s *stream, p uintptr) error { s.read() } if s.char() == '}' { - *(*unsafe.Pointer)(unsafe.Pointer(p)) = mapValue + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue s.cursor++ return nil } @@ -137,7 +137,7 @@ func (d *mapDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) cursor = skipWhiteSpace(buf, cursor) mapValue := makemap(d.mapType, 0) if buf[cursor] == '}' { - *(*unsafe.Pointer)(unsafe.Pointer(p)) = mapValue + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue cursor++ return cursor, nil } @@ -165,7 +165,7 @@ func (d *mapDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) mapassign(d.mapType, mapValue, unsafe.Pointer(&key), unsafe.Pointer(&value)) cursor = skipWhiteSpace(buf, valueCursor) if buf[cursor] == '}' { - *(*unsafe.Pointer)(unsafe.Pointer(p)) = mapValue + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue cursor++ return cursor, nil } diff --git a/decode_ptr.go b/decode_ptr.go index 4ce625d..900af57 100644 --- a/decode_ptr.go +++ b/decode_ptr.go @@ -21,7 +21,7 @@ func (d *ptrDecoder) decodeStream(s *stream, p uintptr) error { if err := d.dec.decodeStream(s, newptr); err != nil { return err } - *(*uintptr)(unsafe.Pointer(p)) = newptr + **(**uintptr)(unsafe.Pointer(&p)) = newptr return nil } @@ -32,6 +32,6 @@ func (d *ptrDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) return 0, err } cursor = c - *(*uintptr)(unsafe.Pointer(p)) = newptr + **(**uintptr)(unsafe.Pointer(&p)) = newptr return cursor, nil } diff --git a/decode_slice.go b/decode_slice.go index de10f25..10aa60f 100644 --- a/decode_slice.go +++ b/decode_slice.go @@ -70,7 +70,7 @@ func (d *sliceDecoder) decodeStream(s *stream, p uintptr) error { s.cursor++ s.skipWhiteSpace() if s.char() == ']' { - *(*sliceHeader)(unsafe.Pointer(p)) = sliceHeader{ + **(**sliceHeader)(unsafe.Pointer(&p)) = sliceHeader{ data: newArray(d.elemType, 0), len: 0, cap: 0, @@ -111,7 +111,7 @@ func (d *sliceDecoder) decodeStream(s *stream, p uintptr) error { len: slice.len, cap: slice.cap, }) - *(*sliceHeader)(unsafe.Pointer(p)) = dst + **(**sliceHeader)(unsafe.Pointer(&p)) = dst d.releaseSlice(slice) s.cursor++ return nil @@ -170,7 +170,7 @@ func (d *sliceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error cursor++ cursor = skipWhiteSpace(buf, cursor) if buf[cursor] == ']' { - *(*sliceHeader)(unsafe.Pointer(p)) = sliceHeader{ + **(**sliceHeader)(unsafe.Pointer(&p)) = sliceHeader{ data: newArray(d.elemType, 0), len: 0, cap: 0, @@ -212,7 +212,7 @@ func (d *sliceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error len: slice.len, cap: slice.cap, }) - *(*sliceHeader)(unsafe.Pointer(p)) = dst + **(**sliceHeader)(unsafe.Pointer(&p)) = dst d.releaseSlice(slice) cursor++ return cursor, nil diff --git a/decode_string.go b/decode_string.go index ea3855d..8722764 100644 --- a/decode_string.go +++ b/decode_string.go @@ -16,7 +16,7 @@ func (d *stringDecoder) decodeStream(s *stream, p uintptr) error { if err != nil { return err } - *(*string)(unsafe.Pointer(p)) = *(*string)(unsafe.Pointer(&bytes)) + **(**string)(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&bytes)) return nil } @@ -26,7 +26,7 @@ func (d *stringDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, erro return 0, err } cursor = c - *(*string)(unsafe.Pointer(p)) = *(*string)(unsafe.Pointer(&bytes)) + **(**string)(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&bytes)) return cursor, nil } diff --git a/decode_unmarshal_json.go b/decode_unmarshal_json.go index f84f850..75e7506 100644 --- a/decode_unmarshal_json.go +++ b/decode_unmarshal_json.go @@ -21,7 +21,7 @@ func (d *unmarshalJSONDecoder) decodeStream(s *stream, p uintptr) error { src := s.buf[start:s.cursor] v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: d.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) if err := v.(Unmarshaler).UnmarshalJSON(src); err != nil { return err @@ -39,7 +39,7 @@ func (d *unmarshalJSONDecoder) decode(buf []byte, cursor int64, p uintptr) (int6 src := buf[start:end] v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: d.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) if err := v.(Unmarshaler).UnmarshalJSON(src); err != nil { return 0, err diff --git a/decode_unmarshal_text.go b/decode_unmarshal_text.go index 17b00a8..acb0fb7 100644 --- a/decode_unmarshal_text.go +++ b/decode_unmarshal_text.go @@ -28,7 +28,7 @@ func (d *unmarshalTextDecoder) decodeStream(s *stream, p uintptr) error { } v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: d.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) if err := v.(encoding.TextUnmarshaler).UnmarshalText(src); err != nil { return err @@ -49,7 +49,7 @@ func (d *unmarshalTextDecoder) decode(buf []byte, cursor int64, p uintptr) (int6 } v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: d.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) if err := v.(encoding.TextUnmarshaler).UnmarshalText(src); err != nil { return 0, err diff --git a/encode.go b/encode.go index 0720f34..ca1cab1 100644 --- a/encode.go +++ b/encode.go @@ -191,7 +191,7 @@ func (e *Encoder) encode(v interface{}) error { } // noescape trick for header.typ ( reflect.*rtype ) - copiedType := (*rtype)(unsafe.Pointer(typeptr)) + copiedType := *(**rtype)(unsafe.Pointer(&typeptr)) codeIndent, err := e.compileHead(&encodeCompileContext{ typ: copiedType, diff --git a/encode_vm.go b/encode_vm.go index c926812..21ef38c 100644 --- a/encode_vm.go +++ b/encode_vm.go @@ -15,17 +15,19 @@ import ( const startDetectingCyclesAfter = 1000 func load(base uintptr, idx uintptr) uintptr { - return *(*uintptr)(unsafe.Pointer(base + idx)) + addr := base + idx + return **(**uintptr)(unsafe.Pointer(&addr)) } func store(base uintptr, idx uintptr, p uintptr) { - *(*uintptr)(unsafe.Pointer(base + idx)) = p + addr := base + idx + **(**uintptr)(unsafe.Pointer(&addr)) = p } func errUnsupportedValue(code *opcode, ptr uintptr) *UnsupportedValueError { v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)), })) return &UnsupportedValueError{ Value: reflect.ValueOf(v), @@ -175,7 +177,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.next case opBytes: ptr := load(ctxptr, code.idx) - header := (*sliceHeader)(unsafe.Pointer(ptr)) + header := *(**sliceHeader)(unsafe.Pointer(&ptr)) if ptr == 0 || uintptr(header.data) == 0 { e.encodeNull() } else { @@ -285,7 +287,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)), })) if _, exists := seenPtr[ptr]; exists { return &UnsupportedValueError{ @@ -368,7 +370,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { ptr := load(ctxptr, code.idx) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)), })) b, err := v.(Marshaler).MarshalJSON() if err != nil { @@ -441,7 +443,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { case opMarshalText: ptr := load(ctxptr, code.idx) isPtr := code.typ.Kind() == reflect.Ptr - p := unsafe.Pointer(ptr) + p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) if p == nil { e.encodeNull() e.encodeByte(',') @@ -498,7 +500,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.next case opSliceHead: p := load(ctxptr, code.idx) - header := (*sliceHeader)(unsafe.Pointer(p)) + header := *(**sliceHeader)(unsafe.Pointer(&p)) if p == 0 || uintptr(header.data) == 0 { e.encodeNull() e.encodeByte(',') @@ -540,7 +542,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) code = code.end.next } else { - header := (*sliceHeader)(unsafe.Pointer(p)) + header := *(**sliceHeader)(unsafe.Pointer(&p)) store(ctxptr, code.elemIdx, 0) store(ctxptr, code.length, uintptr(header.len)) store(ctxptr, code.idx, uintptr(header.data)) @@ -563,7 +565,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) code = code.end.next } else { - header := (*sliceHeader)(unsafe.Pointer(p)) + header := *(**sliceHeader)(unsafe.Pointer(&p)) store(ctxptr, code.elemIdx, 0) store(ctxptr, code.length, uintptr(header.len)) store(ctxptr, code.idx, uintptr(header.data)) @@ -688,10 +690,11 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') code = code.end.next } else { - mlen := maplen(unsafe.Pointer(ptr)) + uptr := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) + mlen := maplen(uptr) if mlen > 0 { e.encodeByte('{') - iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) + iter := mapiterinit(code.typ, uptr) ctx.keepRefs = append(ctx.keepRefs, iter) store(ctxptr, code.elemIdx, 0) store(ctxptr, code.length, uintptr(mlen)) @@ -719,17 +722,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { // load pointer - ptr = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(ptr))) + ptr = uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&ptr))) + uptr := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) if ptr == 0 { e.encodeNull() e.encodeByte(',') code = code.end.next break } - mlen := maplen(unsafe.Pointer(ptr)) + mlen := maplen(uptr) if mlen > 0 { e.encodeByte('{') - iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) + iter := mapiterinit(code.typ, uptr) ctx.keepRefs = append(ctx.keepRefs, iter) store(ctxptr, code.elemIdx, 0) store(ctxptr, code.length, uintptr(mlen)) @@ -755,7 +759,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { idx++ if e.unorderedMap { if idx < length { - iter := unsafe.Pointer(load(ctxptr, code.mapIter)) + ptr := load(ctxptr, code.mapIter) + iter := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) store(ctxptr, code.elemIdx, idx) key := mapiterkey(iter) store(ctxptr, code.next.idx, uintptr(key)) @@ -767,10 +772,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } } else { - posPtr := (*[]int)(unsafe.Pointer(load(ctxptr, code.end.mapPos))) + ptr := load(ctxptr, code.end.mapPos) + posPtr := (*[]int)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr))) *posPtr = append(*posPtr, len(e.buf)) if idx < length { - iter := unsafe.Pointer(load(ctxptr, code.mapIter)) + ptr := load(ctxptr, code.mapIter) + iter := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) store(ctxptr, code.elemIdx, idx) key := mapiterkey(iter) store(ctxptr, code.next.idx, uintptr(key)) @@ -784,10 +791,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { last := len(e.buf) - 1 e.buf[last] = ':' } else { - posPtr := (*[]int)(unsafe.Pointer(load(ctxptr, code.end.mapPos))) + ptr := load(ctxptr, code.end.mapPos) + posPtr := (*[]int)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr))) *posPtr = append(*posPtr, len(e.buf)) } - iter := unsafe.Pointer(load(ctxptr, code.mapIter)) + ptr := load(ctxptr, code.mapIter) + iter := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) value := mapitervalue(iter) store(ctxptr, code.next.idx, uintptr(value)) mapiternext(iter) @@ -800,7 +809,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { value string } kvs := make([]mapKV, 0, length) - posPtr := unsafe.Pointer(load(ctxptr, code.mapPos)) + ptr := load(ctxptr, code.mapPos) + posPtr := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) pos := *(*[]int)(posPtr) for i := 0; i < length; i++ { startKey := pos[i*2] @@ -839,10 +849,11 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) code = code.end.next } else { - mlen := maplen(unsafe.Pointer(ptr)) + uptr := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) + mlen := maplen(uptr) if mlen > 0 { e.encodeBytes([]byte{'{', '\n'}) - iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) + iter := mapiterinit(code.typ, uptr) ctx.keepRefs = append(ctx.keepRefs, iter) store(ctxptr, code.elemIdx, 0) store(ctxptr, code.length, uintptr(mlen)) @@ -875,18 +886,19 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { // load pointer - ptr = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(ptr))) - if ptr == 0 { + ptr = uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&ptr))) + uptr := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) + if uintptr(uptr) == 0 { e.encodeIndent(code.indent) e.encodeNull() e.encodeBytes([]byte{',', '\n'}) code = code.end.next break } - mlen := maplen(unsafe.Pointer(ptr)) + mlen := maplen(uptr) if mlen > 0 { e.encodeBytes([]byte{'{', '\n'}) - iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) + iter := mapiterinit(code.typ, uptr) ctx.keepRefs = append(ctx.keepRefs, iter) store(ctxptr, code.elemIdx, 0) store(ctxptr, code.length, uintptr(mlen)) @@ -919,7 +931,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if idx < length { e.encodeIndent(code.indent) store(ctxptr, code.elemIdx, idx) - iter := unsafe.Pointer(load(ctxptr, code.mapIter)) + ptr := load(ctxptr, code.mapIter) + iter := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) key := mapiterkey(iter) store(ctxptr, code.next.idx, uintptr(key)) code = code.next @@ -931,10 +944,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } } else { - posPtr := (*[]int)(unsafe.Pointer(load(ctxptr, code.end.mapPos))) + ptr := load(ctxptr, code.end.mapPos) + posPtr := (*[]int)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr))) *posPtr = append(*posPtr, len(e.buf)) if idx < length { - iter := unsafe.Pointer(load(ctxptr, code.mapIter)) + ptr := load(ctxptr, code.mapIter) + iter := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) store(ctxptr, code.elemIdx, idx) key := mapiterkey(iter) store(ctxptr, code.next.idx, uintptr(key)) @@ -947,10 +962,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.unorderedMap { e.encodeBytes([]byte{':', ' '}) } else { - posPtr := (*[]int)(unsafe.Pointer(load(ctxptr, code.end.mapPos))) + ptr := load(ctxptr, code.end.mapPos) + posPtr := (*[]int)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr))) *posPtr = append(*posPtr, len(e.buf)) } - iter := unsafe.Pointer(load(ctxptr, code.mapIter)) + ptr := load(ctxptr, code.mapIter) + iter := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) value := mapitervalue(iter) store(ctxptr, code.next.idx, uintptr(value)) mapiternext(iter) @@ -963,7 +980,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { value string } kvs := make([]mapKV, 0, length) - pos := *(*[]int)(unsafe.Pointer(load(ctxptr, code.mapPos))) + ptr := load(ctxptr, code.mapPos) + pos := *(*[]int)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr))) for i := 0; i < length; i++ { startKey := pos[i*2] startValue := pos[i*2+1] @@ -1053,7 +1071,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { // restore ctxptr offset := load(ctxptr, code.idx) - code = (*opcode)(unsafe.Pointer(load(ctxptr, code.elemIdx))) + ptr := load(ctxptr, code.elemIdx) + code = (*opcode)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr))) ctxptr = ctx.ptr() + offset ptrOffset = offset case opStructFieldPtrHead: @@ -1807,9 +1826,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeByte('{') e.encodeKey(code) + ptr += code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr + code.offset), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)), })) rv := reflect.ValueOf(v) if rv.Type().Kind() == reflect.Interface && rv.IsNil() { @@ -1847,9 +1867,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeKey(code) + ptr += code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr + code.offset), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)), })) rv := reflect.ValueOf(v) if rv.Type().Kind() == reflect.Interface && rv.IsNil() { @@ -1897,9 +1918,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeByte('{') e.encodeKey(code) + ptr += code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr + code.offset), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)), })) rv := reflect.ValueOf(v) if rv.Type().Kind() == reflect.Interface && rv.IsNil() { @@ -1928,9 +1950,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeKey(code) + ptr += code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr + code.offset), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)), })) rv := reflect.ValueOf(v) if rv.Type().Kind() == reflect.Interface && rv.IsNil() { @@ -2304,7 +2327,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeByte('{') p := ptr + code.offset - if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { + if p == 0 || *(*uintptr)(*(*unsafe.Pointer)(unsafe.Pointer(&p))) == 0 { code = code.nextField } else { e.encodeKey(code) @@ -2324,7 +2347,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { p := ptr + code.offset - if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { + if p == 0 || *(*uintptr)(*(*unsafe.Pointer)(unsafe.Pointer(&p))) == 0 { code = code.nextField } else { e.encodeKey(code) @@ -3033,7 +3056,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - p := unsafe.Pointer(ptr + code.offset) + ptr += code.offset + p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) isPtr := code.typ.Kind() == reflect.Ptr if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) { code = code.nextField @@ -3077,7 +3101,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - p := unsafe.Pointer(ptr + code.offset) + ptr += code.offset + p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) isPtr := code.typ.Kind() == reflect.Ptr if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) { code = code.nextField @@ -3124,7 +3149,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - p := unsafe.Pointer(ptr + code.offset) + ptr += code.offset + p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) isPtr := code.typ.Kind() == reflect.Ptr if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) { code = code.nextField @@ -3154,7 +3180,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - p := unsafe.Pointer(ptr + code.offset) + ptr += code.offset + p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) isPtr := code.typ.Kind() == reflect.Ptr if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) { code = code.nextField @@ -3190,7 +3217,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) p := ptr + code.offset - if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { + if p == 0 || *(*uintptr)(*(*unsafe.Pointer)(unsafe.Pointer(&p))) == 0 { code = code.nextField } else { e.encodeIndent(code.indent + 1) @@ -4225,7 +4252,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - p := unsafe.Pointer(ptr + code.offset) + ptr += code.offset + p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) isPtr := code.typ.Kind() == reflect.Ptr v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) b, err := v.(Marshaler).MarshalJSON() @@ -4267,7 +4295,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - p := unsafe.Pointer(ptr + code.offset) + ptr += code.offset + p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) isPtr := code.typ.Kind() == reflect.Ptr v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) b, err := v.(Marshaler).MarshalJSON() @@ -4313,7 +4342,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - p := unsafe.Pointer(ptr + code.offset) + ptr += code.offset + p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { @@ -4338,7 +4368,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - p := unsafe.Pointer(ptr + code.offset) + ptr += code.offset + p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { @@ -4997,7 +5028,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) b, err := v.(Marshaler).MarshalJSON() if err != nil { @@ -5019,7 +5050,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { @@ -5207,7 +5238,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) b, err := v.(Marshaler).MarshalJSON() if err != nil { @@ -5229,7 +5260,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - header := (*sliceHeader)(unsafe.Pointer(p)) + header := *(**sliceHeader)(unsafe.Pointer(&p)) if p == 0 || uintptr(header.data) == 0 { e.encodeNull() e.encodeBytes([]byte{',', '\n'}) @@ -5243,7 +5274,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - header := (*sliceHeader)(unsafe.Pointer(p)) + header := *(**sliceHeader)(unsafe.Pointer(&p)) if p == 0 || uintptr(header.data) == 0 { e.encodeNull() e.encodeBytes([]byte{',', '\n'}) @@ -5261,7 +5292,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeNull() code = code.nextField } else { - mlen := maplen(unsafe.Pointer(p)) + p = uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) + mlen := maplen(*(*unsafe.Pointer)(unsafe.Pointer(&p))) if mlen == 0 { e.encodeBytes([]byte{'{', '}', ',', '\n'}) mapCode := code.next @@ -5280,8 +5312,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeNull() code = code.nextField } else { - p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p))) - mlen := maplen(unsafe.Pointer(p)) + p = uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) + mlen := maplen(*(*unsafe.Pointer)(unsafe.Pointer(&p))) if mlen == 0 { e.encodeBytes([]byte{'{', '}', ',', '\n'}) code = code.nextField @@ -5312,7 +5344,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { case opStructFieldOmitEmpty: ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { + if p == 0 || **(**uintptr)(unsafe.Pointer(&p)) == 0 { code = code.nextField } else { e.encodeKey(code) @@ -5465,7 +5497,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) if v != nil { b, err := v.(Marshaler).MarshalJSON() @@ -5488,12 +5520,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) if v != nil { v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { @@ -5509,7 +5541,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { case opStructFieldOmitEmptyArray: ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - header := (*sliceHeader)(unsafe.Pointer(p)) + header := *(**sliceHeader)(unsafe.Pointer(&p)) if p == 0 || uintptr(header.data) == 0 { code = code.nextField } else { @@ -5518,7 +5550,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { case opStructFieldOmitEmptySlice: ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - header := (*sliceHeader)(unsafe.Pointer(p)) + header := *(**sliceHeader)(unsafe.Pointer(&p)) if p == 0 || uintptr(header.data) == 0 { code = code.nextField } else { @@ -5530,7 +5562,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if p == 0 { code = code.nextField } else { - mlen := maplen(unsafe.Pointer(p)) + mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p))) if mlen == 0 { code = code.nextField } else { @@ -5543,8 +5575,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if p == 0 { code = code.nextField } else { - p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p))) - mlen := maplen(unsafe.Pointer(p)) + mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p))) if mlen == 0 { code = code.nextField } else { @@ -5554,7 +5585,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { case opStructFieldOmitEmptyIndent: ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { + if p == 0 || **(**uintptr)(unsafe.Pointer(&p)) == 0 { code = code.nextField } else { e.encodeIndent(code.indent) @@ -5740,7 +5771,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { case opStructFieldOmitEmptyArrayIndent: ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - header := (*sliceHeader)(unsafe.Pointer(p)) + header := *(**sliceHeader)(unsafe.Pointer(&p)) if p == 0 || uintptr(header.data) == 0 { code = code.nextField } else { @@ -5752,7 +5783,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { case opStructFieldOmitEmptySliceIndent: ptr := load(ctxptr, code.headIdx) p := ptr + code.offset - header := (*sliceHeader)(unsafe.Pointer(p)) + header := *(**sliceHeader)(unsafe.Pointer(&p)) if p == 0 || uintptr(header.data) == 0 { code = code.nextField } else { @@ -5767,7 +5798,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if p == 0 { code = code.nextField } else { - mlen := maplen(unsafe.Pointer(p)) + mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p))) if mlen == 0 { code = code.nextField } else { @@ -5783,8 +5814,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if p == 0 { code = code.nextField } else { - p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p))) - mlen := maplen(unsafe.Pointer(p)) + mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p))) if mlen == 0 { code = code.nextField } else { @@ -5924,7 +5954,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) b, err := v.(Marshaler).MarshalJSON() if err != nil { @@ -5945,7 +5975,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { @@ -6109,7 +6139,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) b, err := v.(Marshaler).MarshalJSON() if err != nil { @@ -6133,7 +6163,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(p), + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { @@ -6175,20 +6205,20 @@ END: return nil } -func (e *Encoder) ptrToPtr(p uintptr) uintptr { return *(*uintptr)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToInt(p uintptr) int { return *(*int)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToInt8(p uintptr) int8 { return *(*int8)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToInt16(p uintptr) int16 { return *(*int16)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToInt32(p uintptr) int32 { return *(*int32)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToInt64(p uintptr) int64 { return *(*int64)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToUint(p uintptr) uint { return *(*uint)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToUint8(p uintptr) uint8 { return *(*uint8)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToUint16(p uintptr) uint16 { return *(*uint16)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToUint32(p uintptr) uint32 { return *(*uint32)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToUint64(p uintptr) uint64 { return *(*uint64)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToFloat32(p uintptr) float32 { return *(*float32)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToFloat64(p uintptr) float64 { return *(*float64)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToBool(p uintptr) bool { return *(*bool)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToByte(p uintptr) byte { return *(*byte)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToBytes(p uintptr) []byte { return *(*[]byte)(unsafe.Pointer(p)) } -func (e *Encoder) ptrToString(p uintptr) string { return *(*string)(unsafe.Pointer(p)) } +func (e *Encoder) ptrToPtr(p uintptr) uintptr { return **(**uintptr)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToInt(p uintptr) int { return **(**int)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToInt8(p uintptr) int8 { return **(**int8)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToInt16(p uintptr) int16 { return **(**int16)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToInt32(p uintptr) int32 { return **(**int32)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToInt64(p uintptr) int64 { return **(**int64)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToUint(p uintptr) uint { return **(**uint)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToUint8(p uintptr) uint8 { return **(**uint8)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToUint16(p uintptr) uint16 { return **(**uint16)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToUint32(p uintptr) uint32 { return **(**uint32)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToUint64(p uintptr) uint64 { return **(**uint64)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToByte(p uintptr) byte { return **(**byte)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func (e *Encoder) ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) }