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
This commit is contained in:
Cuong Manh Le 2020-11-15 03:27:15 +07:00
parent e58b1eabaf
commit 6b1d701387
No known key found for this signature in database
GPG Key ID: C3FA65829435642E
12 changed files with 173 additions and 143 deletions

View File

@ -85,7 +85,7 @@ func (d *Decoder) decode(src []byte, header *interfaceHeader) error {
typeptr := uintptr(unsafe.Pointer(typ)) typeptr := uintptr(unsafe.Pointer(typ))
// noescape trick for header.typ ( reflect.*rtype ) // noescape trick for header.typ ( reflect.*rtype )
copiedType := (*rtype)(unsafe.Pointer(typeptr)) copiedType := *(**rtype)(unsafe.Pointer(&typeptr))
ptr := uintptr(header.ptr) ptr := uintptr(header.ptr)
if err := d.validateType(copiedType, ptr); err != nil { if err := d.validateType(copiedType, ptr); err != nil {
@ -150,7 +150,7 @@ func (d *Decoder) Decode(v interface{}) error {
ptr := uintptr(header.ptr) ptr := uintptr(header.ptr)
typeptr := uintptr(unsafe.Pointer(typ)) typeptr := uintptr(unsafe.Pointer(typ))
// noescape trick for header.typ ( reflect.*rtype ) // 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 { if err := d.validateType(copiedType, ptr); err != nil {
return err return err

View File

@ -66,13 +66,13 @@ func (d *boolDecoder) decodeStream(s *stream, p uintptr) error {
if err := trueBytes(s); err != nil { if err := trueBytes(s); err != nil {
return err return err
} }
*(*bool)(unsafe.Pointer(p)) = true **(**bool)(unsafe.Pointer(&p)) = true
return nil return nil
case 'f': case 'f':
if err := falseBytes(s); err != nil { if err := falseBytes(s); err != nil {
return err return err
} }
*(*bool)(unsafe.Pointer(p)) = false **(**bool)(unsafe.Pointer(&p)) = false
return nil return nil
case nul: case nul:
if s.read() { 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) return 0, errInvalidCharacter(buf[cursor+3], "bool(true)", cursor)
} }
cursor += 4 cursor += 4
*(*bool)(unsafe.Pointer(p)) = true **(**bool)(unsafe.Pointer(&p)) = true
return cursor, nil return cursor, nil
case 'f': case 'f':
if cursor+4 >= buflen { 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) return 0, errInvalidCharacter(buf[cursor+4], "bool(false)", cursor)
} }
cursor += 5 cursor += 5
*(*bool)(unsafe.Pointer(p)) = false **(**bool)(unsafe.Pointer(&p)) = false
return cursor, nil return cursor, nil
} }
return 0, errUnexpectedEndOfJSON("bool", cursor) return 0, errUnexpectedEndOfJSON("bool", cursor)

View File

@ -89,73 +89,73 @@ func (d *Decoder) compilePtr(typ *rtype) (decoder, error) {
func (d *Decoder) compileInt() (decoder, error) { func (d *Decoder) compileInt() (decoder, error) {
return newIntDecoder(func(p uintptr, v int64) { return newIntDecoder(func(p uintptr, v int64) {
*(*int)(unsafe.Pointer(p)) = int(v) **(**int)(unsafe.Pointer(&p)) = int(v)
}), nil }), nil
} }
func (d *Decoder) compileInt8() (decoder, error) { func (d *Decoder) compileInt8() (decoder, error) {
return newIntDecoder(func(p uintptr, v int64) { return newIntDecoder(func(p uintptr, v int64) {
*(*int8)(unsafe.Pointer(p)) = int8(v) **(**int8)(unsafe.Pointer(&p)) = int8(v)
}), nil }), nil
} }
func (d *Decoder) compileInt16() (decoder, error) { func (d *Decoder) compileInt16() (decoder, error) {
return newIntDecoder(func(p uintptr, v int64) { return newIntDecoder(func(p uintptr, v int64) {
*(*int16)(unsafe.Pointer(p)) = int16(v) **(**int16)(unsafe.Pointer(&p)) = int16(v)
}), nil }), nil
} }
func (d *Decoder) compileInt32() (decoder, error) { func (d *Decoder) compileInt32() (decoder, error) {
return newIntDecoder(func(p uintptr, v int64) { return newIntDecoder(func(p uintptr, v int64) {
*(*int32)(unsafe.Pointer(p)) = int32(v) **(**int32)(unsafe.Pointer(&p)) = int32(v)
}), nil }), nil
} }
func (d *Decoder) compileInt64() (decoder, error) { func (d *Decoder) compileInt64() (decoder, error) {
return newIntDecoder(func(p uintptr, v int64) { return newIntDecoder(func(p uintptr, v int64) {
*(*int64)(unsafe.Pointer(p)) = v **(**int64)(unsafe.Pointer(&p)) = v
}), nil }), nil
} }
func (d *Decoder) compileUint() (decoder, error) { func (d *Decoder) compileUint() (decoder, error) {
return newUintDecoder(func(p uintptr, v uint64) { return newUintDecoder(func(p uintptr, v uint64) {
*(*uint)(unsafe.Pointer(p)) = uint(v) **(**uint)(unsafe.Pointer(&p)) = uint(v)
}), nil }), nil
} }
func (d *Decoder) compileUint8() (decoder, error) { func (d *Decoder) compileUint8() (decoder, error) {
return newUintDecoder(func(p uintptr, v uint64) { return newUintDecoder(func(p uintptr, v uint64) {
*(*uint8)(unsafe.Pointer(p)) = uint8(v) **(**uint8)(unsafe.Pointer(&p)) = uint8(v)
}), nil }), nil
} }
func (d *Decoder) compileUint16() (decoder, error) { func (d *Decoder) compileUint16() (decoder, error) {
return newUintDecoder(func(p uintptr, v uint64) { return newUintDecoder(func(p uintptr, v uint64) {
*(*uint16)(unsafe.Pointer(p)) = uint16(v) **(**uint16)(unsafe.Pointer(&p)) = uint16(v)
}), nil }), nil
} }
func (d *Decoder) compileUint32() (decoder, error) { func (d *Decoder) compileUint32() (decoder, error) {
return newUintDecoder(func(p uintptr, v uint64) { return newUintDecoder(func(p uintptr, v uint64) {
*(*uint32)(unsafe.Pointer(p)) = uint32(v) **(**uint32)(unsafe.Pointer(&p)) = uint32(v)
}), nil }), nil
} }
func (d *Decoder) compileUint64() (decoder, error) { func (d *Decoder) compileUint64() (decoder, error) {
return newUintDecoder(func(p uintptr, v uint64) { return newUintDecoder(func(p uintptr, v uint64) {
*(*uint64)(unsafe.Pointer(p)) = v **(**uint64)(unsafe.Pointer(&p)) = v
}), nil }), nil
} }
func (d *Decoder) compileFloat32() (decoder, error) { func (d *Decoder) compileFloat32() (decoder, error) {
return newFloatDecoder(func(p uintptr, v float64) { return newFloatDecoder(func(p uintptr, v float64) {
*(*float32)(unsafe.Pointer(p)) = float32(v) **(**float32)(unsafe.Pointer(&p)) = float32(v)
}), nil }), nil
} }
func (d *Decoder) compileFloat64() (decoder, error) { func (d *Decoder) compileFloat64() (decoder, error) {
return newFloatDecoder(func(p uintptr, v float64) { return newFloatDecoder(func(p uintptr, v float64) {
*(*float64)(unsafe.Pointer(p)) = v **(**float64)(unsafe.Pointer(&p)) = v
}), nil }), nil
} }

View File

@ -19,11 +19,11 @@ func newInterfaceDecoder(typ *rtype) *interfaceDecoder {
func (d *interfaceDecoder) numDecoder(s *stream) decoder { func (d *interfaceDecoder) numDecoder(s *stream) decoder {
if s.useNumber { if s.useNumber {
return newNumberDecoder(func(p uintptr, v Number) { return newNumberDecoder(func(p uintptr, v Number) {
*(*interface{})(unsafe.Pointer(p)) = v **(**interface{})(unsafe.Pointer(&p)) = v
}) })
} }
return newFloatDecoder(func(p uintptr, v float64) { 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 { ).decodeStream(s, uintptr(ptr)); err != nil {
return err return err
} }
*(*interface{})(unsafe.Pointer(p)) = v **(**interface{})(unsafe.Pointer(&p)) = v
return nil return nil
case '[': case '[':
var v []interface{} var v []interface{}
@ -61,7 +61,7 @@ func (d *interfaceDecoder) decodeStream(s *stream, p uintptr) error {
).decodeStream(s, uintptr(ptr)); err != nil { ).decodeStream(s, uintptr(ptr)); err != nil {
return err return err
} }
*(*interface{})(unsafe.Pointer(p)) = v **(**interface{})(unsafe.Pointer(&p)) = v
return nil return nil
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return d.numDecoder(s).decodeStream(s, p) return d.numDecoder(s).decodeStream(s, p)
@ -77,7 +77,7 @@ func (d *interfaceDecoder) decodeStream(s *stream, p uintptr) error {
case '"': case '"':
literal := s.buf[start:s.cursor] literal := s.buf[start:s.cursor]
s.cursor++ s.cursor++
*(*interface{})(unsafe.Pointer(p)) = *(*string)(unsafe.Pointer(&literal)) **(**interface{})(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&literal))
return nil return nil
case nul: case nul:
if s.read() { if s.read() {
@ -92,19 +92,19 @@ func (d *interfaceDecoder) decodeStream(s *stream, p uintptr) error {
if err := trueBytes(s); err != nil { if err := trueBytes(s); err != nil {
return err return err
} }
*(*interface{})(unsafe.Pointer(p)) = true **(**interface{})(unsafe.Pointer(&p)) = true
return nil return nil
case 'f': case 'f':
if err := falseBytes(s); err != nil { if err := falseBytes(s); err != nil {
return err return err
} }
*(*interface{})(unsafe.Pointer(p)) = false **(**interface{})(unsafe.Pointer(&p)) = false
return nil return nil
case 'n': case 'n':
if err := nullBytes(s); err != nil { if err := nullBytes(s); err != nil {
return err return err
} }
*(*interface{})(unsafe.Pointer(p)) = nil **(**interface{})(unsafe.Pointer(&p)) = nil
return nil return nil
case nul: case nul:
if s.read() { if s.read() {
@ -132,7 +132,7 @@ func (d *interfaceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, e
if err != nil { if err != nil {
return 0, err return 0, err
} }
*(*interface{})(unsafe.Pointer(p)) = v **(**interface{})(unsafe.Pointer(&p)) = v
return cursor, nil return cursor, nil
case '[': case '[':
var v []interface{} var v []interface{}
@ -147,11 +147,11 @@ func (d *interfaceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, e
if err != nil { if err != nil {
return 0, err return 0, err
} }
*(*interface{})(unsafe.Pointer(p)) = v **(**interface{})(unsafe.Pointer(&p)) = v
return cursor, nil return cursor, nil
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return newFloatDecoder(func(p uintptr, v float64) { return newFloatDecoder(func(p uintptr, v float64) {
*(*interface{})(unsafe.Pointer(p)) = v **(**interface{})(unsafe.Pointer(&p)) = v
}).decode(buf, cursor, p) }).decode(buf, cursor, p)
case '"': case '"':
cursor++ cursor++
@ -163,7 +163,7 @@ func (d *interfaceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, e
case '"': case '"':
literal := buf[start:cursor] literal := buf[start:cursor]
cursor++ cursor++
*(*interface{})(unsafe.Pointer(p)) = *(*string)(unsafe.Pointer(&literal)) **(**interface{})(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&literal))
return cursor, nil return cursor, nil
case nul: case nul:
return 0, errUnexpectedEndOfJSON("string", cursor) 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) return 0, errInvalidCharacter(buf[cursor+3], "bool(true)", cursor)
} }
cursor += 4 cursor += 4
*(*interface{})(unsafe.Pointer(p)) = true **(**interface{})(unsafe.Pointer(&p)) = true
return cursor, nil return cursor, nil
case 'f': case 'f':
if cursor+4 >= int64(len(buf)) { 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) return 0, errInvalidCharacter(buf[cursor+4], "bool(false)", cursor)
} }
cursor += 5 cursor += 5
*(*interface{})(unsafe.Pointer(p)) = false **(**interface{})(unsafe.Pointer(&p)) = false
return cursor, nil return cursor, nil
case 'n': case 'n':
if cursor+3 >= int64(len(buf)) { 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) return 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
} }
cursor += 4 cursor += 4
*(*interface{})(unsafe.Pointer(p)) = nil **(**interface{})(unsafe.Pointer(&p)) = nil
return cursor, nil return cursor, nil
} }
return cursor, errNotAtBeginningOfValue(cursor) return cursor, errNotAtBeginningOfValue(cursor)

View File

@ -65,7 +65,7 @@ func (d *mapDecoder) decodeStream(s *stream, p uintptr) error {
s.skipWhiteSpace() s.skipWhiteSpace()
mapValue := makemap(d.mapType, 0) mapValue := makemap(d.mapType, 0)
if s.buf[s.cursor+1] == '}' { if s.buf[s.cursor+1] == '}' {
*(*unsafe.Pointer)(unsafe.Pointer(p)) = mapValue **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue
s.cursor++ s.cursor++
return nil return nil
} }
@ -96,7 +96,7 @@ func (d *mapDecoder) decodeStream(s *stream, p uintptr) error {
s.read() s.read()
} }
if s.char() == '}' { if s.char() == '}' {
*(*unsafe.Pointer)(unsafe.Pointer(p)) = mapValue **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue
s.cursor++ s.cursor++
return nil return nil
} }
@ -137,7 +137,7 @@ func (d *mapDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error)
cursor = skipWhiteSpace(buf, cursor) cursor = skipWhiteSpace(buf, cursor)
mapValue := makemap(d.mapType, 0) mapValue := makemap(d.mapType, 0)
if buf[cursor] == '}' { if buf[cursor] == '}' {
*(*unsafe.Pointer)(unsafe.Pointer(p)) = mapValue **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue
cursor++ cursor++
return cursor, nil 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)) mapassign(d.mapType, mapValue, unsafe.Pointer(&key), unsafe.Pointer(&value))
cursor = skipWhiteSpace(buf, valueCursor) cursor = skipWhiteSpace(buf, valueCursor)
if buf[cursor] == '}' { if buf[cursor] == '}' {
*(*unsafe.Pointer)(unsafe.Pointer(p)) = mapValue **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue
cursor++ cursor++
return cursor, nil return cursor, nil
} }

View File

@ -21,7 +21,7 @@ func (d *ptrDecoder) decodeStream(s *stream, p uintptr) error {
if err := d.dec.decodeStream(s, newptr); err != nil { if err := d.dec.decodeStream(s, newptr); err != nil {
return err return err
} }
*(*uintptr)(unsafe.Pointer(p)) = newptr **(**uintptr)(unsafe.Pointer(&p)) = newptr
return nil return nil
} }
@ -32,6 +32,6 @@ func (d *ptrDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error)
return 0, err return 0, err
} }
cursor = c cursor = c
*(*uintptr)(unsafe.Pointer(p)) = newptr **(**uintptr)(unsafe.Pointer(&p)) = newptr
return cursor, nil return cursor, nil
} }

View File

@ -70,7 +70,7 @@ func (d *sliceDecoder) decodeStream(s *stream, p uintptr) error {
s.cursor++ s.cursor++
s.skipWhiteSpace() s.skipWhiteSpace()
if s.char() == ']' { if s.char() == ']' {
*(*sliceHeader)(unsafe.Pointer(p)) = sliceHeader{ **(**sliceHeader)(unsafe.Pointer(&p)) = sliceHeader{
data: newArray(d.elemType, 0), data: newArray(d.elemType, 0),
len: 0, len: 0,
cap: 0, cap: 0,
@ -111,7 +111,7 @@ func (d *sliceDecoder) decodeStream(s *stream, p uintptr) error {
len: slice.len, len: slice.len,
cap: slice.cap, cap: slice.cap,
}) })
*(*sliceHeader)(unsafe.Pointer(p)) = dst **(**sliceHeader)(unsafe.Pointer(&p)) = dst
d.releaseSlice(slice) d.releaseSlice(slice)
s.cursor++ s.cursor++
return nil return nil
@ -170,7 +170,7 @@ func (d *sliceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error
cursor++ cursor++
cursor = skipWhiteSpace(buf, cursor) cursor = skipWhiteSpace(buf, cursor)
if buf[cursor] == ']' { if buf[cursor] == ']' {
*(*sliceHeader)(unsafe.Pointer(p)) = sliceHeader{ **(**sliceHeader)(unsafe.Pointer(&p)) = sliceHeader{
data: newArray(d.elemType, 0), data: newArray(d.elemType, 0),
len: 0, len: 0,
cap: 0, cap: 0,
@ -212,7 +212,7 @@ func (d *sliceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error
len: slice.len, len: slice.len,
cap: slice.cap, cap: slice.cap,
}) })
*(*sliceHeader)(unsafe.Pointer(p)) = dst **(**sliceHeader)(unsafe.Pointer(&p)) = dst
d.releaseSlice(slice) d.releaseSlice(slice)
cursor++ cursor++
return cursor, nil return cursor, nil

View File

@ -16,7 +16,7 @@ func (d *stringDecoder) decodeStream(s *stream, p uintptr) error {
if err != nil { if err != nil {
return err return err
} }
*(*string)(unsafe.Pointer(p)) = *(*string)(unsafe.Pointer(&bytes)) **(**string)(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&bytes))
return nil return nil
} }
@ -26,7 +26,7 @@ func (d *stringDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, erro
return 0, err return 0, err
} }
cursor = c cursor = c
*(*string)(unsafe.Pointer(p)) = *(*string)(unsafe.Pointer(&bytes)) **(**string)(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&bytes))
return cursor, nil return cursor, nil
} }

View File

@ -21,7 +21,7 @@ func (d *unmarshalJSONDecoder) decodeStream(s *stream, p uintptr) error {
src := s.buf[start:s.cursor] src := s.buf[start:s.cursor]
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: d.typ, typ: d.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
if err := v.(Unmarshaler).UnmarshalJSON(src); err != nil { if err := v.(Unmarshaler).UnmarshalJSON(src); err != nil {
return err return err
@ -39,7 +39,7 @@ func (d *unmarshalJSONDecoder) decode(buf []byte, cursor int64, p uintptr) (int6
src := buf[start:end] src := buf[start:end]
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: d.typ, typ: d.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
if err := v.(Unmarshaler).UnmarshalJSON(src); err != nil { if err := v.(Unmarshaler).UnmarshalJSON(src); err != nil {
return 0, err return 0, err

View File

@ -28,7 +28,7 @@ func (d *unmarshalTextDecoder) decodeStream(s *stream, p uintptr) error {
} }
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: d.typ, typ: d.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
if err := v.(encoding.TextUnmarshaler).UnmarshalText(src); err != nil { if err := v.(encoding.TextUnmarshaler).UnmarshalText(src); err != nil {
return err return err
@ -49,7 +49,7 @@ func (d *unmarshalTextDecoder) decode(buf []byte, cursor int64, p uintptr) (int6
} }
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: d.typ, typ: d.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
if err := v.(encoding.TextUnmarshaler).UnmarshalText(src); err != nil { if err := v.(encoding.TextUnmarshaler).UnmarshalText(src); err != nil {
return 0, err return 0, err

View File

@ -191,7 +191,7 @@ func (e *Encoder) encode(v interface{}) error {
} }
// noescape trick for header.typ ( reflect.*rtype ) // noescape trick for header.typ ( reflect.*rtype )
copiedType := (*rtype)(unsafe.Pointer(typeptr)) copiedType := *(**rtype)(unsafe.Pointer(&typeptr))
codeIndent, err := e.compileHead(&encodeCompileContext{ codeIndent, err := e.compileHead(&encodeCompileContext{
typ: copiedType, typ: copiedType,

View File

@ -15,17 +15,19 @@ import (
const startDetectingCyclesAfter = 1000 const startDetectingCyclesAfter = 1000
func load(base uintptr, idx uintptr) uintptr { 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) { 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 { func errUnsupportedValue(code *opcode, ptr uintptr) *UnsupportedValueError {
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(ptr), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)),
})) }))
return &UnsupportedValueError{ return &UnsupportedValueError{
Value: reflect.ValueOf(v), Value: reflect.ValueOf(v),
@ -175,7 +177,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.next code = code.next
case opBytes: case opBytes:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
header := (*sliceHeader)(unsafe.Pointer(ptr)) header := *(**sliceHeader)(unsafe.Pointer(&ptr))
if ptr == 0 || uintptr(header.data) == 0 { if ptr == 0 || uintptr(header.data) == 0 {
e.encodeNull() e.encodeNull()
} else { } else {
@ -285,7 +287,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
} }
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(ptr), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)),
})) }))
if _, exists := seenPtr[ptr]; exists { if _, exists := seenPtr[ptr]; exists {
return &UnsupportedValueError{ return &UnsupportedValueError{
@ -368,7 +370,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(ptr), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)),
})) }))
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
if err != nil { if err != nil {
@ -441,7 +443,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
case opMarshalText: case opMarshalText:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
isPtr := code.typ.Kind() == reflect.Ptr isPtr := code.typ.Kind() == reflect.Ptr
p := unsafe.Pointer(ptr) p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr))
if p == nil { if p == nil {
e.encodeNull() e.encodeNull()
e.encodeByte(',') e.encodeByte(',')
@ -498,7 +500,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.next code = code.next
case opSliceHead: case opSliceHead:
p := load(ctxptr, code.idx) p := load(ctxptr, code.idx)
header := (*sliceHeader)(unsafe.Pointer(p)) header := *(**sliceHeader)(unsafe.Pointer(&p))
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(header.data) == 0 {
e.encodeNull() e.encodeNull()
e.encodeByte(',') e.encodeByte(',')
@ -540,7 +542,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
code = code.end.next code = code.end.next
} else { } else {
header := (*sliceHeader)(unsafe.Pointer(p)) header := *(**sliceHeader)(unsafe.Pointer(&p))
store(ctxptr, code.elemIdx, 0) store(ctxptr, code.elemIdx, 0)
store(ctxptr, code.length, uintptr(header.len)) store(ctxptr, code.length, uintptr(header.len))
store(ctxptr, code.idx, uintptr(header.data)) store(ctxptr, code.idx, uintptr(header.data))
@ -563,7 +565,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
code = code.end.next code = code.end.next
} else { } else {
header := (*sliceHeader)(unsafe.Pointer(p)) header := *(**sliceHeader)(unsafe.Pointer(&p))
store(ctxptr, code.elemIdx, 0) store(ctxptr, code.elemIdx, 0)
store(ctxptr, code.length, uintptr(header.len)) store(ctxptr, code.length, uintptr(header.len))
store(ctxptr, code.idx, uintptr(header.data)) store(ctxptr, code.idx, uintptr(header.data))
@ -688,10 +690,11 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeByte(',') e.encodeByte(',')
code = code.end.next code = code.end.next
} else { } else {
mlen := maplen(unsafe.Pointer(ptr)) uptr := *(*unsafe.Pointer)(unsafe.Pointer(&ptr))
mlen := maplen(uptr)
if mlen > 0 { if mlen > 0 {
e.encodeByte('{') e.encodeByte('{')
iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) iter := mapiterinit(code.typ, uptr)
ctx.keepRefs = append(ctx.keepRefs, iter) ctx.keepRefs = append(ctx.keepRefs, iter)
store(ctxptr, code.elemIdx, 0) store(ctxptr, code.elemIdx, 0)
store(ctxptr, code.length, uintptr(mlen)) store(ctxptr, code.length, uintptr(mlen))
@ -719,17 +722,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.end.next code = code.end.next
} else { } else {
// load pointer // 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 { if ptr == 0 {
e.encodeNull() e.encodeNull()
e.encodeByte(',') e.encodeByte(',')
code = code.end.next code = code.end.next
break break
} }
mlen := maplen(unsafe.Pointer(ptr)) mlen := maplen(uptr)
if mlen > 0 { if mlen > 0 {
e.encodeByte('{') e.encodeByte('{')
iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) iter := mapiterinit(code.typ, uptr)
ctx.keepRefs = append(ctx.keepRefs, iter) ctx.keepRefs = append(ctx.keepRefs, iter)
store(ctxptr, code.elemIdx, 0) store(ctxptr, code.elemIdx, 0)
store(ctxptr, code.length, uintptr(mlen)) store(ctxptr, code.length, uintptr(mlen))
@ -755,7 +759,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
idx++ idx++
if e.unorderedMap { if e.unorderedMap {
if idx < length { 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) store(ctxptr, code.elemIdx, idx)
key := mapiterkey(iter) key := mapiterkey(iter)
store(ctxptr, code.next.idx, uintptr(key)) store(ctxptr, code.next.idx, uintptr(key))
@ -767,10 +772,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.end.next code = code.end.next
} }
} else { } 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)) *posPtr = append(*posPtr, len(e.buf))
if idx < length { 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) store(ctxptr, code.elemIdx, idx)
key := mapiterkey(iter) key := mapiterkey(iter)
store(ctxptr, code.next.idx, uintptr(key)) 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 last := len(e.buf) - 1
e.buf[last] = ':' e.buf[last] = ':'
} else { } 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)) *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) value := mapitervalue(iter)
store(ctxptr, code.next.idx, uintptr(value)) store(ctxptr, code.next.idx, uintptr(value))
mapiternext(iter) mapiternext(iter)
@ -800,7 +809,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
value string value string
} }
kvs := make([]mapKV, 0, length) 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) pos := *(*[]int)(posPtr)
for i := 0; i < length; i++ { for i := 0; i < length; i++ {
startKey := pos[i*2] startKey := pos[i*2]
@ -839,10 +849,11 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
code = code.end.next code = code.end.next
} else { } else {
mlen := maplen(unsafe.Pointer(ptr)) uptr := *(*unsafe.Pointer)(unsafe.Pointer(&ptr))
mlen := maplen(uptr)
if mlen > 0 { if mlen > 0 {
e.encodeBytes([]byte{'{', '\n'}) e.encodeBytes([]byte{'{', '\n'})
iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) iter := mapiterinit(code.typ, uptr)
ctx.keepRefs = append(ctx.keepRefs, iter) ctx.keepRefs = append(ctx.keepRefs, iter)
store(ctxptr, code.elemIdx, 0) store(ctxptr, code.elemIdx, 0)
store(ctxptr, code.length, uintptr(mlen)) store(ctxptr, code.length, uintptr(mlen))
@ -875,18 +886,19 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.end.next code = code.end.next
} else { } else {
// load pointer // load pointer
ptr = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(ptr))) ptr = uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&ptr)))
if ptr == 0 { uptr := *(*unsafe.Pointer)(unsafe.Pointer(&ptr))
if uintptr(uptr) == 0 {
e.encodeIndent(code.indent) e.encodeIndent(code.indent)
e.encodeNull() e.encodeNull()
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
code = code.end.next code = code.end.next
break break
} }
mlen := maplen(unsafe.Pointer(ptr)) mlen := maplen(uptr)
if mlen > 0 { if mlen > 0 {
e.encodeBytes([]byte{'{', '\n'}) e.encodeBytes([]byte{'{', '\n'})
iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) iter := mapiterinit(code.typ, uptr)
ctx.keepRefs = append(ctx.keepRefs, iter) ctx.keepRefs = append(ctx.keepRefs, iter)
store(ctxptr, code.elemIdx, 0) store(ctxptr, code.elemIdx, 0)
store(ctxptr, code.length, uintptr(mlen)) store(ctxptr, code.length, uintptr(mlen))
@ -919,7 +931,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
if idx < length { if idx < length {
e.encodeIndent(code.indent) e.encodeIndent(code.indent)
store(ctxptr, code.elemIdx, idx) 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) key := mapiterkey(iter)
store(ctxptr, code.next.idx, uintptr(key)) store(ctxptr, code.next.idx, uintptr(key))
code = code.next code = code.next
@ -931,10 +944,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.end.next code = code.end.next
} }
} else { } 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)) *posPtr = append(*posPtr, len(e.buf))
if idx < length { 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) store(ctxptr, code.elemIdx, idx)
key := mapiterkey(iter) key := mapiterkey(iter)
store(ctxptr, code.next.idx, uintptr(key)) store(ctxptr, code.next.idx, uintptr(key))
@ -947,10 +962,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
if e.unorderedMap { if e.unorderedMap {
e.encodeBytes([]byte{':', ' '}) e.encodeBytes([]byte{':', ' '})
} else { } 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)) *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) value := mapitervalue(iter)
store(ctxptr, code.next.idx, uintptr(value)) store(ctxptr, code.next.idx, uintptr(value))
mapiternext(iter) mapiternext(iter)
@ -963,7 +980,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
value string value string
} }
kvs := make([]mapKV, 0, length) 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++ { for i := 0; i < length; i++ {
startKey := pos[i*2] startKey := pos[i*2]
startValue := pos[i*2+1] startValue := pos[i*2+1]
@ -1053,7 +1071,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
// restore ctxptr // restore ctxptr
offset := load(ctxptr, code.idx) 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 ctxptr = ctx.ptr() + offset
ptrOffset = offset ptrOffset = offset
case opStructFieldPtrHead: case opStructFieldPtrHead:
@ -1807,9 +1826,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
} else { } else {
e.encodeByte('{') e.encodeByte('{')
e.encodeKey(code) e.encodeKey(code)
ptr += code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(ptr + code.offset), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)),
})) }))
rv := reflect.ValueOf(v) rv := reflect.ValueOf(v)
if rv.Type().Kind() == reflect.Interface && rv.IsNil() { 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 code = code.end.next
} else { } else {
e.encodeKey(code) e.encodeKey(code)
ptr += code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(ptr + code.offset), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)),
})) }))
rv := reflect.ValueOf(v) rv := reflect.ValueOf(v)
if rv.Type().Kind() == reflect.Interface && rv.IsNil() { if rv.Type().Kind() == reflect.Interface && rv.IsNil() {
@ -1897,9 +1918,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
} else { } else {
e.encodeByte('{') e.encodeByte('{')
e.encodeKey(code) e.encodeKey(code)
ptr += code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(ptr + code.offset), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)),
})) }))
rv := reflect.ValueOf(v) rv := reflect.ValueOf(v)
if rv.Type().Kind() == reflect.Interface && rv.IsNil() { 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 code = code.end.next
} else { } else {
e.encodeKey(code) e.encodeKey(code)
ptr += code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(ptr + code.offset), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)),
})) }))
rv := reflect.ValueOf(v) rv := reflect.ValueOf(v)
if rv.Type().Kind() == reflect.Interface && rv.IsNil() { if rv.Type().Kind() == reflect.Interface && rv.IsNil() {
@ -2304,7 +2327,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
} else { } else {
e.encodeByte('{') e.encodeByte('{')
p := ptr + code.offset 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 code = code.nextField
} else { } else {
e.encodeKey(code) e.encodeKey(code)
@ -2324,7 +2347,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.end.next code = code.end.next
} else { } else {
p := ptr + code.offset 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 code = code.nextField
} else { } else {
e.encodeKey(code) e.encodeKey(code)
@ -3033,7 +3056,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.end.next code = code.end.next
} else { } else {
e.encodeByte('{') e.encodeByte('{')
p := unsafe.Pointer(ptr + code.offset) ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr))
isPtr := code.typ.Kind() == reflect.Ptr isPtr := code.typ.Kind() == reflect.Ptr
if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) { if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) {
code = code.nextField code = code.nextField
@ -3077,7 +3101,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
if ptr == 0 { if ptr == 0 {
code = code.end.next code = code.end.next
} else { } else {
p := unsafe.Pointer(ptr + code.offset) ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr))
isPtr := code.typ.Kind() == reflect.Ptr isPtr := code.typ.Kind() == reflect.Ptr
if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) { if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) {
code = code.nextField code = code.nextField
@ -3124,7 +3149,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.end.next code = code.end.next
} else { } else {
e.encodeByte('{') e.encodeByte('{')
p := unsafe.Pointer(ptr + code.offset) ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr))
isPtr := code.typ.Kind() == reflect.Ptr isPtr := code.typ.Kind() == reflect.Ptr
if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) { if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) {
code = code.nextField code = code.nextField
@ -3154,7 +3180,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
if ptr == 0 { if ptr == 0 {
code = code.end.next code = code.end.next
} else { } else {
p := unsafe.Pointer(ptr + code.offset) ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr))
isPtr := code.typ.Kind() == reflect.Ptr isPtr := code.typ.Kind() == reflect.Ptr
if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) { if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) {
code = code.nextField code = code.nextField
@ -3190,7 +3217,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeIndent(code.indent) e.encodeIndent(code.indent)
e.encodeBytes([]byte{'{', '\n'}) e.encodeBytes([]byte{'{', '\n'})
p := ptr + code.offset 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 code = code.nextField
} else { } else {
e.encodeIndent(code.indent + 1) e.encodeIndent(code.indent + 1)
@ -4225,7 +4252,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.end.next code = code.end.next
} else { } else {
e.encodeByte('{') e.encodeByte('{')
p := unsafe.Pointer(ptr + code.offset) ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr))
isPtr := code.typ.Kind() == reflect.Ptr isPtr := code.typ.Kind() == reflect.Ptr
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p}))
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
@ -4267,7 +4295,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
if ptr == 0 { if ptr == 0 {
code = code.end.next code = code.end.next
} else { } else {
p := unsafe.Pointer(ptr + code.offset) ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr))
isPtr := code.typ.Kind() == reflect.Ptr isPtr := code.typ.Kind() == reflect.Ptr
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p}))
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
@ -4313,7 +4342,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.end.next code = code.end.next
} else { } else {
e.encodeByte('{') 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})) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p}))
bytes, err := v.(encoding.TextMarshaler).MarshalText() bytes, err := v.(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
@ -4338,7 +4368,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
if ptr == 0 { if ptr == 0 {
code = code.end.next code = code.end.next
} else { } 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})) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p}))
bytes, err := v.(encoding.TextMarshaler).MarshalText() bytes, err := v.(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
@ -4997,7 +5028,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
if err != nil { if err != nil {
@ -5019,7 +5050,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
bytes, err := v.(encoding.TextMarshaler).MarshalText() bytes, err := v.(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
@ -5207,7 +5238,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
if err != nil { if err != nil {
@ -5229,7 +5260,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeByte(' ') e.encodeByte(' ')
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptr + code.offset p := ptr + code.offset
header := (*sliceHeader)(unsafe.Pointer(p)) header := *(**sliceHeader)(unsafe.Pointer(&p))
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(header.data) == 0 {
e.encodeNull() e.encodeNull()
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
@ -5243,7 +5274,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeByte(' ') e.encodeByte(' ')
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptr + code.offset p := ptr + code.offset
header := (*sliceHeader)(unsafe.Pointer(p)) header := *(**sliceHeader)(unsafe.Pointer(&p))
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(header.data) == 0 {
e.encodeNull() e.encodeNull()
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
@ -5261,7 +5292,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeNull() e.encodeNull()
code = code.nextField code = code.nextField
} else { } else {
mlen := maplen(unsafe.Pointer(p)) p = uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
mlen := maplen(*(*unsafe.Pointer)(unsafe.Pointer(&p)))
if mlen == 0 { if mlen == 0 {
e.encodeBytes([]byte{'{', '}', ',', '\n'}) e.encodeBytes([]byte{'{', '}', ',', '\n'})
mapCode := code.next mapCode := code.next
@ -5280,8 +5312,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeNull() e.encodeNull()
code = code.nextField code = code.nextField
} else { } else {
p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p))) p = uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
mlen := maplen(unsafe.Pointer(p)) mlen := maplen(*(*unsafe.Pointer)(unsafe.Pointer(&p)))
if mlen == 0 { if mlen == 0 {
e.encodeBytes([]byte{'{', '}', ',', '\n'}) e.encodeBytes([]byte{'{', '}', ',', '\n'})
code = code.nextField code = code.nextField
@ -5312,7 +5344,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
case opStructFieldOmitEmpty: case opStructFieldOmitEmpty:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptr + code.offset p := ptr + code.offset
if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { if p == 0 || **(**uintptr)(unsafe.Pointer(&p)) == 0 {
code = code.nextField code = code.nextField
} else { } else {
e.encodeKey(code) e.encodeKey(code)
@ -5465,7 +5497,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
if v != nil { if v != nil {
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
@ -5488,12 +5520,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
if v != nil { if v != nil {
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
bytes, err := v.(encoding.TextMarshaler).MarshalText() bytes, err := v.(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
@ -5509,7 +5541,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
case opStructFieldOmitEmptyArray: case opStructFieldOmitEmptyArray:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptr + code.offset p := ptr + code.offset
header := (*sliceHeader)(unsafe.Pointer(p)) header := *(**sliceHeader)(unsafe.Pointer(&p))
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(header.data) == 0 {
code = code.nextField code = code.nextField
} else { } else {
@ -5518,7 +5550,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
case opStructFieldOmitEmptySlice: case opStructFieldOmitEmptySlice:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptr + code.offset p := ptr + code.offset
header := (*sliceHeader)(unsafe.Pointer(p)) header := *(**sliceHeader)(unsafe.Pointer(&p))
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(header.data) == 0 {
code = code.nextField code = code.nextField
} else { } else {
@ -5530,7 +5562,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
if p == 0 { if p == 0 {
code = code.nextField code = code.nextField
} else { } else {
mlen := maplen(unsafe.Pointer(p)) mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
if mlen == 0 { if mlen == 0 {
code = code.nextField code = code.nextField
} else { } else {
@ -5543,8 +5575,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
if p == 0 { if p == 0 {
code = code.nextField code = code.nextField
} else { } else {
p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p))) mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
mlen := maplen(unsafe.Pointer(p))
if mlen == 0 { if mlen == 0 {
code = code.nextField code = code.nextField
} else { } else {
@ -5554,7 +5585,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
case opStructFieldOmitEmptyIndent: case opStructFieldOmitEmptyIndent:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptr + code.offset p := ptr + code.offset
if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { if p == 0 || **(**uintptr)(unsafe.Pointer(&p)) == 0 {
code = code.nextField code = code.nextField
} else { } else {
e.encodeIndent(code.indent) e.encodeIndent(code.indent)
@ -5740,7 +5771,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
case opStructFieldOmitEmptyArrayIndent: case opStructFieldOmitEmptyArrayIndent:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptr + code.offset p := ptr + code.offset
header := (*sliceHeader)(unsafe.Pointer(p)) header := *(**sliceHeader)(unsafe.Pointer(&p))
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(header.data) == 0 {
code = code.nextField code = code.nextField
} else { } else {
@ -5752,7 +5783,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
case opStructFieldOmitEmptySliceIndent: case opStructFieldOmitEmptySliceIndent:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptr + code.offset p := ptr + code.offset
header := (*sliceHeader)(unsafe.Pointer(p)) header := *(**sliceHeader)(unsafe.Pointer(&p))
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(header.data) == 0 {
code = code.nextField code = code.nextField
} else { } else {
@ -5767,7 +5798,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
if p == 0 { if p == 0 {
code = code.nextField code = code.nextField
} else { } else {
mlen := maplen(unsafe.Pointer(p)) mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
if mlen == 0 { if mlen == 0 {
code = code.nextField code = code.nextField
} else { } else {
@ -5783,8 +5814,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
if p == 0 { if p == 0 {
code = code.nextField code = code.nextField
} else { } else {
p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p))) mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
mlen := maplen(unsafe.Pointer(p))
if mlen == 0 { if mlen == 0 {
code = code.nextField code = code.nextField
} else { } else {
@ -5924,7 +5954,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
if err != nil { if err != nil {
@ -5945,7 +5975,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
bytes, err := v.(encoding.TextMarshaler).MarshalText() bytes, err := v.(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
@ -6109,7 +6139,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
if err != nil { if err != nil {
@ -6133,7 +6163,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ, typ: code.typ,
ptr: unsafe.Pointer(p), ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
})) }))
bytes, err := v.(encoding.TextMarshaler).MarshalText() bytes, err := v.(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
@ -6175,20 +6205,20 @@ END:
return nil return nil
} }
func (e *Encoder) ptrToPtr(p uintptr) uintptr { return *(*uintptr)(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) ptrToInt(p uintptr) int { return **(**int)(unsafe.Pointer(&p)) }
func (e *Encoder) ptrToInt8(p uintptr) int8 { return *(*int8)(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) ptrToInt16(p uintptr) int16 { return **(**int16)(unsafe.Pointer(&p)) }
func (e *Encoder) ptrToInt32(p uintptr) int32 { return *(*int32)(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) ptrToInt64(p uintptr) int64 { return **(**int64)(unsafe.Pointer(&p)) }
func (e *Encoder) ptrToUint(p uintptr) uint { return *(*uint)(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) ptrToUint8(p uintptr) uint8 { return **(**uint8)(unsafe.Pointer(&p)) }
func (e *Encoder) ptrToUint16(p uintptr) uint16 { return *(*uint16)(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) ptrToUint32(p uintptr) uint32 { return **(**uint32)(unsafe.Pointer(&p)) }
func (e *Encoder) ptrToUint64(p uintptr) uint64 { return *(*uint64)(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) ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) }
func (e *Encoder) ptrToFloat64(p uintptr) float64 { return *(*float64)(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) ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) }
func (e *Encoder) ptrToByte(p uintptr) byte { return *(*byte)(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) ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) }
func (e *Encoder) ptrToString(p uintptr) string { return *(*string)(unsafe.Pointer(p)) } func (e *Encoder) ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) }