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