Refactor cast manipulation from uintptr

This commit is contained in:
Masaaki Goshima 2020-11-17 15:09:06 +09:00
parent c79cf6a3f5
commit ea96cc7811
1 changed files with 119 additions and 187 deletions

View File

@ -185,8 +185,8 @@ 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)) slice := e.ptrToSlice(ptr)
if ptr == 0 || uintptr(header.data) == 0 { if ptr == 0 || uintptr(slice.data) == 0 {
e.encodeNull() e.encodeNull()
} else { } else {
e.encodeByteSlice(e.ptrToBytes(ptr)) e.encodeByteSlice(e.ptrToBytes(ptr))
@ -195,8 +195,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.next code = code.next
case opBytesIndent: case opBytesIndent:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
header := (*sliceHeader)(unsafe.Pointer(&ptr)) slice := e.ptrToSlice(ptr)
if ptr == 0 || uintptr(header.data) == 0 { if ptr == 0 || uintptr(slice.data) == 0 {
e.encodeNull() e.encodeNull()
} else { } else {
e.encodeByteSlice(e.ptrToBytes(ptr)) e.encodeByteSlice(e.ptrToBytes(ptr))
@ -211,17 +211,11 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.next code = code.next
break break
} }
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)),
}))
if _, exists := seenPtr[ptr]; exists { if _, exists := seenPtr[ptr]; exists {
return &UnsupportedValueError{ return errUnsupportedValue(code, ptr)
Value: reflect.ValueOf(v),
Str: fmt.Sprintf("encountered a cycle via %s", code.typ),
}
} }
seenPtr[ptr] = struct{}{} seenPtr[ptr] = struct{}{}
v := e.ptrToInterface(code, ptr)
rv := reflect.ValueOf(v) rv := reflect.ValueOf(v)
if rv.IsNil() { if rv.IsNil() {
e.encodeNull() e.encodeNull()
@ -293,17 +287,11 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.next code = code.next
break break
} }
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)),
}))
if _, exists := seenPtr[ptr]; exists { if _, exists := seenPtr[ptr]; exists {
return &UnsupportedValueError{ return errUnsupportedValue(code, ptr)
Value: reflect.ValueOf(v),
Str: fmt.Sprintf("encountered a cycle via %s", code.typ),
}
} }
seenPtr[ptr] = struct{}{} seenPtr[ptr] = struct{}{}
v := e.ptrToInterface(code, ptr)
rv := reflect.ValueOf(v) rv := reflect.ValueOf(v)
if rv.IsNil() { if rv.IsNil() {
e.encodeNull() e.encodeNull()
@ -376,10 +364,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.next code = code.next
case opMarshalJSON: case opMarshalJSON:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, ptr)
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)),
}))
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
if err != nil { if err != nil {
return errMarshaler(code, err) return errMarshaler(code, err)
@ -391,29 +376,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
) )
} }
var buf bytes.Buffer var buf bytes.Buffer
if e.enabledIndent { if err := compact(&buf, b, e.enabledHTMLEscape); err != nil {
if err := encodeWithIndent( return err
&buf,
b,
string(e.prefix)+string(bytes.Repeat(e.indentStr, code.indent)),
string(e.indentStr),
); err != nil {
return err
}
} else {
if err := compact(&buf, b, e.enabledHTMLEscape); err != nil {
return err
}
} }
e.encodeBytes(buf.Bytes()) e.encodeBytes(buf.Bytes())
e.encodeByte(',') e.encodeByte(',')
code = code.next code = code.next
case opMarshalJSONIndent: case opMarshalJSONIndent:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, ptr)
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)),
}))
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
if err != nil { if err != nil {
return errMarshaler(code, err) return errMarshaler(code, err)
@ -425,19 +396,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
) )
} }
var buf bytes.Buffer var buf bytes.Buffer
if e.enabledIndent { if err := encodeWithIndent(
if err := encodeWithIndent( &buf,
&buf, b,
b, string(e.prefix)+string(bytes.Repeat(e.indentStr, code.indent)),
string(e.prefix)+string(bytes.Repeat(e.indentStr, code.indent)), string(e.indentStr),
string(e.indentStr), ); err != nil {
); err != nil { return err
return err
}
} else {
if err := compact(&buf, b, e.enabledHTMLEscape); err != nil {
return err
}
} }
e.encodeBytes(buf.Bytes()) e.encodeBytes(buf.Bytes())
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
@ -445,13 +410,12 @@ 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)(unsafe.Pointer(&ptr)) p := e.ptrToUnsafePtr(ptr)
if p == nil { if p == nil {
e.encodeNull() e.encodeNull()
e.encodeByte(',') e.encodeByte(',')
} else if isPtr && *(*unsafe.Pointer)(p) == nil { } else if isPtr && *(*unsafe.Pointer)(p) == nil {
e.encodeBytes([]byte{'"', '"'}) e.encodeBytes([]byte{'"', '"', ','})
e.encodeByte(',')
} else { } else {
if isPtr && code.typ.Elem().Implements(marshalTextType) { if isPtr && code.typ.Elem().Implements(marshalTextType) {
p = *(*unsafe.Pointer)(p) p = *(*unsafe.Pointer)(p)
@ -471,13 +435,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
case opMarshalTextIndent: case opMarshalTextIndent:
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)(unsafe.Pointer(&ptr)) p := e.ptrToUnsafePtr(ptr)
if p == nil { if p == nil {
e.encodeNull() e.encodeNull()
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
} else if isPtr && *(*unsafe.Pointer)(p) == nil { } else if isPtr && *(*unsafe.Pointer)(p) == nil {
e.encodeBytes([]byte{'"', '"'}) e.encodeBytes([]byte{'"', '"', ',', '\n'})
e.encodeBytes([]byte{',', '\n'})
} else { } else {
if isPtr && code.typ.Elem().Implements(marshalTextType) { if isPtr && code.typ.Elem().Implements(marshalTextType) {
p = *(*unsafe.Pointer)(p) p = *(*unsafe.Pointer)(p)
@ -496,19 +459,19 @@ 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)) slice := e.ptrToSlice(p)
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(slice.data) == 0 {
e.encodeNull() e.encodeNull()
e.encodeByte(',') e.encodeByte(',')
code = code.end.next code = code.end.next
} else { } else {
store(ctxptr, code.elemIdx, 0) store(ctxptr, code.elemIdx, 0)
store(ctxptr, code.length, uintptr(header.len)) store(ctxptr, code.length, uintptr(slice.len))
store(ctxptr, code.idx, uintptr(header.data)) store(ctxptr, code.idx, uintptr(slice.data))
if header.len > 0 { if slice.len > 0 {
e.encodeByte('[') e.encodeByte('[')
code = code.next code = code.next
store(ctxptr, code.idx, uintptr(header.data)) store(ctxptr, code.idx, uintptr(slice.data))
} else { } else {
e.encodeBytes([]byte{'[', ']', ','}) e.encodeBytes([]byte{'[', ']', ','})
code = code.end.next code = code.end.next
@ -538,15 +501,15 @@ 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)) slice := e.ptrToSlice(p)
store(ctxptr, code.elemIdx, 0) store(ctxptr, code.elemIdx, 0)
store(ctxptr, code.length, uintptr(header.len)) store(ctxptr, code.length, uintptr(slice.len))
store(ctxptr, code.idx, uintptr(header.data)) store(ctxptr, code.idx, uintptr(slice.data))
if header.len > 0 { if slice.len > 0 {
e.encodeBytes([]byte{'[', '\n'}) e.encodeBytes([]byte{'[', '\n'})
e.encodeIndent(code.indent + 1) e.encodeIndent(code.indent + 1)
code = code.next code = code.next
store(ctxptr, code.idx, uintptr(header.data)) store(ctxptr, code.idx, uintptr(slice.data))
} else { } else {
e.encodeIndent(code.indent) e.encodeIndent(code.indent)
e.encodeBytes([]byte{'[', ']', '\n'}) e.encodeBytes([]byte{'[', ']', '\n'})
@ -561,15 +524,15 @@ 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)) slice := e.ptrToSlice(p)
store(ctxptr, code.elemIdx, 0) store(ctxptr, code.elemIdx, 0)
store(ctxptr, code.length, uintptr(header.len)) store(ctxptr, code.length, uintptr(slice.len))
store(ctxptr, code.idx, uintptr(header.data)) store(ctxptr, code.idx, uintptr(slice.data))
if header.len > 0 { if slice.len > 0 {
e.encodeBytes([]byte{'[', '\n'}) e.encodeBytes([]byte{'[', '\n'})
e.encodeIndent(code.indent + 1) e.encodeIndent(code.indent + 1)
code = code.next code = code.next
store(ctxptr, code.idx, uintptr(header.data)) store(ctxptr, code.idx, uintptr(slice.data))
} else { } else {
e.encodeIndent(code.indent) e.encodeIndent(code.indent)
e.encodeBytes([]byte{'[', ']', ',', '\n'}) e.encodeBytes([]byte{'[', ']', ',', '\n'})
@ -686,7 +649,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeByte(',') e.encodeByte(',')
code = code.end.next code = code.end.next
} else { } else {
uptr := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) uptr := e.ptrToUnsafePtr(ptr)
mlen := maplen(uptr) mlen := maplen(uptr)
if mlen > 0 { if mlen > 0 {
e.encodeByte('{') e.encodeByte('{')
@ -718,8 +681,8 @@ 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 = e.ptrToPtr(ptr)
uptr := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) uptr := e.ptrToUnsafePtr(ptr)
if ptr == 0 { if ptr == 0 {
e.encodeNull() e.encodeNull()
e.encodeByte(',') e.encodeByte(',')
@ -756,7 +719,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
if e.unorderedMap { if e.unorderedMap {
if idx < length { if idx < length {
ptr := load(ctxptr, code.mapIter) ptr := load(ctxptr, code.mapIter)
iter := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) iter := e.ptrToUnsafePtr(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))
@ -773,7 +736,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
*posPtr = append(*posPtr, len(e.buf)) *posPtr = append(*posPtr, len(e.buf))
if idx < length { if idx < length {
ptr := load(ctxptr, code.mapIter) ptr := load(ctxptr, code.mapIter)
iter := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) iter := e.ptrToUnsafePtr(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))
@ -792,7 +755,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
*posPtr = append(*posPtr, len(e.buf)) *posPtr = append(*posPtr, len(e.buf))
} }
ptr := load(ctxptr, code.mapIter) ptr := load(ctxptr, code.mapIter)
iter := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) iter := e.ptrToUnsafePtr(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)
@ -806,7 +769,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
} }
kvs := make([]mapKV, 0, length) kvs := make([]mapKV, 0, length)
ptr := load(ctxptr, code.mapPos) ptr := load(ctxptr, code.mapPos)
posPtr := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) posPtr := e.ptrToUnsafePtr(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]
@ -845,7 +808,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 {
uptr := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) uptr := e.ptrToUnsafePtr(ptr)
mlen := maplen(uptr) mlen := maplen(uptr)
if mlen > 0 { if mlen > 0 {
e.encodeBytes([]byte{'{', '\n'}) e.encodeBytes([]byte{'{', '\n'})
@ -882,8 +845,8 @@ 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 = e.ptrToPtr(ptr)
uptr := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) uptr := e.ptrToUnsafePtr(ptr)
if uintptr(uptr) == 0 { if uintptr(uptr) == 0 {
e.encodeIndent(code.indent) e.encodeIndent(code.indent)
e.encodeNull() e.encodeNull()
@ -928,7 +891,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeIndent(code.indent) e.encodeIndent(code.indent)
store(ctxptr, code.elemIdx, idx) store(ctxptr, code.elemIdx, idx)
ptr := load(ctxptr, code.mapIter) ptr := load(ctxptr, code.mapIter)
iter := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) iter := e.ptrToUnsafePtr(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
@ -945,7 +908,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
*posPtr = append(*posPtr, len(e.buf)) *posPtr = append(*posPtr, len(e.buf))
if idx < length { if idx < length {
ptr := load(ctxptr, code.mapIter) ptr := load(ctxptr, code.mapIter)
iter := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) iter := e.ptrToUnsafePtr(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))
@ -963,7 +926,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
*posPtr = append(*posPtr, len(e.buf)) *posPtr = append(*posPtr, len(e.buf))
} }
ptr := load(ctxptr, code.mapIter) ptr := load(ctxptr, code.mapIter)
iter := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) iter := e.ptrToUnsafePtr(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)
@ -1068,7 +1031,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
// restore ctxptr // restore ctxptr
offset := load(ctxptr, code.idx) offset := load(ctxptr, code.idx)
ptr := load(ctxptr, code.elemIdx) ptr := load(ctxptr, code.elemIdx)
code = (*opcode)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr))) code = (*opcode)(e.ptrToUnsafePtr(ptr))
ctxptr = ctx.ptr() + offset ctxptr = ctx.ptr() + offset
ptrOffset = offset ptrOffset = offset
case opStructFieldPtrHead: case opStructFieldPtrHead:
@ -1823,10 +1786,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeByte('{') e.encodeByte('{')
e.encodeKey(code) e.encodeKey(code)
ptr += code.offset ptr += code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, ptr)
typ: code.typ,
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() {
e.encodeNull() e.encodeNull()
@ -1861,10 +1821,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
} else { } else {
e.encodeKey(code) e.encodeKey(code)
ptr += code.offset ptr += code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, ptr)
typ: code.typ,
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() {
e.encodeNull() e.encodeNull()
@ -1909,10 +1866,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeByte('{') e.encodeByte('{')
e.encodeKey(code) e.encodeKey(code)
ptr += code.offset ptr += code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, ptr)
typ: code.typ,
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() {
e.encodeNull() e.encodeNull()
@ -1938,10 +1892,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
} else { } else {
e.encodeKey(code) e.encodeKey(code)
ptr += code.offset ptr += code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, ptr)
typ: code.typ,
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() {
e.encodeNull() e.encodeNull()
@ -3041,7 +2992,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
} else { } else {
e.encodeByte('{') e.encodeByte('{')
ptr += code.offset ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) p := e.ptrToUnsafePtr(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
@ -3086,7 +3037,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.end.next code = code.end.next
} else { } else {
ptr += code.offset ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) p := e.ptrToUnsafePtr(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
@ -3134,7 +3085,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
} else { } else {
e.encodeByte('{') e.encodeByte('{')
ptr += code.offset ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) p := e.ptrToUnsafePtr(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
@ -3165,7 +3116,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.end.next code = code.end.next
} else { } else {
ptr += code.offset ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) p := e.ptrToUnsafePtr(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
@ -4237,7 +4188,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
} else { } else {
e.encodeByte('{') e.encodeByte('{')
ptr += code.offset ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) p := e.ptrToUnsafePtr(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()
@ -4280,7 +4231,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.end.next code = code.end.next
} else { } else {
ptr += code.offset ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) p := e.ptrToUnsafePtr(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()
@ -4327,7 +4278,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
} else { } else {
e.encodeByte('{') e.encodeByte('{')
ptr += code.offset ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) p := e.ptrToUnsafePtr(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 {
@ -4353,7 +4304,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.end.next code = code.end.next
} else { } else {
ptr += code.offset ptr += code.offset
p := *(*unsafe.Pointer)(unsafe.Pointer(&ptr)) p := e.ptrToUnsafePtr(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 {
@ -5007,10 +4958,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
e.encodeKey(code) e.encodeKey(code)
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, p)
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
}))
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
if err != nil { if err != nil {
return errMarshaler(code, err) return errMarshaler(code, err)
@ -5026,10 +4974,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
e.encodeKey(code) e.encodeKey(code)
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, p)
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
}))
bytes, err := v.(encoding.TextMarshaler).MarshalText() bytes, err := v.(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
return errMarshaler(code, err) return errMarshaler(code, err)
@ -5211,10 +5156,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
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, p)
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
}))
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
if err != nil { if err != nil {
return errMarshaler(code, err) return errMarshaler(code, err)
@ -5232,8 +5174,8 @@ 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)) array := e.ptrToSlice(p)
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(array.data) == 0 {
e.encodeNull() e.encodeNull()
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
code = code.nextField code = code.nextField
@ -5246,8 +5188,8 @@ 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)) slice := e.ptrToSlice(p)
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(slice.data) == 0 {
e.encodeNull() e.encodeNull()
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
code = code.nextField code = code.nextField
@ -5264,8 +5206,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 = e.ptrToPtr(p)
mlen := maplen(*(*unsafe.Pointer)(unsafe.Pointer(&p))) mlen := maplen(e.ptrToUnsafePtr(p))
if mlen == 0 { if mlen == 0 {
e.encodeBytes([]byte{'{', '}', ',', '\n'}) e.encodeBytes([]byte{'{', '}', ',', '\n'})
mapCode := code.next mapCode := code.next
@ -5284,8 +5226,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 = e.ptrToPtr(p)
mlen := maplen(*(*unsafe.Pointer)(unsafe.Pointer(&p))) mlen := maplen(e.ptrToUnsafePtr(p))
if mlen == 0 { if mlen == 0 {
e.encodeBytes([]byte{'{', '}', ',', '\n'}) e.encodeBytes([]byte{'{', '}', ',', '\n'})
code = code.nextField code = code.nextField
@ -5467,10 +5409,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
case opStructFieldOmitEmptyMarshalJSON: case opStructFieldOmitEmptyMarshalJSON:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, p)
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
}))
if v != nil { if v != nil {
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
if err != nil { if err != nil {
@ -5487,15 +5426,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
case opStructFieldOmitEmptyMarshalText: case opStructFieldOmitEmptyMarshalText:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, p)
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
}))
if v != nil { if v != nil {
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
}))
bytes, err := v.(encoding.TextMarshaler).MarshalText() bytes, err := v.(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
return errMarshaler(code, err) return errMarshaler(code, err)
@ -5507,8 +5439,8 @@ 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)) array := e.ptrToSlice(p)
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(array.data) == 0 {
code = code.nextField code = code.nextField
} else { } else {
code = code.next code = code.next
@ -5516,8 +5448,8 @@ 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)) slice := e.ptrToSlice(p)
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(slice.data) == 0 {
code = code.nextField code = code.nextField
} else { } else {
code = code.next code = code.next
@ -5737,8 +5669,8 @@ 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)) array := e.ptrToSlice(p)
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(array.data) == 0 {
code = code.nextField code = code.nextField
} else { } else {
e.encodeIndent(code.indent) e.encodeIndent(code.indent)
@ -5749,8 +5681,8 @@ 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)) slice := e.ptrToSlice(p)
if p == 0 || uintptr(header.data) == 0 { if p == 0 || uintptr(slice.data) == 0 {
code = code.nextField code = code.nextField
} else { } else {
e.encodeIndent(code.indent) e.encodeIndent(code.indent)
@ -5918,10 +5850,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
case opStructFieldStringTagMarshalJSON: case opStructFieldStringTagMarshalJSON:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, p)
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
}))
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
if err != nil { if err != nil {
return errMarshaler(code, err) return errMarshaler(code, err)
@ -5936,10 +5865,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
case opStructFieldStringTagMarshalText: case opStructFieldStringTagMarshalText:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, p)
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
}))
bytes, err := v.(encoding.TextMarshaler).MarshalText() bytes, err := v.(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
return errMarshaler(code, err) return errMarshaler(code, err)
@ -6097,10 +6023,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeKey(code) e.encodeKey(code)
e.encodeByte(' ') e.encodeByte(' ')
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, p)
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
}))
b, err := v.(Marshaler).MarshalJSON() b, err := v.(Marshaler).MarshalJSON()
if err != nil { if err != nil {
return errMarshaler(code, err) return errMarshaler(code, err)
@ -6118,10 +6041,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeKey(code) e.encodeKey(code)
e.encodeByte(' ') e.encodeByte(' ')
p := ptr + code.offset p := ptr + code.offset
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ v := e.ptrToInterface(code, p)
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
}))
bytes, err := v.(encoding.TextMarshaler).MarshalText() bytes, err := v.(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
return errMarshaler(code, err) return errMarshaler(code, err)
@ -6159,20 +6079,32 @@ END:
return nil 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) 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)) } func (e *Encoder) ptrToSlice(p uintptr) *sliceHeader { return *(**sliceHeader)(unsafe.Pointer(&p)) }
func (e *Encoder) ptrToPtr(p uintptr) uintptr {
return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
}
func (e *Encoder) ptrToUnsafePtr(p uintptr) unsafe.Pointer {
return *(*unsafe.Pointer)(unsafe.Pointer(&p))
}
func (e *Encoder) ptrToInterface(code *opcode, p uintptr) interface{} {
return *(*interface{})(unsafe.Pointer(&interfaceHeader{
typ: code.typ,
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
}))
}