From 3415acf30dcf8cd10e4e40a0100c95997fa1d886 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Sat, 9 Jan 2021 21:08:29 +0900 Subject: [PATCH] Add float32/float64 test cases --- coverage_test.go | 1264 +++++++++++++++++++++++++++++++++++++++++++++- encode_vm.go | 483 ++++++++++++++++-- 2 files changed, 1689 insertions(+), 58 deletions(-) diff --git a/coverage_test.go b/coverage_test.go index 08fe30d..bc94e55 100644 --- a/coverage_test.go +++ b/coverage_test.go @@ -6,16 +6,18 @@ import ( "testing" ) -func intptr(v int) *int { return &v } -func int8ptr(v int8) *int8 { return &v } -func int16ptr(v int16) *int16 { return &v } -func int32ptr(v int32) *int32 { return &v } -func int64ptr(v int64) *int64 { return &v } -func uptr(v uint) *uint { return &v } -func uint8ptr(v uint8) *uint8 { return &v } -func uint16ptr(v uint16) *uint16 { return &v } -func uint32ptr(v uint32) *uint32 { return &v } -func uint64ptr(v uint64) *uint64 { return &v } +func intptr(v int) *int { return &v } +func int8ptr(v int8) *int8 { return &v } +func int16ptr(v int16) *int16 { return &v } +func int32ptr(v int32) *int32 { return &v } +func int64ptr(v int64) *int64 { return &v } +func uptr(v uint) *uint { return &v } +func uint8ptr(v uint8) *uint8 { return &v } +func uint16ptr(v uint16) *uint16 { return &v } +func uint32ptr(v uint32) *uint32 { return &v } +func uint64ptr(v uint64) *uint64 { return &v } +func float32ptr(v float32) *float32 { return &v } +func float64ptr(v float64) *float64 { return &v } func TestCoverStructHeadInt(t *testing.T) { type structInt struct { @@ -6228,3 +6230,1245 @@ func TestCoverStructHeadUint64(t *testing.T) { } } } + +func TestCoverStructHeadFloat32(t *testing.T) { + type structFloat32 struct { + A float32 `json:"a"` + } + type structFloat32Ptr struct { + A *float32 `json:"a"` + } + + tests := []struct { + name string + expected string + data interface{} + }{ + { + name: "HeadFloat32Zero", + expected: `{"a":0}`, + data: struct { + A float32 `json:"a"` + }{}, + }, + { + name: "HeadFloat32", + expected: `{"a":1}`, + data: struct { + A float32 `json:"a"` + }{A: 1}, + }, + { + name: "HeadFloat32Ptr", + expected: `{"a":1}`, + data: struct { + A *float32 `json:"a"` + }{A: float32ptr(1)}, + }, + { + name: "HeadFloat32PtrNil", + expected: `{"a":null}`, + data: struct { + A *float32 `json:"a"` + }{A: nil}, + }, + { + name: "PtrHeadFloat32Zero", + expected: `{"a":0}`, + data: &struct { + A float32 `json:"a"` + }{}, + }, + { + name: "PtrHeadFloat32", + expected: `{"a":1}`, + data: &struct { + A float32 `json:"a"` + }{A: 1}, + }, + { + name: "PtrHeadFloat32Ptr", + expected: `{"a":1}`, + data: &struct { + A *float32 `json:"a"` + }{A: float32ptr(1)}, + }, + { + name: "PtrHeadFloat32PtrNil", + expected: `{"a":null}`, + data: &struct { + A *float32 `json:"a"` + }{A: nil}, + }, + { + name: "PtrHeadFloat32Nil", + expected: `null`, + data: (*struct { + A *float32 `json:"a"` + })(nil), + }, + { + name: "HeadFloat32ZeroMultiFields", + expected: `{"a":0,"b":0}`, + data: struct { + A float32 `json:"a"` + B float32 `json:"b"` + }{}, + }, + { + name: "HeadFloat32MultiFields", + expected: `{"a":1,"b":2}`, + data: struct { + A float32 `json:"a"` + B float32 `json:"b"` + }{A: 1, B: 2}, + }, + { + name: "HeadFloat32PtrMultiFields", + expected: `{"a":1,"b":2}`, + data: struct { + A *float32 `json:"a"` + B *float32 `json:"b"` + }{A: float32ptr(1), B: float32ptr(2)}, + }, + { + name: "HeadFloat32PtrNilMultiFields", + expected: `{"a":null,"b":null}`, + data: struct { + A *float32 `json:"a"` + B *float32 `json:"b"` + }{A: nil, B: nil}, + }, + { + name: "PtrHeadFloat32ZeroMultiFields", + expected: `{"a":0,"b":0}`, + data: &struct { + A float32 `json:"a"` + B float32 `json:"b"` + }{}, + }, + { + name: "PtrHeadFloat32MultiFields", + expected: `{"a":1,"b":2}`, + data: &struct { + A float32 `json:"a"` + B float32 `json:"b"` + }{A: 1, B: 2}, + }, + { + name: "PtrHeadFloat32PtrMultiFields", + expected: `{"a":1,"b":2}`, + data: &struct { + A *float32 `json:"a"` + B *float32 `json:"b"` + }{A: float32ptr(1), B: float32ptr(2)}, + }, + { + name: "PtrHeadFloat32PtrNilMultiFields", + expected: `{"a":null,"b":null}`, + data: &struct { + A *float32 `json:"a"` + B *float32 `json:"b"` + }{A: nil, B: nil}, + }, + { + name: "PtrHeadFloat32NilMultiFields", + expected: `null`, + data: (*struct { + A *float32 `json:"a"` + B *float32 `json:"b"` + })(nil), + }, + { + name: "HeadFloat32ZeroNotRoot", + expected: `{"A":{"a":0}}`, + data: struct { + A struct { + A float32 `json:"a"` + } + }{}, + }, + { + name: "HeadFloat32NotRoot", + expected: `{"A":{"a":1}}`, + data: struct { + A struct { + A float32 `json:"a"` + } + }{A: struct { + A float32 `json:"a"` + }{A: 1}}, + }, + { + name: "HeadFloat32PtrNotRoot", + expected: `{"A":{"a":1}}`, + data: struct { + A struct { + A *float32 `json:"a"` + } + }{A: struct { + A *float32 `json:"a"` + }{float32ptr(1)}}, + }, + { + name: "HeadFloat32PtrNilNotRoot", + expected: `{"A":{"a":null}}`, + data: struct { + A struct { + A *float32 `json:"a"` + } + }{}, + }, + { + name: "PtrHeadFloat32ZeroNotRoot", + expected: `{"A":{"a":0}}`, + data: struct { + A *struct { + A float32 `json:"a"` + } + }{A: new(struct { + A float32 `json:"a"` + })}, + }, + { + name: "PtrHeadFloat32NotRoot", + expected: `{"A":{"a":1}}`, + data: struct { + A *struct { + A float32 `json:"a"` + } + }{A: &(struct { + A float32 `json:"a"` + }{A: 1})}, + }, + { + name: "PtrHeadFloat32PtrNotRoot", + expected: `{"A":{"a":1}}`, + data: struct { + A *struct { + A *float32 `json:"a"` + } + }{A: &(struct { + A *float32 `json:"a"` + }{A: float32ptr(1)})}, + }, + { + name: "PtrHeadFloat32PtrNilNotRoot", + expected: `{"A":{"a":null}}`, + data: struct { + A *struct { + A *float32 `json:"a"` + } + }{A: &(struct { + A *float32 `json:"a"` + }{A: nil})}, + }, + { + name: "PtrHeadFloat32NilNotRoot", + expected: `{"A":null}`, + data: struct { + A *struct { + A *float32 `json:"a"` + } + }{A: nil}, + }, + { + name: "HeadFloat32ZeroMultiFieldsNotRoot", + expected: `{"A":{"a":0},"B":{"b":0}}`, + data: struct { + A struct { + A float32 `json:"a"` + } + B struct { + B float32 `json:"b"` + } + }{}, + }, + { + name: "HeadFloat32MultiFieldsNotRoot", + expected: `{"A":{"a":1},"B":{"b":2}}`, + data: struct { + A struct { + A float32 `json:"a"` + } + B struct { + B float32 `json:"b"` + } + }{A: struct { + A float32 `json:"a"` + }{A: 1}, B: struct { + B float32 `json:"b"` + }{B: 2}}, + }, + { + name: "HeadFloat32PtrMultiFieldsNotRoot", + expected: `{"A":{"a":1},"B":{"b":2}}`, + data: struct { + A struct { + A *float32 `json:"a"` + } + B struct { + B *float32 `json:"b"` + } + }{A: struct { + A *float32 `json:"a"` + }{A: float32ptr(1)}, B: struct { + B *float32 `json:"b"` + }{B: float32ptr(2)}}, + }, + { + name: "HeadFloat32PtrNilMultiFieldsNotRoot", + expected: `{"A":{"a":null},"B":{"b":null}}`, + data: struct { + A struct { + A *float32 `json:"a"` + } + B struct { + B *float32 `json:"b"` + } + }{A: struct { + A *float32 `json:"a"` + }{A: nil}, B: struct { + B *float32 `json:"b"` + }{B: nil}}, + }, + { + name: "PtrHeadFloat32ZeroMultiFieldsNotRoot", + expected: `{"A":{"a":0},"B":{"b":0}}`, + data: &struct { + A struct { + A float32 `json:"a"` + } + B struct { + B float32 `json:"b"` + } + }{}, + }, + { + name: "PtrHeadFloat32MultiFieldsNotRoot", + expected: `{"A":{"a":1},"B":{"b":2}}`, + data: &struct { + A struct { + A float32 `json:"a"` + } + B struct { + B float32 `json:"b"` + } + }{A: struct { + A float32 `json:"a"` + }{A: 1}, B: struct { + B float32 `json:"b"` + }{B: 2}}, + }, + { + name: "PtrHeadFloat32PtrMultiFieldsNotRoot", + expected: `{"A":{"a":1},"B":{"b":2}}`, + data: &struct { + A *struct { + A *float32 `json:"a"` + } + B *struct { + B *float32 `json:"b"` + } + }{A: &(struct { + A *float32 `json:"a"` + }{A: float32ptr(1)}), B: &(struct { + B *float32 `json:"b"` + }{B: float32ptr(2)})}, + }, + { + name: "PtrHeadFloat32PtrNilMultiFieldsNotRoot", + expected: `{"A":null,"B":null}`, + data: &struct { + A *struct { + A *float32 `json:"a"` + } + B *struct { + B *float32 `json:"b"` + } + }{A: nil, B: nil}, + }, + { + name: "PtrHeadFloat32NilMultiFieldsNotRoot", + expected: `null`, + data: (*struct { + A *struct { + A *float32 `json:"a"` + } + B *struct { + B *float32 `json:"b"` + } + })(nil), + }, + { + name: "PtrHeadFloat32DoubleMultiFieldsNotRoot", + expected: `{"A":{"a":1,"b":2},"B":{"a":3,"b":4}}`, + data: &struct { + A *struct { + A float32 `json:"a"` + B float32 `json:"b"` + } + B *struct { + A float32 `json:"a"` + B float32 `json:"b"` + } + }{A: &(struct { + A float32 `json:"a"` + B float32 `json:"b"` + }{A: 1, B: 2}), B: &(struct { + A float32 `json:"a"` + B float32 `json:"b"` + }{A: 3, B: 4})}, + }, + { + name: "PtrHeadFloat32NilDoubleMultiFieldsNotRoot", + expected: `{"A":null,"B":null}`, + data: &struct { + A *struct { + A float32 `json:"a"` + B float32 `json:"b"` + } + B *struct { + A float32 `json:"a"` + B float32 `json:"b"` + } + }{A: nil, B: nil}, + }, + { + name: "PtrHeadFloat32NilDoubleMultiFieldsNotRoot", + expected: `null`, + data: (*struct { + A *struct { + A float32 `json:"a"` + B float32 `json:"b"` + } + B *struct { + A float32 `json:"a"` + B float32 `json:"b"` + } + })(nil), + }, + { + name: "PtrHeadFloat32PtrDoubleMultiFieldsNotRoot", + expected: `{"A":{"a":1,"b":2},"B":{"a":3,"b":4}}`, + data: &struct { + A *struct { + A *float32 `json:"a"` + B *float32 `json:"b"` + } + B *struct { + A *float32 `json:"a"` + B *float32 `json:"b"` + } + }{A: &(struct { + A *float32 `json:"a"` + B *float32 `json:"b"` + }{A: float32ptr(1), B: float32ptr(2)}), B: &(struct { + A *float32 `json:"a"` + B *float32 `json:"b"` + }{A: float32ptr(3), B: float32ptr(4)})}, + }, + { + name: "PtrHeadFloat32PtrNilDoubleMultiFieldsNotRoot", + expected: `{"A":null,"B":null}`, + data: &struct { + A *struct { + A *float32 `json:"a"` + B *float32 `json:"b"` + } + B *struct { + A *float32 `json:"a"` + B *float32 `json:"b"` + } + }{A: nil, B: nil}, + }, + { + name: "PtrHeadFloat32PtrNilDoubleMultiFieldsNotRoot", + expected: `null`, + data: (*struct { + A *struct { + A *float32 `json:"a"` + B *float32 `json:"b"` + } + B *struct { + A *float32 `json:"a"` + B *float32 `json:"b"` + } + })(nil), + }, + { + name: "AnonymousHeadFloat32", + expected: `{"a":1,"b":2}`, + data: struct { + structFloat32 + B float32 `json:"b"` + }{ + structFloat32: structFloat32{A: 1}, + B: 2, + }, + }, + { + name: "PtrAnonymousHeadFloat32", + expected: `{"a":1,"b":2}`, + data: struct { + *structFloat32 + B float32 `json:"b"` + }{ + structFloat32: &structFloat32{A: 1}, + B: 2, + }, + }, + { + name: "NilPtrAnonymousHeadFloat32", + expected: `{"b":2}`, + data: struct { + *structFloat32 + B float32 `json:"b"` + }{ + structFloat32: nil, + B: 2, + }, + }, + { + name: "AnonymousHeadFloat32Ptr", + expected: `{"a":1,"b":2}`, + data: struct { + structFloat32Ptr + B *float32 `json:"b"` + }{ + structFloat32Ptr: structFloat32Ptr{A: float32ptr(1)}, + B: float32ptr(2), + }, + }, + { + name: "AnonymousHeadFloat32PtrNil", + expected: `{"a":null,"b":2}`, + data: struct { + structFloat32Ptr + B *float32 `json:"b"` + }{ + structFloat32Ptr: structFloat32Ptr{A: nil}, + B: float32ptr(2), + }, + }, + { + name: "PtrAnonymousHeadFloat32Ptr", + expected: `{"a":1,"b":2}`, + data: struct { + *structFloat32Ptr + B *float32 `json:"b"` + }{ + structFloat32Ptr: &structFloat32Ptr{A: float32ptr(1)}, + B: float32ptr(2), + }, + }, + { + name: "NilPtrAnonymousHeadFloat32Ptr", + expected: `{"b":2}`, + data: struct { + *structFloat32Ptr + B *float32 `json:"b"` + }{ + structFloat32Ptr: nil, + B: float32ptr(2), + }, + }, + { + name: "AnonymousHeadFloat32Only", + expected: `{"a":1}`, + data: struct { + structFloat32 + }{ + structFloat32: structFloat32{A: 1}, + }, + }, + { + name: "PtrAnonymousHeadFloat32Only", + expected: `{"a":1}`, + data: struct { + *structFloat32 + }{ + structFloat32: &structFloat32{A: 1}, + }, + }, + { + name: "NilPtrAnonymousHeadFloat32Only", + expected: `{}`, + data: struct { + *structFloat32 + }{ + structFloat32: nil, + }, + }, + { + name: "AnonymousHeadFloat32PtrOnly", + expected: `{"a":1}`, + data: struct { + structFloat32Ptr + }{ + structFloat32Ptr: structFloat32Ptr{A: float32ptr(1)}, + }, + }, + { + name: "AnonymousHeadFloat32PtrNilOnly", + expected: `{"a":null}`, + data: struct { + structFloat32Ptr + }{ + structFloat32Ptr: structFloat32Ptr{A: nil}, + }, + }, + { + name: "PtrAnonymousHeadFloat32PtrOnly", + expected: `{"a":1}`, + data: struct { + *structFloat32Ptr + }{ + structFloat32Ptr: &structFloat32Ptr{A: float32ptr(1)}, + }, + }, + { + name: "NilPtrAnonymousHeadFloat32PtrOnly", + expected: `{}`, + data: struct { + *structFloat32Ptr + }{ + structFloat32Ptr: nil, + }, + }, + } + for _, test := range tests { + for _, htmlEscape := range []bool{true, false} { + var buf bytes.Buffer + enc := NewEncoder(&buf) + enc.SetEscapeHTML(htmlEscape) + if err := enc.Encode(test.data); err != nil { + t.Fatalf("%s(htmlEscape:%T): %s: %s", test.name, htmlEscape, test.expected, err) + } + if strings.TrimRight(buf.String(), "\n") != test.expected { + t.Fatalf("%s(htmlEscape:%T): expected %q but got %q", test.name, htmlEscape, test.expected, buf.String()) + } + } + } +} + +func TestCoverStructHeadFloat64(t *testing.T) { + type structFloat64 struct { + A float64 `json:"a"` + } + type structFloat64Ptr struct { + A *float64 `json:"a"` + } + + tests := []struct { + name string + expected string + data interface{} + }{ + { + name: "HeadFloat64Zero", + expected: `{"a":0}`, + data: struct { + A float64 `json:"a"` + }{}, + }, + { + name: "HeadFloat64", + expected: `{"a":1}`, + data: struct { + A float64 `json:"a"` + }{A: 1}, + }, + { + name: "HeadFloat64Ptr", + expected: `{"a":1}`, + data: struct { + A *float64 `json:"a"` + }{A: float64ptr(1)}, + }, + { + name: "HeadFloat64PtrNil", + expected: `{"a":null}`, + data: struct { + A *float64 `json:"a"` + }{A: nil}, + }, + { + name: "PtrHeadFloat64Zero", + expected: `{"a":0}`, + data: &struct { + A float64 `json:"a"` + }{}, + }, + { + name: "PtrHeadFloat64", + expected: `{"a":1}`, + data: &struct { + A float64 `json:"a"` + }{A: 1}, + }, + { + name: "PtrHeadFloat64Ptr", + expected: `{"a":1}`, + data: &struct { + A *float64 `json:"a"` + }{A: float64ptr(1)}, + }, + { + name: "PtrHeadFloat64PtrNil", + expected: `{"a":null}`, + data: &struct { + A *float64 `json:"a"` + }{A: nil}, + }, + { + name: "PtrHeadFloat64Nil", + expected: `null`, + data: (*struct { + A *float64 `json:"a"` + })(nil), + }, + { + name: "HeadFloat64ZeroMultiFields", + expected: `{"a":0,"b":0}`, + data: struct { + A float64 `json:"a"` + B float64 `json:"b"` + }{}, + }, + { + name: "HeadFloat64MultiFields", + expected: `{"a":1,"b":2}`, + data: struct { + A float64 `json:"a"` + B float64 `json:"b"` + }{A: 1, B: 2}, + }, + { + name: "HeadFloat64PtrMultiFields", + expected: `{"a":1,"b":2}`, + data: struct { + A *float64 `json:"a"` + B *float64 `json:"b"` + }{A: float64ptr(1), B: float64ptr(2)}, + }, + { + name: "HeadFloat64PtrNilMultiFields", + expected: `{"a":null,"b":null}`, + data: struct { + A *float64 `json:"a"` + B *float64 `json:"b"` + }{A: nil, B: nil}, + }, + { + name: "PtrHeadFloat64ZeroMultiFields", + expected: `{"a":0,"b":0}`, + data: &struct { + A float64 `json:"a"` + B float64 `json:"b"` + }{}, + }, + { + name: "PtrHeadFloat64MultiFields", + expected: `{"a":1,"b":2}`, + data: &struct { + A float64 `json:"a"` + B float64 `json:"b"` + }{A: 1, B: 2}, + }, + { + name: "PtrHeadFloat64PtrMultiFields", + expected: `{"a":1,"b":2}`, + data: &struct { + A *float64 `json:"a"` + B *float64 `json:"b"` + }{A: float64ptr(1), B: float64ptr(2)}, + }, + { + name: "PtrHeadFloat64PtrNilMultiFields", + expected: `{"a":null,"b":null}`, + data: &struct { + A *float64 `json:"a"` + B *float64 `json:"b"` + }{A: nil, B: nil}, + }, + { + name: "PtrHeadFloat64NilMultiFields", + expected: `null`, + data: (*struct { + A *float64 `json:"a"` + B *float64 `json:"b"` + })(nil), + }, + { + name: "HeadFloat64ZeroNotRoot", + expected: `{"A":{"a":0}}`, + data: struct { + A struct { + A float64 `json:"a"` + } + }{}, + }, + { + name: "HeadFloat64NotRoot", + expected: `{"A":{"a":1}}`, + data: struct { + A struct { + A float64 `json:"a"` + } + }{A: struct { + A float64 `json:"a"` + }{A: 1}}, + }, + { + name: "HeadFloat64PtrNotRoot", + expected: `{"A":{"a":1}}`, + data: struct { + A struct { + A *float64 `json:"a"` + } + }{A: struct { + A *float64 `json:"a"` + }{float64ptr(1)}}, + }, + { + name: "HeadFloat64PtrNilNotRoot", + expected: `{"A":{"a":null}}`, + data: struct { + A struct { + A *float64 `json:"a"` + } + }{}, + }, + { + name: "PtrHeadFloat64ZeroNotRoot", + expected: `{"A":{"a":0}}`, + data: struct { + A *struct { + A float64 `json:"a"` + } + }{A: new(struct { + A float64 `json:"a"` + })}, + }, + { + name: "PtrHeadFloat64NotRoot", + expected: `{"A":{"a":1}}`, + data: struct { + A *struct { + A float64 `json:"a"` + } + }{A: &(struct { + A float64 `json:"a"` + }{A: 1})}, + }, + { + name: "PtrHeadFloat64PtrNotRoot", + expected: `{"A":{"a":1}}`, + data: struct { + A *struct { + A *float64 `json:"a"` + } + }{A: &(struct { + A *float64 `json:"a"` + }{A: float64ptr(1)})}, + }, + { + name: "PtrHeadFloat64PtrNilNotRoot", + expected: `{"A":{"a":null}}`, + data: struct { + A *struct { + A *float64 `json:"a"` + } + }{A: &(struct { + A *float64 `json:"a"` + }{A: nil})}, + }, + { + name: "PtrHeadFloat64NilNotRoot", + expected: `{"A":null}`, + data: struct { + A *struct { + A *float64 `json:"a"` + } + }{A: nil}, + }, + { + name: "HeadFloat64ZeroMultiFieldsNotRoot", + expected: `{"A":{"a":0},"B":{"b":0}}`, + data: struct { + A struct { + A float64 `json:"a"` + } + B struct { + B float64 `json:"b"` + } + }{}, + }, + { + name: "HeadFloat64MultiFieldsNotRoot", + expected: `{"A":{"a":1},"B":{"b":2}}`, + data: struct { + A struct { + A float64 `json:"a"` + } + B struct { + B float64 `json:"b"` + } + }{A: struct { + A float64 `json:"a"` + }{A: 1}, B: struct { + B float64 `json:"b"` + }{B: 2}}, + }, + { + name: "HeadFloat64PtrMultiFieldsNotRoot", + expected: `{"A":{"a":1},"B":{"b":2}}`, + data: struct { + A struct { + A *float64 `json:"a"` + } + B struct { + B *float64 `json:"b"` + } + }{A: struct { + A *float64 `json:"a"` + }{A: float64ptr(1)}, B: struct { + B *float64 `json:"b"` + }{B: float64ptr(2)}}, + }, + { + name: "HeadFloat64PtrNilMultiFieldsNotRoot", + expected: `{"A":{"a":null},"B":{"b":null}}`, + data: struct { + A struct { + A *float64 `json:"a"` + } + B struct { + B *float64 `json:"b"` + } + }{A: struct { + A *float64 `json:"a"` + }{A: nil}, B: struct { + B *float64 `json:"b"` + }{B: nil}}, + }, + { + name: "PtrHeadFloat64ZeroMultiFieldsNotRoot", + expected: `{"A":{"a":0},"B":{"b":0}}`, + data: &struct { + A struct { + A float64 `json:"a"` + } + B struct { + B float64 `json:"b"` + } + }{}, + }, + { + name: "PtrHeadFloat64MultiFieldsNotRoot", + expected: `{"A":{"a":1},"B":{"b":2}}`, + data: &struct { + A struct { + A float64 `json:"a"` + } + B struct { + B float64 `json:"b"` + } + }{A: struct { + A float64 `json:"a"` + }{A: 1}, B: struct { + B float64 `json:"b"` + }{B: 2}}, + }, + { + name: "PtrHeadFloat64PtrMultiFieldsNotRoot", + expected: `{"A":{"a":1},"B":{"b":2}}`, + data: &struct { + A *struct { + A *float64 `json:"a"` + } + B *struct { + B *float64 `json:"b"` + } + }{A: &(struct { + A *float64 `json:"a"` + }{A: float64ptr(1)}), B: &(struct { + B *float64 `json:"b"` + }{B: float64ptr(2)})}, + }, + { + name: "PtrHeadFloat64PtrNilMultiFieldsNotRoot", + expected: `{"A":null,"B":null}`, + data: &struct { + A *struct { + A *float64 `json:"a"` + } + B *struct { + B *float64 `json:"b"` + } + }{A: nil, B: nil}, + }, + { + name: "PtrHeadFloat64NilMultiFieldsNotRoot", + expected: `null`, + data: (*struct { + A *struct { + A *float64 `json:"a"` + } + B *struct { + B *float64 `json:"b"` + } + })(nil), + }, + { + name: "PtrHeadFloat64DoubleMultiFieldsNotRoot", + expected: `{"A":{"a":1,"b":2},"B":{"a":3,"b":4}}`, + data: &struct { + A *struct { + A float64 `json:"a"` + B float64 `json:"b"` + } + B *struct { + A float64 `json:"a"` + B float64 `json:"b"` + } + }{A: &(struct { + A float64 `json:"a"` + B float64 `json:"b"` + }{A: 1, B: 2}), B: &(struct { + A float64 `json:"a"` + B float64 `json:"b"` + }{A: 3, B: 4})}, + }, + { + name: "PtrHeadFloat64NilDoubleMultiFieldsNotRoot", + expected: `{"A":null,"B":null}`, + data: &struct { + A *struct { + A float64 `json:"a"` + B float64 `json:"b"` + } + B *struct { + A float64 `json:"a"` + B float64 `json:"b"` + } + }{A: nil, B: nil}, + }, + { + name: "PtrHeadFloat64NilDoubleMultiFieldsNotRoot", + expected: `null`, + data: (*struct { + A *struct { + A float64 `json:"a"` + B float64 `json:"b"` + } + B *struct { + A float64 `json:"a"` + B float64 `json:"b"` + } + })(nil), + }, + { + name: "PtrHeadFloat64PtrDoubleMultiFieldsNotRoot", + expected: `{"A":{"a":1,"b":2},"B":{"a":3,"b":4}}`, + data: &struct { + A *struct { + A *float64 `json:"a"` + B *float64 `json:"b"` + } + B *struct { + A *float64 `json:"a"` + B *float64 `json:"b"` + } + }{A: &(struct { + A *float64 `json:"a"` + B *float64 `json:"b"` + }{A: float64ptr(1), B: float64ptr(2)}), B: &(struct { + A *float64 `json:"a"` + B *float64 `json:"b"` + }{A: float64ptr(3), B: float64ptr(4)})}, + }, + { + name: "PtrHeadFloat64PtrNilDoubleMultiFieldsNotRoot", + expected: `{"A":null,"B":null}`, + data: &struct { + A *struct { + A *float64 `json:"a"` + B *float64 `json:"b"` + } + B *struct { + A *float64 `json:"a"` + B *float64 `json:"b"` + } + }{A: nil, B: nil}, + }, + { + name: "PtrHeadFloat64PtrNilDoubleMultiFieldsNotRoot", + expected: `null`, + data: (*struct { + A *struct { + A *float64 `json:"a"` + B *float64 `json:"b"` + } + B *struct { + A *float64 `json:"a"` + B *float64 `json:"b"` + } + })(nil), + }, + { + name: "AnonymousHeadFloat64", + expected: `{"a":1,"b":2}`, + data: struct { + structFloat64 + B float64 `json:"b"` + }{ + structFloat64: structFloat64{A: 1}, + B: 2, + }, + }, + { + name: "PtrAnonymousHeadFloat64", + expected: `{"a":1,"b":2}`, + data: struct { + *structFloat64 + B float64 `json:"b"` + }{ + structFloat64: &structFloat64{A: 1}, + B: 2, + }, + }, + { + name: "NilPtrAnonymousHeadFloat64", + expected: `{"b":2}`, + data: struct { + *structFloat64 + B float64 `json:"b"` + }{ + structFloat64: nil, + B: 2, + }, + }, + { + name: "AnonymousHeadFloat64Ptr", + expected: `{"a":1,"b":2}`, + data: struct { + structFloat64Ptr + B *float64 `json:"b"` + }{ + structFloat64Ptr: structFloat64Ptr{A: float64ptr(1)}, + B: float64ptr(2), + }, + }, + { + name: "AnonymousHeadFloat64PtrNil", + expected: `{"a":null,"b":2}`, + data: struct { + structFloat64Ptr + B *float64 `json:"b"` + }{ + structFloat64Ptr: structFloat64Ptr{A: nil}, + B: float64ptr(2), + }, + }, + { + name: "PtrAnonymousHeadFloat64Ptr", + expected: `{"a":1,"b":2}`, + data: struct { + *structFloat64Ptr + B *float64 `json:"b"` + }{ + structFloat64Ptr: &structFloat64Ptr{A: float64ptr(1)}, + B: float64ptr(2), + }, + }, + { + name: "NilPtrAnonymousHeadFloat64Ptr", + expected: `{"b":2}`, + data: struct { + *structFloat64Ptr + B *float64 `json:"b"` + }{ + structFloat64Ptr: nil, + B: float64ptr(2), + }, + }, + { + name: "AnonymousHeadFloat64Only", + expected: `{"a":1}`, + data: struct { + structFloat64 + }{ + structFloat64: structFloat64{A: 1}, + }, + }, + { + name: "PtrAnonymousHeadFloat64Only", + expected: `{"a":1}`, + data: struct { + *structFloat64 + }{ + structFloat64: &structFloat64{A: 1}, + }, + }, + { + name: "NilPtrAnonymousHeadFloat64Only", + expected: `{}`, + data: struct { + *structFloat64 + }{ + structFloat64: nil, + }, + }, + { + name: "AnonymousHeadFloat64PtrOnly", + expected: `{"a":1}`, + data: struct { + structFloat64Ptr + }{ + structFloat64Ptr: structFloat64Ptr{A: float64ptr(1)}, + }, + }, + { + name: "AnonymousHeadFloat64PtrNilOnly", + expected: `{"a":null}`, + data: struct { + structFloat64Ptr + }{ + structFloat64Ptr: structFloat64Ptr{A: nil}, + }, + }, + { + name: "PtrAnonymousHeadFloat64PtrOnly", + expected: `{"a":1}`, + data: struct { + *structFloat64Ptr + }{ + structFloat64Ptr: &structFloat64Ptr{A: float64ptr(1)}, + }, + }, + { + name: "NilPtrAnonymousHeadFloat64PtrOnly", + expected: `{}`, + data: struct { + *structFloat64Ptr + }{ + structFloat64Ptr: nil, + }, + }, + } + for _, test := range tests { + for _, htmlEscape := range []bool{true, false} { + var buf bytes.Buffer + enc := NewEncoder(&buf) + enc.SetEscapeHTML(htmlEscape) + if err := enc.Encode(test.data); err != nil { + t.Fatalf("%s(htmlEscape:%T): %s: %s", test.name, htmlEscape, test.expected, err) + } + if strings.TrimRight(buf.String(), "\n") != test.expected { + t.Fatalf("%s(htmlEscape:%T): expected %q but got %q", test.name, htmlEscape, test.expected, buf.String()) + } + } + } +} diff --git a/encode_vm.go b/encode_vm.go index 8809461..682e853 100644 --- a/encode_vm.go +++ b/encode_vm.go @@ -3830,26 +3830,14 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte } b = encodeComma(b) code = code.next - case opStructFieldPtrHeadFloat32: - p := load(ctxptr, code.idx) - if p == 0 { - b = encodeNull(b) - b = encodeComma(b) - code = code.end.next - break - } - store(ctxptr, code.idx, e.ptrToPtr(p)) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadFloat32: ptr := load(ctxptr, code.idx) if ptr == 0 { - if code.op == opStructFieldPtrHeadFloat32 { - b = encodeNull(b) - b = encodeComma(b) - } else { - b = append(b, '{', '}', ',') - } + b = encodeNull(b) + b = encodeComma(b) code = code.end.next } else { b = append(b, '{') @@ -3858,7 +3846,59 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte b = encodeComma(b) code = code.next } + case opStructFieldPtrHeadFloat32Only, opStructFieldHeadFloat32Only: + p := load(ctxptr, code.idx) + b = append(b, '{') + b = append(b, code.key...) + b = encodeFloat32(b, e.ptrToFloat32(p)) + b = encodeComma(b) + code = code.next case opStructEscapedFieldPtrHeadFloat32: + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) + fallthrough + case opStructEscapedFieldHeadFloat32: + ptr := load(ctxptr, code.idx) + if ptr == 0 { + b = encodeNull(b) + b = encodeComma(b) + code = code.end.next + } else { + b = append(b, '{') + b = append(b, code.escapedKey...) + b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset)) + b = encodeComma(b) + code = code.next + } + case opStructEscapedFieldPtrHeadFloat32Only, opStructEscapedFieldHeadFloat32Only: + p := load(ctxptr, code.idx) + b = append(b, '{') + b = append(b, code.escapedKey...) + b = encodeFloat32(b, e.ptrToFloat32(p)) + b = encodeComma(b) + code = code.next + case opStructFieldPtrHeadFloat32Ptr: + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) + fallthrough + case opStructFieldHeadFloat32Ptr: + p := load(ctxptr, code.idx) + if p == 0 { + b = encodeNull(b) + b = encodeComma(b) + code = code.end.next + break + } else { + b = append(b, '{') + b = append(b, code.key...) + p = e.ptrToPtr(p) + if p == 0 { + b = encodeNull(b) + } else { + b = encodeFloat32(b, e.ptrToFloat32(p+code.offset)) + } + } + b = encodeComma(b) + code = code.next + case opStructFieldPtrHeadFloat32PtrOnly: p := load(ctxptr, code.idx) if p == 0 { b = encodeNull(b) @@ -3868,23 +3908,60 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte } store(ctxptr, code.idx, e.ptrToPtr(p)) fallthrough - case opStructEscapedFieldHeadFloat32: - ptr := load(ctxptr, code.idx) - if ptr == 0 { - if code.op == opStructEscapedFieldPtrHeadFloat32 { - b = encodeNull(b) - b = encodeComma(b) - } else { - b = append(b, '{', '}', ',') - } + case opStructFieldHeadFloat32PtrOnly: + p := load(ctxptr, code.idx) + b = append(b, '{') + b = append(b, code.key...) + if p == 0 { + b = encodeNull(b) + } else { + b = encodeFloat32(b, e.ptrToFloat32(p+code.offset)) + } + b = encodeComma(b) + code = code.next + case opStructEscapedFieldPtrHeadFloat32Ptr: + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) + fallthrough + case opStructEscapedFieldHeadFloat32Ptr: + p := load(ctxptr, code.idx) + if p == 0 { + b = encodeNull(b) + b = encodeComma(b) code = code.end.next + break } else { b = append(b, '{') b = append(b, code.escapedKey...) - b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset)) - b = encodeComma(b) - code = code.next + p = e.ptrToPtr(p) + if p == 0 { + b = encodeNull(b) + } else { + b = encodeFloat32(b, e.ptrToFloat32(p+code.offset)) + } } + b = encodeComma(b) + code = code.next + case opStructEscapedFieldPtrHeadFloat32PtrOnly: + p := load(ctxptr, code.idx) + if p == 0 { + b = encodeNull(b) + b = encodeComma(b) + code = code.end.next + break + } + store(ctxptr, code.idx, e.ptrToPtr(p)) + fallthrough + case opStructEscapedFieldHeadFloat32PtrOnly: + p := load(ctxptr, code.idx) + b = append(b, '{') + b = append(b, code.escapedKey...) + if p == 0 { + b = encodeNull(b) + } else { + b = encodeFloat32(b, e.ptrToFloat32(p+code.offset)) + } + b = encodeComma(b) + code = code.next case opStructFieldPtrAnonymousHeadFloat32: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough @@ -3911,25 +3988,106 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte b = encodeComma(b) code = code.next } - case opStructFieldPtrHeadFloat64: + case opStructFieldPtrAnonymousHeadFloat32Only, opStructFieldAnonymousHeadFloat32Only: + ptr := load(ctxptr, code.idx) + if ptr == 0 { + code = code.end.next + } else { + b = append(b, code.key...) + b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset)) + b = encodeComma(b) + code = code.next + } + case opStructEscapedFieldPtrAnonymousHeadFloat32Only, opStructEscapedFieldAnonymousHeadFloat32Only: + ptr := load(ctxptr, code.idx) + if ptr == 0 { + code = code.end.next + } else { + b = append(b, code.escapedKey...) + b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset)) + b = encodeComma(b) + code = code.next + } + case opStructFieldPtrAnonymousHeadFloat32Ptr: + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) + fallthrough + case opStructFieldAnonymousHeadFloat32Ptr: p := load(ctxptr, code.idx) + if p == 0 { + code = code.end.next + break + } + b = append(b, code.key...) + p = e.ptrToPtr(p) if p == 0 { b = encodeNull(b) - b = encodeComma(b) + } else { + b = encodeFloat32(b, e.ptrToFloat32(p+code.offset)) + } + b = encodeComma(b) + code = code.next + case opStructEscapedFieldPtrAnonymousHeadFloat32Ptr: + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) + fallthrough + case opStructEscapedFieldAnonymousHeadFloat32Ptr: + p := load(ctxptr, code.idx) + if p == 0 { + code = code.end.next + break + } + b = append(b, code.escapedKey...) + p = e.ptrToPtr(p) + if p == 0 { + b = encodeNull(b) + } else { + b = encodeFloat32(b, e.ptrToFloat32(p+code.offset)) + } + b = encodeComma(b) + code = code.next + case opStructFieldPtrAnonymousHeadFloat32PtrOnly: + p := load(ctxptr, code.idx) + if p == 0 { code = code.end.next break } store(ctxptr, code.idx, e.ptrToPtr(p)) fallthrough + case opStructFieldAnonymousHeadFloat32PtrOnly: + p := load(ctxptr, code.idx) + b = append(b, code.key...) + if p == 0 { + b = encodeNull(b) + } else { + b = encodeFloat32(b, e.ptrToFloat32(p+code.offset)) + } + b = encodeComma(b) + code = code.next + case opStructEscapedFieldPtrAnonymousHeadFloat32PtrOnly: + p := load(ctxptr, code.idx) + if p == 0 { + code = code.end.next + break + } + store(ctxptr, code.idx, e.ptrToPtr(p)) + fallthrough + case opStructEscapedFieldAnonymousHeadFloat32PtrOnly: + p := load(ctxptr, code.idx) + b = append(b, code.escapedKey...) + if p == 0 { + b = encodeNull(b) + } else { + b = encodeFloat32(b, e.ptrToFloat32(p+code.offset)) + } + b = encodeComma(b) + code = code.next + case opStructFieldPtrHeadFloat64: + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) + fallthrough case opStructFieldHeadFloat64: ptr := load(ctxptr, code.idx) if ptr == 0 { - if code.op == opStructFieldPtrHeadFloat64 { - b = encodeNull(b) - b = encodeComma(b) - } else { - b = append(b, '{', '}', ',') - } + b = encodeNull(b) + b = encodeComma(b) code = code.end.next } else { v := e.ptrToFloat64(ptr + code.offset) @@ -3942,25 +4100,25 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte b = encodeComma(b) code = code.next } - case opStructEscapedFieldPtrHeadFloat64: + case opStructFieldPtrHeadFloat64Only, opStructFieldHeadFloat64Only: p := load(ctxptr, code.idx) - if p == 0 { - b = encodeNull(b) - b = encodeComma(b) - code = code.end.next - break + b = append(b, '{') + b = append(b, code.key...) + v := e.ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) } - store(ctxptr, code.idx, e.ptrToPtr(p)) + b = encodeFloat64(b, v) + b = encodeComma(b) + code = code.next + case opStructEscapedFieldPtrHeadFloat64: + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructEscapedFieldHeadFloat64: ptr := load(ctxptr, code.idx) if ptr == 0 { - if code.op == opStructEscapedFieldPtrHeadFloat64 { - b = encodeNull(b) - b = encodeComma(b) - } else { - b = append(b, '{', '}', ',') - } + b = encodeNull(b) + b = encodeComma(b) code = code.end.next } else { v := e.ptrToFloat64(ptr + code.offset) @@ -3973,6 +4131,119 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte b = encodeComma(b) code = code.next } + case opStructEscapedFieldPtrHeadFloat64Only, opStructEscapedFieldHeadFloat64Only: + p := load(ctxptr, code.idx) + b = append(b, '{') + b = append(b, code.escapedKey...) + v := e.ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = encodeFloat64(b, v) + b = encodeComma(b) + code = code.next + case opStructFieldPtrHeadFloat64Ptr: + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) + fallthrough + case opStructFieldHeadFloat64Ptr: + p := load(ctxptr, code.idx) + if p == 0 { + b = encodeNull(b) + b = encodeComma(b) + code = code.end.next + break + } else { + b = append(b, '{') + b = append(b, code.key...) + p = e.ptrToPtr(p) + if p == 0 { + b = encodeNull(b) + } else { + v := e.ptrToFloat64(p + code.offset) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = encodeFloat64(b, v) + } + } + b = encodeComma(b) + code = code.next + case opStructFieldPtrHeadFloat64PtrOnly: + p := load(ctxptr, code.idx) + if p == 0 { + b = encodeNull(b) + b = encodeComma(b) + code = code.end.next + break + } + store(ctxptr, code.idx, e.ptrToPtr(p)) + fallthrough + case opStructFieldHeadFloat64PtrOnly: + p := load(ctxptr, code.idx) + b = append(b, '{') + b = append(b, code.key...) + if p == 0 { + b = encodeNull(b) + } else { + v := e.ptrToFloat64(p + code.offset) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = encodeFloat64(b, v) + } + b = encodeComma(b) + code = code.next + case opStructEscapedFieldPtrHeadFloat64Ptr: + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) + fallthrough + case opStructEscapedFieldHeadFloat64Ptr: + p := load(ctxptr, code.idx) + if p == 0 { + b = encodeNull(b) + b = encodeComma(b) + code = code.end.next + break + } else { + b = append(b, '{') + b = append(b, code.escapedKey...) + p = e.ptrToPtr(p) + if p == 0 { + b = encodeNull(b) + } else { + v := e.ptrToFloat64(p + code.offset) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = encodeFloat64(b, v) + } + } + b = encodeComma(b) + code = code.next + case opStructEscapedFieldPtrHeadFloat64PtrOnly: + p := load(ctxptr, code.idx) + if p == 0 { + b = encodeNull(b) + b = encodeComma(b) + code = code.end.next + break + } + store(ctxptr, code.idx, e.ptrToPtr(p)) + fallthrough + case opStructEscapedFieldHeadFloat64PtrOnly: + p := load(ctxptr, code.idx) + b = append(b, '{') + b = append(b, code.escapedKey...) + if p == 0 { + b = encodeNull(b) + } else { + v := e.ptrToFloat64(p + code.offset) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = encodeFloat64(b, v) + } + b = encodeComma(b) + code = code.next case opStructFieldPtrAnonymousHeadFloat64: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough @@ -4007,6 +4278,122 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte b = encodeComma(b) code = code.next } + case opStructFieldPtrAnonymousHeadFloat64Only, opStructFieldAnonymousHeadFloat64Only: + ptr := load(ctxptr, code.idx) + if ptr == 0 { + code = code.end.next + } else { + b = append(b, code.key...) + v := e.ptrToFloat64(ptr + code.offset) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = encodeFloat64(b, v) + b = encodeComma(b) + code = code.next + } + case opStructEscapedFieldPtrAnonymousHeadFloat64Only, opStructEscapedFieldAnonymousHeadFloat64Only: + ptr := load(ctxptr, code.idx) + if ptr == 0 { + code = code.end.next + } else { + b = append(b, code.escapedKey...) + v := e.ptrToFloat64(ptr + code.offset) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = encodeFloat64(b, v) + b = encodeComma(b) + code = code.next + } + case opStructFieldPtrAnonymousHeadFloat64Ptr: + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) + fallthrough + case opStructFieldAnonymousHeadFloat64Ptr: + p := load(ctxptr, code.idx) + if p == 0 { + code = code.end.next + break + } + b = append(b, code.key...) + p = e.ptrToPtr(p) + if p == 0 { + b = encodeNull(b) + } else { + v := e.ptrToFloat64(p + code.offset) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = encodeFloat64(b, v) + } + b = encodeComma(b) + code = code.next + case opStructEscapedFieldPtrAnonymousHeadFloat64Ptr: + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) + fallthrough + case opStructEscapedFieldAnonymousHeadFloat64Ptr: + p := load(ctxptr, code.idx) + if p == 0 { + code = code.end.next + break + } + b = append(b, code.escapedKey...) + p = e.ptrToPtr(p) + if p == 0 { + b = encodeNull(b) + } else { + v := e.ptrToFloat64(p + code.offset) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = encodeFloat64(b, v) + } + b = encodeComma(b) + code = code.next + case opStructFieldPtrAnonymousHeadFloat64PtrOnly: + p := load(ctxptr, code.idx) + if p == 0 { + code = code.end.next + break + } + store(ctxptr, code.idx, e.ptrToPtr(p)) + fallthrough + case opStructFieldAnonymousHeadFloat64PtrOnly: + p := load(ctxptr, code.idx) + b = append(b, code.key...) + if p == 0 { + b = encodeNull(b) + } else { + v := e.ptrToFloat64(p + code.offset) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = encodeFloat64(b, v) + } + b = encodeComma(b) + code = code.next + case opStructEscapedFieldPtrAnonymousHeadFloat64PtrOnly: + p := load(ctxptr, code.idx) + if p == 0 { + code = code.end.next + break + } + store(ctxptr, code.idx, e.ptrToPtr(p)) + fallthrough + case opStructEscapedFieldAnonymousHeadFloat64PtrOnly: + p := load(ctxptr, code.idx) + b = append(b, code.escapedKey...) + if p == 0 { + b = encodeNull(b) + } else { + v := e.ptrToFloat64(p + code.offset) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = encodeFloat64(b, v) + } + b = encodeComma(b) + code = code.next case opStructFieldPtrHeadString: p := load(ctxptr, code.idx) if p == 0 {