From 69ea157270dd33a64c77ca04af3a3946050932bf Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Tue, 17 Nov 2020 15:06:05 +0900 Subject: [PATCH 1/4] Refactor unsupported value for float64 --- encode_vm.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/encode_vm.go b/encode_vm.go index d71e032..1b043c5 100644 --- a/encode_vm.go +++ b/encode_vm.go @@ -35,6 +35,12 @@ func errUnsupportedValue(code *opcode, ptr uintptr) *UnsupportedValueError { } } +func errUnsupportedFloat(v float64) *UnsupportedValueError { + return &UnsupportedValueError{ + Value: reflect.ValueOf(v), + Str: strconv.FormatFloat(v, 'g', -1, 64), + } +} func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { recursiveLevel := 0 seenPtr := map[uintptr]struct{}{} @@ -140,10 +146,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { case opFloat64: v := e.ptrToFloat64(load(ctxptr, code.idx)) if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeFloat64(v) e.encodeByte(',') @@ -151,10 +154,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { case opFloat64Indent: v := e.ptrToFloat64(load(ctxptr, code.idx)) if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeFloat64(v) e.encodeBytes([]byte{',', '\n'}) From c79cf6a3f55373e41d911be85af1f76bc27830a2 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Tue, 17 Nov 2020 15:08:12 +0900 Subject: [PATCH 2/4] Refactor error of marshaler --- encode_vm.go | 98 ++++++++++++++-------------------------------------- 1 file changed, 26 insertions(+), 72 deletions(-) diff --git a/encode_vm.go b/encode_vm.go index 1b043c5..ddb7ca8 100644 --- a/encode_vm.go +++ b/encode_vm.go @@ -41,6 +41,14 @@ func errUnsupportedFloat(v float64) *UnsupportedValueError { Str: strconv.FormatFloat(v, 'g', -1, 64), } } + +func errMarshaler(code *opcode, err error) *MarshalerError { + return &MarshalerError{ + Type: rtype2type(code.typ), + Err: err, + } +} + func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { recursiveLevel := 0 seenPtr := map[uintptr]struct{}{} @@ -374,10 +382,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { })) b, err := v.(Marshaler).MarshalJSON() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } if len(b) == 0 { return errUnexpectedEndOfJSON( @@ -411,10 +416,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { })) b, err := v.(Marshaler).MarshalJSON() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } if len(b) == 0 { return errUnexpectedEndOfJSON( @@ -460,10 +462,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) e.encodeByte(',') @@ -489,10 +488,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) e.encodeBytes([]byte{',', '\n'}) @@ -1839,10 +1835,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } b, err := rv.Interface().(Marshaler).MarshalJSON() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } if len(b) == 0 { return errUnexpectedEndOfJSON( @@ -1880,10 +1873,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } b, err := rv.Interface().(Marshaler).MarshalJSON() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } if len(b) == 0 { return errUnexpectedEndOfJSON( @@ -1932,10 +1922,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } bytes, err := rv.Interface().(encoding.TextMarshaler).MarshalText() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) e.encodeByte(',') @@ -1964,10 +1951,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } bytes, err := rv.Interface().(encoding.TextMarshaler).MarshalText() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) e.encodeByte(',') @@ -4373,10 +4357,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } e.encodeKey(code) e.encodeString(*(*string)(unsafe.Pointer(&bytes))) @@ -5032,10 +5013,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { })) b, err := v.(Marshaler).MarshalJSON() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } var buf bytes.Buffer if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { @@ -5054,10 +5032,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) e.encodeByte(',') @@ -5242,10 +5217,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { })) b, err := v.(Marshaler).MarshalJSON() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } var buf bytes.Buffer if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { @@ -5502,10 +5474,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v != nil { b, err := v.(Marshaler).MarshalJSON() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } var buf bytes.Buffer if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { @@ -5529,10 +5498,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) e.encodeByte(',') @@ -5958,10 +5924,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { })) b, err := v.(Marshaler).MarshalJSON() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } var buf bytes.Buffer if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { @@ -5979,10 +5942,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) e.encodeByte(',') @@ -6143,10 +6103,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { })) b, err := v.(Marshaler).MarshalJSON() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } var buf bytes.Buffer if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { @@ -6167,10 +6124,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { - return &MarshalerError{ - Type: rtype2type(code.typ), - Err: err, - } + return errMarshaler(code, err) } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) e.encodeBytes([]byte{',', '\n'}) From ea96cc7811e007c05980e1464ca0236e6db67db0 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Tue, 17 Nov 2020 15:09:06 +0900 Subject: [PATCH 3/4] 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)), + })) +} From 9802f67a9bf4924034ddf0df39b75d62d6b0c199 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Tue, 17 Nov 2020 15:14:07 +0900 Subject: [PATCH 4/4] Refactor unsupported value error for float64 --- encode_vm.go | 80 +++++++++++----------------------------------------- 1 file changed, 16 insertions(+), 64 deletions(-) diff --git a/encode_vm.go b/encode_vm.go index 3240584..744e592 100644 --- a/encode_vm.go +++ b/encode_vm.go @@ -1533,10 +1533,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeByte('{') e.encodeKey(code) @@ -1554,10 +1551,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeKey(code) e.encodeFloat64(v) @@ -2170,10 +2164,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { v := e.ptrToFloat64(ptr) if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) @@ -2804,10 +2795,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeKey(code) e.encodeFloat64(v) @@ -2831,10 +2819,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeKey(code) e.encodeFloat64(v) @@ -3491,10 +3476,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeIndent(code.indent + 1) e.encodeKey(code) @@ -4026,10 +4008,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte('{') v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeKey(code) e.encodeString(fmt.Sprint(v)) @@ -4049,10 +4028,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeKey(code) e.encodeString(fmt.Sprint(v)) @@ -4596,10 +4572,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{'{', '\n'}) v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeIndent(code.indent + 1) e.encodeKey(code) @@ -4893,10 +4866,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } v := e.ptrToFloat64(p) if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeFloat64(v) e.encodeByte(',') @@ -4906,10 +4876,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeKey(code) v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeFloat64(v) e.encodeByte(',') @@ -5115,10 +5082,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { ptr := load(ctxptr, code.headIdx) v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeFloat64(v) e.encodeBytes([]byte{',', '\n'}) @@ -5369,10 +5333,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { v := e.ptrToFloat64(ptr + code.offset) if v != 0 { if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeKey(code) e.encodeFloat64(v) @@ -5618,10 +5579,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { v := e.ptrToFloat64(ptr + code.offset) if v != 0 { if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeIndent(code.indent) e.encodeKey(code) @@ -5817,10 +5775,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { ptr := load(ctxptr, code.headIdx) v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeKey(code) e.encodeString(fmt.Sprint(v)) @@ -5973,10 +5928,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { ptr := load(ctxptr, code.headIdx) v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: strconv.FormatFloat(v, 'g', -1, 64), - } + return errUnsupportedFloat(v) } e.encodeIndent(code.indent) e.encodeKey(code)