diff --git a/cover_int16_test.go b/cover_int16_test.go
index ce3f100..20b1fdf 100644
--- a/cover_int16_test.go
+++ b/cover_int16_test.go
@@ -12,9 +12,22 @@ func TestCoverInt16(t *testing.T) {
 	type structInt16 struct {
 		A int16 `json:"a"`
 	}
+	type structInt16OmitEmpty struct {
+		A int16 `json:"a,omitempty"`
+	}
+	type structInt16String struct {
+		A int16 `json:"a,string"`
+	}
+
 	type structInt16Ptr struct {
 		A *int16 `json:"a"`
 	}
+	type structInt16PtrOmitEmpty struct {
+		A *int16 `json:"a,omitempty"`
+	}
+	type structInt16PtrString struct {
+		A *int16 `json:"a,string"`
+	}
 
 	tests := []struct {
 		name           string
@@ -22,6 +35,7 @@ func TestCoverInt16(t *testing.T) {
 		indentExpected string
 		data           interface{}
 	}{
+		// HeadInt16Zero
 		{
 			name:     "HeadInt16Zero",
 			expected: `{"a":0}`,
@@ -34,6 +48,30 @@ func TestCoverInt16(t *testing.T) {
 				A int16 `json:"a"`
 			}{},
 		},
+		{
+			name:     "HeadInt16ZeroOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: struct {
+				A int16 `json:"a,omitempty"`
+			}{},
+		},
+		{
+			name:     "HeadInt16ZeroString",
+			expected: `{"a":"0"}`,
+			indentExpected: `
+{
+  "a": "0"
+}
+`,
+			data: struct {
+				A int16 `json:"a,string"`
+			}{},
+		},
+
+		// HeadInt16
 		{
 			name:     "HeadInt16",
 			expected: `{"a":1}`,
@@ -46,6 +84,32 @@ func TestCoverInt16(t *testing.T) {
 				A int16 `json:"a"`
 			}{A: 1},
 		},
+		{
+			name:     "HeadInt16OmitEmpty",
+			expected: `{"a":1}`,
+			indentExpected: `
+{
+  "a": 1
+}
+`,
+			data: struct {
+				A int16 `json:"a,omitempty"`
+			}{A: 1},
+		},
+		{
+			name:     "HeadInt16String",
+			expected: `{"a":"1"}`,
+			indentExpected: `
+{
+  "a": "1"
+}
+`,
+			data: struct {
+				A int16 `json:"a,string"`
+			}{A: 1},
+		},
+
+		// HeadInt16Ptr
 		{
 			name:     "HeadInt16Ptr",
 			expected: `{"a":1}`,
@@ -58,6 +122,32 @@ func TestCoverInt16(t *testing.T) {
 				A *int16 `json:"a"`
 			}{A: int16ptr(1)},
 		},
+		{
+			name:     "HeadInt16PtrOmitEmpty",
+			expected: `{"a":1}`,
+			indentExpected: `
+{
+  "a": 1
+}
+`,
+			data: struct {
+				A *int16 `json:"a,omitempty"`
+			}{A: int16ptr(1)},
+		},
+		{
+			name:     "HeadInt16PtrString",
+			expected: `{"a":"1"}`,
+			indentExpected: `
+{
+  "a": "1"
+}
+`,
+			data: struct {
+				A *int16 `json:"a,string"`
+			}{A: int16ptr(1)},
+		},
+
+		// HeadInt16PtrNil
 		{
 			name:     "HeadInt16PtrNil",
 			expected: `{"a":null}`,
@@ -70,6 +160,30 @@ func TestCoverInt16(t *testing.T) {
 				A *int16 `json:"a"`
 			}{A: nil},
 		},
+		{
+			name:     "HeadInt16PtrNilOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: struct {
+				A *int16 `json:"a,omitempty"`
+			}{A: nil},
+		},
+		{
+			name:     "HeadInt16PtrNilString",
+			expected: `{"a":null}`,
+			indentExpected: `
+{
+  "a": null
+}
+`,
+			data: struct {
+				A *int16 `json:"a,string"`
+			}{A: nil},
+		},
+
+		// PtrHeadInt16Zero
 		{
 			name:     "PtrHeadInt16Zero",
 			expected: `{"a":0}`,
@@ -82,6 +196,30 @@ func TestCoverInt16(t *testing.T) {
 				A int16 `json:"a"`
 			}{},
 		},
+		{
+			name:     "PtrHeadInt16ZeroOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: &struct {
+				A int16 `json:"a,omitempty"`
+			}{},
+		},
+		{
+			name:     "PtrHeadInt16ZeroString",
+			expected: `{"a":"0"}`,
+			indentExpected: `
+{
+  "a": "0"
+}
+`,
+			data: &struct {
+				A int16 `json:"a,string"`
+			}{},
+		},
+
+		// PtrHeadInt16
 		{
 			name:     "PtrHeadInt16",
 			expected: `{"a":1}`,
@@ -94,6 +232,32 @@ func TestCoverInt16(t *testing.T) {
 				A int16 `json:"a"`
 			}{A: 1},
 		},
+		{
+			name:     "PtrHeadInt16OmitEmpty",
+			expected: `{"a":1}`,
+			indentExpected: `
+{
+  "a": 1
+}
+`,
+			data: &struct {
+				A int16 `json:"a,omitempty"`
+			}{A: 1},
+		},
+		{
+			name:     "PtrHeadInt16String",
+			expected: `{"a":"1"}`,
+			indentExpected: `
+{
+  "a": "1"
+}
+`,
+			data: &struct {
+				A int16 `json:"a,string"`
+			}{A: 1},
+		},
+
+		// PtrHeadInt16Ptr
 		{
 			name:     "PtrHeadInt16Ptr",
 			expected: `{"a":1}`,
@@ -106,6 +270,32 @@ func TestCoverInt16(t *testing.T) {
 				A *int16 `json:"a"`
 			}{A: int16ptr(1)},
 		},
+		{
+			name:     "PtrHeadInt16PtrOmitEmpty",
+			expected: `{"a":1}`,
+			indentExpected: `
+{
+  "a": 1
+}
+`,
+			data: &struct {
+				A *int16 `json:"a,omitempty"`
+			}{A: int16ptr(1)},
+		},
+		{
+			name:     "PtrHeadInt16PtrString",
+			expected: `{"a":"1"}`,
+			indentExpected: `
+{
+  "a": "1"
+}
+`,
+			data: &struct {
+				A *int16 `json:"a,string"`
+			}{A: int16ptr(1)},
+		},
+
+		// PtrHeadInt16PtrNil
 		{
 			name:     "PtrHeadInt16PtrNil",
 			expected: `{"a":null}`,
@@ -118,6 +308,30 @@ func TestCoverInt16(t *testing.T) {
 				A *int16 `json:"a"`
 			}{A: nil},
 		},
+		{
+			name:     "PtrHeadInt16PtrNilOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: &struct {
+				A *int16 `json:"a,omitempty"`
+			}{A: nil},
+		},
+		{
+			name:     "PtrHeadInt16PtrNilString",
+			expected: `{"a":null}`,
+			indentExpected: `
+{
+  "a": null
+}
+`,
+			data: &struct {
+				A *int16 `json:"a,string"`
+			}{A: nil},
+		},
+
+		// PtrHeadInt16Nil
 		{
 			name:     "PtrHeadInt16Nil",
 			expected: `null`,
@@ -128,6 +342,28 @@ null
 				A *int16 `json:"a"`
 			})(nil),
 		},
+		{
+			name:     "PtrHeadInt16NilOmitEmpty",
+			expected: `null`,
+			indentExpected: `
+null
+`,
+			data: (*struct {
+				A *int16 `json:"a,omitempty"`
+			})(nil),
+		},
+		{
+			name:     "PtrHeadInt16NilString",
+			expected: `null`,
+			indentExpected: `
+null
+`,
+			data: (*struct {
+				A *int16 `json:"a,string"`
+			})(nil),
+		},
+
+		// HeadInt16ZeroMultiFields
 		{
 			name:     "HeadInt16ZeroMultiFields",
 			expected: `{"a":0,"b":0}`,
@@ -142,6 +378,33 @@ null
 				B int16 `json:"b"`
 			}{},
 		},
+		{
+			name:     "HeadInt16ZeroMultiFieldsOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: struct {
+				A int16 `json:"a,omitempty"`
+				B int16 `json:"b,omitempty"`
+			}{},
+		},
+		{
+			name:     "HeadInt16ZeroMultiFields",
+			expected: `{"a":"0","b":"0"}`,
+			indentExpected: `
+{
+  "a": "0",
+  "b": "0"
+}
+`,
+			data: struct {
+				A int16 `json:"a,string"`
+				B int16 `json:"b,string"`
+			}{},
+		},
+
+		// HeadInt16MultiFields
 		{
 			name:     "HeadInt16MultiFields",
 			expected: `{"a":1,"b":2}`,
@@ -156,6 +419,36 @@ null
 				B int16 `json:"b"`
 			}{A: 1, B: 2},
 		},
+		{
+			name:     "HeadInt16MultiFieldsOmitEmpty",
+			expected: `{"a":1,"b":2}`,
+			indentExpected: `
+{
+  "a": 1,
+  "b": 2
+}
+`,
+			data: struct {
+				A int16 `json:"a,omitempty"`
+				B int16 `json:"b,omitempty"`
+			}{A: 1, B: 2},
+		},
+		{
+			name:     "HeadInt16MultiFieldsString",
+			expected: `{"a":"1","b":"2"}`,
+			indentExpected: `
+{
+  "a": "1",
+  "b": "2"
+}
+`,
+			data: struct {
+				A int16 `json:"a,string"`
+				B int16 `json:"b,string"`
+			}{A: 1, B: 2},
+		},
+
+		// HeadInt16PtrMultiFields
 		{
 			name:     "HeadInt16PtrMultiFields",
 			expected: `{"a":1,"b":2}`,
@@ -170,6 +463,36 @@ null
 				B *int16 `json:"b"`
 			}{A: int16ptr(1), B: int16ptr(2)},
 		},
+		{
+			name:     "HeadInt16PtrMultiFieldsOmitEmpty",
+			expected: `{"a":1,"b":2}`,
+			indentExpected: `
+{
+  "a": 1,
+  "b": 2
+}
+`,
+			data: struct {
+				A *int16 `json:"a,omitempty"`
+				B *int16 `json:"b,omitempty"`
+			}{A: int16ptr(1), B: int16ptr(2)},
+		},
+		{
+			name:     "HeadInt16PtrMultiFieldsString",
+			expected: `{"a":"1","b":"2"}`,
+			indentExpected: `
+{
+  "a": "1",
+  "b": "2"
+}
+`,
+			data: struct {
+				A *int16 `json:"a,string"`
+				B *int16 `json:"b,string"`
+			}{A: int16ptr(1), B: int16ptr(2)},
+		},
+
+		// HeadInt16PtrNilMultiFields
 		{
 			name:     "HeadInt16PtrNilMultiFields",
 			expected: `{"a":null,"b":null}`,
@@ -184,6 +507,33 @@ null
 				B *int16 `json:"b"`
 			}{A: nil, B: nil},
 		},
+		{
+			name:     "HeadInt16PtrNilMultiFieldsOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: struct {
+				A *int16 `json:"a,omitempty"`
+				B *int16 `json:"b,omitempty"`
+			}{A: nil, B: nil},
+		},
+		{
+			name:     "HeadInt16PtrNilMultiFieldsString",
+			expected: `{"a":null,"b":null}`,
+			indentExpected: `
+{
+  "a": null,
+  "b": null
+}
+`,
+			data: struct {
+				A *int16 `json:"a,string"`
+				B *int16 `json:"b,string"`
+			}{A: nil, B: nil},
+		},
+
+		// PtrHeadInt16ZeroMultiFields
 		{
 			name:     "PtrHeadInt16ZeroMultiFields",
 			expected: `{"a":0,"b":0}`,
@@ -198,6 +548,33 @@ null
 				B int16 `json:"b"`
 			}{},
 		},
+		{
+			name:     "PtrHeadInt16ZeroMultiFieldsOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: &struct {
+				A int16 `json:"a,omitempty"`
+				B int16 `json:"b,omitempty"`
+			}{},
+		},
+		{
+			name:     "PtrHeadInt16ZeroMultiFieldsString",
+			expected: `{"a":"0","b":"0"}`,
+			indentExpected: `
+{
+  "a": "0",
+  "b": "0"
+}
+`,
+			data: &struct {
+				A int16 `json:"a,string"`
+				B int16 `json:"b,string"`
+			}{},
+		},
+
+		// PtrHeadInt16MultiFields
 		{
 			name:     "PtrHeadInt16MultiFields",
 			expected: `{"a":1,"b":2}`,
@@ -212,6 +589,36 @@ null
 				B int16 `json:"b"`
 			}{A: 1, B: 2},
 		},
+		{
+			name:     "PtrHeadInt16MultiFieldsOmitEmpty",
+			expected: `{"a":1,"b":2}`,
+			indentExpected: `
+{
+  "a": 1,
+  "b": 2
+}
+`,
+			data: &struct {
+				A int16 `json:"a,omitempty"`
+				B int16 `json:"b,omitempty"`
+			}{A: 1, B: 2},
+		},
+		{
+			name:     "PtrHeadInt16MultiFieldsString",
+			expected: `{"a":"1","b":"2"}`,
+			indentExpected: `
+{
+  "a": "1",
+  "b": "2"
+}
+`,
+			data: &struct {
+				A int16 `json:"a,string"`
+				B int16 `json:"b,string"`
+			}{A: 1, B: 2},
+		},
+
+		// PtrHeadInt16PtrMultiFields
 		{
 			name:     "PtrHeadInt16PtrMultiFields",
 			expected: `{"a":1,"b":2}`,
@@ -226,6 +633,36 @@ null
 				B *int16 `json:"b"`
 			}{A: int16ptr(1), B: int16ptr(2)},
 		},
+		{
+			name:     "PtrHeadInt16PtrMultiFieldsOmitEmpty",
+			expected: `{"a":1,"b":2}`,
+			indentExpected: `
+{
+  "a": 1,
+  "b": 2
+}
+`,
+			data: &struct {
+				A *int16 `json:"a,omitempty"`
+				B *int16 `json:"b,omitempty"`
+			}{A: int16ptr(1), B: int16ptr(2)},
+		},
+		{
+			name:     "PtrHeadInt16PtrMultiFieldsString",
+			expected: `{"a":"1","b":"2"}`,
+			indentExpected: `
+{
+  "a": "1",
+  "b": "2"
+}
+`,
+			data: &struct {
+				A *int16 `json:"a,string"`
+				B *int16 `json:"b,string"`
+			}{A: int16ptr(1), B: int16ptr(2)},
+		},
+
+		// PtrHeadInt16PtrNilMultiFields
 		{
 			name:     "PtrHeadInt16PtrNilMultiFields",
 			expected: `{"a":null,"b":null}`,
@@ -240,6 +677,33 @@ null
 				B *int16 `json:"b"`
 			}{A: nil, B: nil},
 		},
+		{
+			name:     "PtrHeadInt16PtrNilMultiFieldsOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: &struct {
+				A *int16 `json:"a,omitempty"`
+				B *int16 `json:"b,omitempty"`
+			}{A: nil, B: nil},
+		},
+		{
+			name:     "PtrHeadInt16PtrNilMultiFieldsString",
+			expected: `{"a":null,"b":null}`,
+			indentExpected: `
+{
+  "a": null,
+  "b": null
+}
+`,
+			data: &struct {
+				A *int16 `json:"a,string"`
+				B *int16 `json:"b,string"`
+			}{A: nil, B: nil},
+		},
+
+		// PtrHeadInt16NilMultiFields
 		{
 			name:     "PtrHeadInt16NilMultiFields",
 			expected: `null`,
@@ -251,6 +715,30 @@ null
 				B *int16 `json:"b"`
 			})(nil),
 		},
+		{
+			name:     "PtrHeadInt16NilMultiFieldsOmitEmpty",
+			expected: `null`,
+			indentExpected: `
+null
+`,
+			data: (*struct {
+				A *int16 `json:"a,omitempty"`
+				B *int16 `json:"b,omitempty"`
+			})(nil),
+		},
+		{
+			name:     "PtrHeadInt16NilMultiFieldsString",
+			expected: `null`,
+			indentExpected: `
+null
+`,
+			data: (*struct {
+				A *int16 `json:"a,string"`
+				B *int16 `json:"b,string"`
+			})(nil),
+		},
+
+		// HeadInt16ZeroNotRoot
 		{
 			name:     "HeadInt16ZeroNotRoot",
 			expected: `{"A":{"a":0}}`,
@@ -267,6 +755,38 @@ null
 				}
 			}{},
 		},
+		{
+			name:     "HeadInt16ZeroNotRootOmitEmpty",
+			expected: `{"A":{}}`,
+			indentExpected: `
+{
+  "A": {}
+}
+`,
+			data: struct {
+				A struct {
+					A int16 `json:"a,omitempty"`
+				}
+			}{},
+		},
+		{
+			name:     "HeadInt16ZeroNotRootString",
+			expected: `{"A":{"a":"0"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "0"
+  }
+}
+`,
+			data: struct {
+				A struct {
+					A int16 `json:"a,string"`
+				}
+			}{},
+		},
+
+		// HeadInt16NotRoot
 		{
 			name:     "HeadInt16NotRoot",
 			expected: `{"A":{"a":1}}`,
@@ -285,6 +805,44 @@ null
 				A int16 `json:"a"`
 			}{A: 1}},
 		},
+		{
+			name:     "HeadInt16NotRootOmitEmpty",
+			expected: `{"A":{"a":1}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": 1
+  }
+}
+`,
+			data: struct {
+				A struct {
+					A int16 `json:"a,omitempty"`
+				}
+			}{A: struct {
+				A int16 `json:"a,omitempty"`
+			}{A: 1}},
+		},
+		{
+			name:     "HeadInt16NotRootString",
+			expected: `{"A":{"a":"1"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "1"
+  }
+}
+`,
+			data: struct {
+				A struct {
+					A int16 `json:"a,string"`
+				}
+			}{A: struct {
+				A int16 `json:"a,string"`
+			}{A: 1}},
+		},
+
+		// HeadInt16PtrNotRoot
 		{
 			name:     "HeadInt16PtrNotRoot",
 			expected: `{"A":{"a":1}}`,
@@ -303,6 +861,44 @@ null
 				A *int16 `json:"a"`
 			}{int16ptr(1)}},
 		},
+		{
+			name:     "HeadInt16PtrNotRootOmitEmpty",
+			expected: `{"A":{"a":1}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": 1
+  }
+}
+`,
+			data: struct {
+				A struct {
+					A *int16 `json:"a,omitempty"`
+				}
+			}{A: struct {
+				A *int16 `json:"a,omitempty"`
+			}{int16ptr(1)}},
+		},
+		{
+			name:     "HeadInt16PtrNotRootString",
+			expected: `{"A":{"a":"1"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "1"
+  }
+}
+`,
+			data: struct {
+				A struct {
+					A *int16 `json:"a,string"`
+				}
+			}{A: struct {
+				A *int16 `json:"a,string"`
+			}{int16ptr(1)}},
+		},
+
+		// HeadInt16PtrNilNotRoot
 		{
 			name:     "HeadInt16PtrNilNotRoot",
 			expected: `{"A":{"a":null}}`,
@@ -319,6 +915,38 @@ null
 				}
 			}{},
 		},
+		{
+			name:     "HeadInt16PtrNilNotRootOmitEmpty",
+			expected: `{"A":{}}`,
+			indentExpected: `
+{
+  "A": {}
+}
+`,
+			data: struct {
+				A struct {
+					A *int16 `json:"a,omitempty"`
+				}
+			}{},
+		},
+		{
+			name:     "HeadInt16PtrNilNotRootString",
+			expected: `{"A":{"a":null}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": null
+  }
+}
+`,
+			data: struct {
+				A struct {
+					A *int16 `json:"a,string"`
+				}
+			}{},
+		},
+
+		// PtrHeadInt16ZeroNotRoot
 		{
 			name:     "PtrHeadInt16ZeroNotRoot",
 			expected: `{"A":{"a":0}}`,
@@ -337,6 +965,42 @@ null
 				A int16 `json:"a"`
 			})},
 		},
+		{
+			name:     "PtrHeadInt16ZeroNotRootOmitEmpty",
+			expected: `{"A":{}}`,
+			indentExpected: `
+{
+  "A": {}
+}
+`,
+			data: struct {
+				A *struct {
+					A int16 `json:"a,omitempty"`
+				}
+			}{A: new(struct {
+				A int16 `json:"a,omitempty"`
+			})},
+		},
+		{
+			name:     "PtrHeadInt16ZeroNotRootString",
+			expected: `{"A":{"a":"0"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "0"
+  }
+}
+`,
+			data: struct {
+				A *struct {
+					A int16 `json:"a,string"`
+				}
+			}{A: new(struct {
+				A int16 `json:"a,string"`
+			})},
+		},
+
+		// PtrHeadInt16NotRoot
 		{
 			name:     "PtrHeadInt16NotRoot",
 			expected: `{"A":{"a":1}}`,
@@ -355,6 +1019,44 @@ null
 				A int16 `json:"a"`
 			}{A: 1})},
 		},
+		{
+			name:     "PtrHeadInt16NotRootOmitEmpty",
+			expected: `{"A":{"a":1}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": 1
+  }
+}
+`,
+			data: struct {
+				A *struct {
+					A int16 `json:"a,omitempty"`
+				}
+			}{A: &(struct {
+				A int16 `json:"a,omitempty"`
+			}{A: 1})},
+		},
+		{
+			name:     "PtrHeadInt16NotRootString",
+			expected: `{"A":{"a":"1"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "1"
+  }
+}
+`,
+			data: struct {
+				A *struct {
+					A int16 `json:"a,string"`
+				}
+			}{A: &(struct {
+				A int16 `json:"a,string"`
+			}{A: 1})},
+		},
+
+		// PtrHeadInt16PtrNotRoot
 		{
 			name:     "PtrHeadInt16PtrNotRoot",
 			expected: `{"A":{"a":1}}`,
@@ -373,6 +1075,44 @@ null
 				A *int16 `json:"a"`
 			}{A: int16ptr(1)})},
 		},
+		{
+			name:     "PtrHeadInt16PtrNotRootOmitEmpty",
+			expected: `{"A":{"a":1}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": 1
+  }
+}
+`,
+			data: struct {
+				A *struct {
+					A *int16 `json:"a,omitempty"`
+				}
+			}{A: &(struct {
+				A *int16 `json:"a,omitempty"`
+			}{A: int16ptr(1)})},
+		},
+		{
+			name:     "PtrHeadInt16PtrNotRootString",
+			expected: `{"A":{"a":"1"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "1"
+  }
+}
+`,
+			data: struct {
+				A *struct {
+					A *int16 `json:"a,string"`
+				}
+			}{A: &(struct {
+				A *int16 `json:"a,string"`
+			}{A: int16ptr(1)})},
+		},
+
+		// PtrHeadInt16PtrNilNotRoot
 		{
 			name:     "PtrHeadInt16PtrNilNotRoot",
 			expected: `{"A":{"a":null}}`,
@@ -391,6 +1131,42 @@ null
 				A *int16 `json:"a"`
 			}{A: nil})},
 		},
+		{
+			name:     "PtrHeadInt16PtrNilNotRootOmitEmpty",
+			expected: `{"A":{}}`,
+			indentExpected: `
+{
+  "A": {}
+}
+`,
+			data: struct {
+				A *struct {
+					A *int16 `json:"a,omitempty"`
+				}
+			}{A: &(struct {
+				A *int16 `json:"a,omitempty"`
+			}{A: nil})},
+		},
+		{
+			name:     "PtrHeadInt16PtrNilNotRootString",
+			expected: `{"A":{"a":null}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": null
+  }
+}
+`,
+			data: struct {
+				A *struct {
+					A *int16 `json:"a,string"`
+				}
+			}{A: &(struct {
+				A *int16 `json:"a,string"`
+			}{A: nil})},
+		},
+
+		// PtrHeadInt16NilNotRoot
 		{
 			name:     "PtrHeadInt16NilNotRoot",
 			expected: `{"A":null}`,
@@ -405,6 +1181,34 @@ null
 				}
 			}{A: nil},
 		},
+		{
+			name:     "PtrHeadInt16NilNotRootOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: struct {
+				A *struct {
+					A *int16 `json:"a,omitempty"`
+				} `json:",omitempty"`
+			}{A: nil},
+		},
+		{
+			name:     "PtrHeadInt16NilNotRootString",
+			expected: `{"A":null}`,
+			indentExpected: `
+{
+  "A": null
+}
+`,
+			data: struct {
+				A *struct {
+					A *int16 `json:"a,string"`
+				} `json:",string"`
+			}{A: nil},
+		},
+
+		// HeadInt16ZeroMultiFieldsNotRoot
 		{
 			name:     "HeadInt16ZeroMultiFieldsNotRoot",
 			expected: `{"A":{"a":0},"B":{"b":0}}`,
@@ -427,6 +1231,48 @@ null
 				}
 			}{},
 		},
+		{
+			name:     "HeadInt16ZeroMultiFieldsNotRootOmitEmpty",
+			expected: `{"A":{},"B":{}}`,
+			indentExpected: `
+{
+  "A": {},
+  "B": {}
+}
+`,
+			data: struct {
+				A struct {
+					A int16 `json:"a,omitempty"`
+				}
+				B struct {
+					B int16 `json:"b,omitempty"`
+				}
+			}{},
+		},
+		{
+			name:     "HeadInt16ZeroMultiFieldsNotRootString",
+			expected: `{"A":{"a":"0"},"B":{"b":"0"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "0"
+  },
+  "B": {
+    "b": "0"
+  }
+}
+`,
+			data: struct {
+				A struct {
+					A int16 `json:"a,string"`
+				}
+				B struct {
+					B int16 `json:"b,string"`
+				}
+			}{},
+		},
+
+		// HeadInt16MultiFieldsNotRoot
 		{
 			name:     "HeadInt16MultiFieldsNotRoot",
 			expected: `{"A":{"a":1},"B":{"b":2}}`,
@@ -453,6 +1299,60 @@ null
 				B int16 `json:"b"`
 			}{B: 2}},
 		},
+		{
+			name:     "HeadInt16MultiFieldsNotRootOmitEmpty",
+			expected: `{"A":{"a":1},"B":{"b":2}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": 1
+  },
+  "B": {
+    "b": 2
+  }
+}
+`,
+			data: struct {
+				A struct {
+					A int16 `json:"a,omitempty"`
+				}
+				B struct {
+					B int16 `json:"b,omitempty"`
+				}
+			}{A: struct {
+				A int16 `json:"a,omitempty"`
+			}{A: 1}, B: struct {
+				B int16 `json:"b,omitempty"`
+			}{B: 2}},
+		},
+		{
+			name:     "HeadInt16MultiFieldsNotRootString",
+			expected: `{"A":{"a":"1"},"B":{"b":"2"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "1"
+  },
+  "B": {
+    "b": "2"
+  }
+}
+`,
+			data: struct {
+				A struct {
+					A int16 `json:"a,string"`
+				}
+				B struct {
+					B int16 `json:"b,string"`
+				}
+			}{A: struct {
+				A int16 `json:"a,string"`
+			}{A: 1}, B: struct {
+				B int16 `json:"b,string"`
+			}{B: 2}},
+		},
+
+		// HeadInt16PtrMultiFieldsNotRoot
 		{
 			name:     "HeadInt16PtrMultiFieldsNotRoot",
 			expected: `{"A":{"a":1},"B":{"b":2}}`,
@@ -479,6 +1379,60 @@ null
 				B *int16 `json:"b"`
 			}{B: int16ptr(2)}},
 		},
+		{
+			name:     "HeadInt16PtrMultiFieldsNotRootOmitEmpty",
+			expected: `{"A":{"a":1},"B":{"b":2}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": 1
+  },
+  "B": {
+    "b": 2
+  }
+}
+`,
+			data: struct {
+				A struct {
+					A *int16 `json:"a,omitempty"`
+				}
+				B struct {
+					B *int16 `json:"b,omitempty"`
+				}
+			}{A: struct {
+				A *int16 `json:"a,omitempty"`
+			}{A: int16ptr(1)}, B: struct {
+				B *int16 `json:"b,omitempty"`
+			}{B: int16ptr(2)}},
+		},
+		{
+			name:     "HeadInt16PtrMultiFieldsNotRootString",
+			expected: `{"A":{"a":"1"},"B":{"b":"2"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "1"
+  },
+  "B": {
+    "b": "2"
+  }
+}
+`,
+			data: struct {
+				A struct {
+					A *int16 `json:"a,string"`
+				}
+				B struct {
+					B *int16 `json:"b,string"`
+				}
+			}{A: struct {
+				A *int16 `json:"a,string"`
+			}{A: int16ptr(1)}, B: struct {
+				B *int16 `json:"b,string"`
+			}{B: int16ptr(2)}},
+		},
+
+		// HeadInt16PtrNilMultiFieldsNotRoot
 		{
 			name:     "HeadInt16PtrNilMultiFieldsNotRoot",
 			expected: `{"A":{"a":null},"B":{"b":null}}`,
@@ -505,6 +1459,56 @@ null
 				B *int16 `json:"b"`
 			}{B: nil}},
 		},
+		{
+			name:     "HeadInt16PtrNilMultiFieldsNotRootOmitEmpty",
+			expected: `{"A":{},"B":{}}`,
+			indentExpected: `
+{
+  "A": {},
+  "B": {}
+}
+`,
+			data: struct {
+				A struct {
+					A *int16 `json:"a,omitempty"`
+				}
+				B struct {
+					B *int16 `json:"b,omitempty"`
+				}
+			}{A: struct {
+				A *int16 `json:"a,omitempty"`
+			}{A: nil}, B: struct {
+				B *int16 `json:"b,omitempty"`
+			}{B: nil}},
+		},
+		{
+			name:     "HeadInt16PtrNilMultiFieldsNotRootString",
+			expected: `{"A":{"a":null},"B":{"b":null}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": null
+  },
+  "B": {
+    "b": null
+  }
+}
+`,
+			data: struct {
+				A struct {
+					A *int16 `json:"a,string"`
+				}
+				B struct {
+					B *int16 `json:"b,string"`
+				}
+			}{A: struct {
+				A *int16 `json:"a,string"`
+			}{A: nil}, B: struct {
+				B *int16 `json:"b,string"`
+			}{B: nil}},
+		},
+
+		// PtrHeadInt16ZeroMultiFieldsNotRoot
 		{
 			name:     "PtrHeadInt16ZeroMultiFieldsNotRoot",
 			expected: `{"A":{"a":0},"B":{"b":0}}`,
@@ -527,6 +1531,48 @@ null
 				}
 			}{},
 		},
+		{
+			name:     "PtrHeadInt16ZeroMultiFieldsNotRootOmitEmpty",
+			expected: `{"A":{},"B":{}}`,
+			indentExpected: `
+{
+  "A": {},
+  "B": {}
+}
+`,
+			data: &struct {
+				A struct {
+					A int16 `json:"a,omitempty"`
+				}
+				B struct {
+					B int16 `json:"b,omitempty"`
+				}
+			}{},
+		},
+		{
+			name:     "PtrHeadInt16ZeroMultiFieldsNotRootString",
+			expected: `{"A":{"a":"0"},"B":{"b":"0"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "0"
+  },
+  "B": {
+    "b": "0"
+  }
+}
+`,
+			data: &struct {
+				A struct {
+					A int16 `json:"a,string"`
+				}
+				B struct {
+					B int16 `json:"b,string"`
+				}
+			}{},
+		},
+
+		// PtrHeadInt16MultiFieldsNotRoot
 		{
 			name:     "PtrHeadInt16MultiFieldsNotRoot",
 			expected: `{"A":{"a":1},"B":{"b":2}}`,
@@ -553,6 +1599,60 @@ null
 				B int16 `json:"b"`
 			}{B: 2}},
 		},
+		{
+			name:     "PtrHeadInt16MultiFieldsNotRootOmitEmpty",
+			expected: `{"A":{"a":1},"B":{"b":2}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": 1
+  },
+  "B": {
+    "b": 2
+  }
+}
+`,
+			data: &struct {
+				A struct {
+					A int16 `json:"a,omitempty"`
+				}
+				B struct {
+					B int16 `json:"b,omitempty"`
+				}
+			}{A: struct {
+				A int16 `json:"a,omitempty"`
+			}{A: 1}, B: struct {
+				B int16 `json:"b,omitempty"`
+			}{B: 2}},
+		},
+		{
+			name:     "PtrHeadInt16MultiFieldsNotRootString",
+			expected: `{"A":{"a":"1"},"B":{"b":"2"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "1"
+  },
+  "B": {
+    "b": "2"
+  }
+}
+`,
+			data: &struct {
+				A struct {
+					A int16 `json:"a,string"`
+				}
+				B struct {
+					B int16 `json:"b,string"`
+				}
+			}{A: struct {
+				A int16 `json:"a,string"`
+			}{A: 1}, B: struct {
+				B int16 `json:"b,string"`
+			}{B: 2}},
+		},
+
+		// PtrHeadInt16PtrMultiFieldsNotRoot
 		{
 			name:     "PtrHeadInt16PtrMultiFieldsNotRoot",
 			expected: `{"A":{"a":1},"B":{"b":2}}`,
@@ -579,6 +1679,60 @@ null
 				B *int16 `json:"b"`
 			}{B: int16ptr(2)})},
 		},
+		{
+			name:     "PtrHeadInt16PtrMultiFieldsNotRootOmitEmpty",
+			expected: `{"A":{"a":1},"B":{"b":2}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": 1
+  },
+  "B": {
+    "b": 2
+  }
+}
+`,
+			data: &struct {
+				A *struct {
+					A *int16 `json:"a,omitempty"`
+				}
+				B *struct {
+					B *int16 `json:"b,omitempty"`
+				}
+			}{A: &(struct {
+				A *int16 `json:"a,omitempty"`
+			}{A: int16ptr(1)}), B: &(struct {
+				B *int16 `json:"b,omitempty"`
+			}{B: int16ptr(2)})},
+		},
+		{
+			name:     "PtrHeadInt16PtrMultiFieldsNotRootString",
+			expected: `{"A":{"a":"1"},"B":{"b":"2"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "1"
+  },
+  "B": {
+    "b": "2"
+  }
+}
+`,
+			data: &struct {
+				A *struct {
+					A *int16 `json:"a,string"`
+				}
+				B *struct {
+					B *int16 `json:"b,string"`
+				}
+			}{A: &(struct {
+				A *int16 `json:"a,string"`
+			}{A: int16ptr(1)}), B: &(struct {
+				B *int16 `json:"b,string"`
+			}{B: int16ptr(2)})},
+		},
+
+		// PtrHeadInt16PtrNilMultiFieldsNotRoot
 		{
 			name:     "PtrHeadInt16PtrNilMultiFieldsNotRoot",
 			expected: `{"A":null,"B":null}`,
@@ -597,6 +1751,41 @@ null
 				}
 			}{A: nil, B: nil},
 		},
+		{
+			name:     "PtrHeadInt16PtrNilMultiFieldsNotRootOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: &struct {
+				A *struct {
+					A *int16 `json:"a,omitempty"`
+				} `json:",omitempty"`
+				B *struct {
+					B *int16 `json:"b,omitempty"`
+				} `json:",omitempty"`
+			}{A: nil, B: nil},
+		},
+		{
+			name:     "PtrHeadInt16PtrNilMultiFieldsNotRootString",
+			expected: `{"A":null,"B":null}`,
+			indentExpected: `
+{
+  "A": null,
+  "B": null
+}
+`,
+			data: &struct {
+				A *struct {
+					A *int16 `json:"a,string"`
+				} `json:",string"`
+				B *struct {
+					B *int16 `json:"b,string"`
+				} `json:",string"`
+			}{A: nil, B: nil},
+		},
+
+		// PtrHeadInt16NilMultiFieldsNotRoot
 		{
 			name:     "PtrHeadInt16NilMultiFieldsNotRoot",
 			expected: `null`,
@@ -612,6 +1801,38 @@ null
 				}
 			})(nil),
 		},
+		{
+			name:     "PtrHeadInt16NilMultiFieldsNotRootOmitEmpty",
+			expected: `null`,
+			indentExpected: `
+null
+`,
+			data: (*struct {
+				A *struct {
+					A *int16 `json:"a,omitempty"`
+				}
+				B *struct {
+					B *int16 `json:"b,omitempty"`
+				}
+			})(nil),
+		},
+		{
+			name:     "PtrHeadInt16NilMultiFieldsNotRootString",
+			expected: `null`,
+			indentExpected: `
+null
+`,
+			data: (*struct {
+				A *struct {
+					A *int16 `json:"a,string"`
+				}
+				B *struct {
+					B *int16 `json:"b,string"`
+				}
+			})(nil),
+		},
+
+		// PtrHeadInt16DoubleMultiFieldsNotRoot
 		{
 			name:     "PtrHeadInt16DoubleMultiFieldsNotRoot",
 			expected: `{"A":{"a":1,"b":2},"B":{"a":3,"b":4}}`,
@@ -644,6 +1865,72 @@ null
 				B int16 `json:"b"`
 			}{A: 3, B: 4})},
 		},
+		{
+			name:     "PtrHeadInt16DoubleMultiFieldsNotRootOmitEmpty",
+			expected: `{"A":{"a":1,"b":2},"B":{"a":3,"b":4}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": 1,
+    "b": 2
+  },
+  "B": {
+    "a": 3,
+    "b": 4
+  }
+}
+`,
+			data: &struct {
+				A *struct {
+					A int16 `json:"a,omitempty"`
+					B int16 `json:"b,omitempty"`
+				}
+				B *struct {
+					A int16 `json:"a,omitempty"`
+					B int16 `json:"b,omitempty"`
+				}
+			}{A: &(struct {
+				A int16 `json:"a,omitempty"`
+				B int16 `json:"b,omitempty"`
+			}{A: 1, B: 2}), B: &(struct {
+				A int16 `json:"a,omitempty"`
+				B int16 `json:"b,omitempty"`
+			}{A: 3, B: 4})},
+		},
+		{
+			name:     "PtrHeadInt16DoubleMultiFieldsNotRootString",
+			expected: `{"A":{"a":"1","b":"2"},"B":{"a":"3","b":"4"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "1",
+    "b": "2"
+  },
+  "B": {
+    "a": "3",
+    "b": "4"
+  }
+}
+`,
+			data: &struct {
+				A *struct {
+					A int16 `json:"a,string"`
+					B int16 `json:"b,string"`
+				}
+				B *struct {
+					A int16 `json:"a,string"`
+					B int16 `json:"b,string"`
+				}
+			}{A: &(struct {
+				A int16 `json:"a,string"`
+				B int16 `json:"b,string"`
+			}{A: 1, B: 2}), B: &(struct {
+				A int16 `json:"a,string"`
+				B int16 `json:"b,string"`
+			}{A: 3, B: 4})},
+		},
+
+		// PtrHeadInt16NilDoubleMultiFieldsNotRoot
 		{
 			name:     "PtrHeadInt16NilDoubleMultiFieldsNotRoot",
 			expected: `{"A":null,"B":null}`,
@@ -664,6 +1951,45 @@ null
 				}
 			}{A: nil, B: nil},
 		},
+		{
+			name:     "PtrHeadInt16NilDoubleMultiFieldsNotRootOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: &struct {
+				A *struct {
+					A int16 `json:"a,omitempty"`
+					B int16 `json:"b,omitempty"`
+				} `json:",omitempty"`
+				B *struct {
+					A int16 `json:"a,omitempty"`
+					B int16 `json:"b,omitempty"`
+				} `json:",omitempty"`
+			}{A: nil, B: nil},
+		},
+		{
+			name:     "PtrHeadInt16NilDoubleMultiFieldsNotRootString",
+			expected: `{"A":null,"B":null}`,
+			indentExpected: `
+{
+  "A": null,
+  "B": null
+}
+`,
+			data: &struct {
+				A *struct {
+					A int16 `json:"a,string"`
+					B int16 `json:"b,string"`
+				}
+				B *struct {
+					A int16 `json:"a,string"`
+					B int16 `json:"b,string"`
+				}
+			}{A: nil, B: nil},
+		},
+
+		// PtrHeadInt16NilDoubleMultiFieldsNotRoot
 		{
 			name:     "PtrHeadInt16NilDoubleMultiFieldsNotRoot",
 			expected: `null`,
@@ -681,6 +2007,42 @@ null
 				}
 			})(nil),
 		},
+		{
+			name:     "PtrHeadInt16NilDoubleMultiFieldsNotRootOmitEmpty",
+			expected: `null`,
+			indentExpected: `
+null
+`,
+			data: (*struct {
+				A *struct {
+					A int16 `json:"a,omitempty"`
+					B int16 `json:"b,omitempty"`
+				}
+				B *struct {
+					A int16 `json:"a,omitempty"`
+					B int16 `json:"b,omitempty"`
+				}
+			})(nil),
+		},
+		{
+			name:     "PtrHeadInt16NilDoubleMultiFieldsNotRootString",
+			expected: `null`,
+			indentExpected: `
+null
+`,
+			data: (*struct {
+				A *struct {
+					A int16 `json:"a,string"`
+					B int16 `json:"b,string"`
+				}
+				B *struct {
+					A int16 `json:"a,string"`
+					B int16 `json:"b,string"`
+				}
+			})(nil),
+		},
+
+		// PtrHeadInt16PtrDoubleMultiFieldsNotRoot
 		{
 			name:     "PtrHeadInt16PtrDoubleMultiFieldsNotRoot",
 			expected: `{"A":{"a":1,"b":2},"B":{"a":3,"b":4}}`,
@@ -713,6 +2075,72 @@ null
 				B *int16 `json:"b"`
 			}{A: int16ptr(3), B: int16ptr(4)})},
 		},
+		{
+			name:     "PtrHeadInt16PtrDoubleMultiFieldsNotRootOmitEmpty",
+			expected: `{"A":{"a":1,"b":2},"B":{"a":3,"b":4}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": 1,
+    "b": 2
+  },
+  "B": {
+    "a": 3,
+    "b": 4
+  }
+}
+`,
+			data: &struct {
+				A *struct {
+					A *int16 `json:"a,omitempty"`
+					B *int16 `json:"b,omitempty"`
+				}
+				B *struct {
+					A *int16 `json:"a,omitempty"`
+					B *int16 `json:"b,omitempty"`
+				}
+			}{A: &(struct {
+				A *int16 `json:"a,omitempty"`
+				B *int16 `json:"b,omitempty"`
+			}{A: int16ptr(1), B: int16ptr(2)}), B: &(struct {
+				A *int16 `json:"a,omitempty"`
+				B *int16 `json:"b,omitempty"`
+			}{A: int16ptr(3), B: int16ptr(4)})},
+		},
+		{
+			name:     "PtrHeadInt16PtrDoubleMultiFieldsNotRootString",
+			expected: `{"A":{"a":"1","b":"2"},"B":{"a":"3","b":"4"}}`,
+			indentExpected: `
+{
+  "A": {
+    "a": "1",
+    "b": "2"
+  },
+  "B": {
+    "a": "3",
+    "b": "4"
+  }
+}
+`,
+			data: &struct {
+				A *struct {
+					A *int16 `json:"a,string"`
+					B *int16 `json:"b,string"`
+				}
+				B *struct {
+					A *int16 `json:"a,string"`
+					B *int16 `json:"b,string"`
+				}
+			}{A: &(struct {
+				A *int16 `json:"a,string"`
+				B *int16 `json:"b,string"`
+			}{A: int16ptr(1), B: int16ptr(2)}), B: &(struct {
+				A *int16 `json:"a,string"`
+				B *int16 `json:"b,string"`
+			}{A: int16ptr(3), B: int16ptr(4)})},
+		},
+
+		// PtrHeadInt16PtrNilDoubleMultiFieldsNotRoot
 		{
 			name:     "PtrHeadInt16PtrNilDoubleMultiFieldsNotRoot",
 			expected: `{"A":null,"B":null}`,
@@ -733,6 +2161,45 @@ null
 				}
 			}{A: nil, B: nil},
 		},
+		{
+			name:     "PtrHeadInt16PtrNilDoubleMultiFieldsNotRootOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: &struct {
+				A *struct {
+					A *int16 `json:"a,omitempty"`
+					B *int16 `json:"b,omitempty"`
+				} `json:",omitempty"`
+				B *struct {
+					A *int16 `json:"a,omitempty"`
+					B *int16 `json:"b,omitempty"`
+				} `json:",omitempty"`
+			}{A: nil, B: nil},
+		},
+		{
+			name:     "PtrHeadInt16PtrNilDoubleMultiFieldsNotRootString",
+			expected: `{"A":null,"B":null}`,
+			indentExpected: `
+{
+  "A": null,
+  "B": null
+}
+`,
+			data: &struct {
+				A *struct {
+					A *int16 `json:"a,string"`
+					B *int16 `json:"b,string"`
+				}
+				B *struct {
+					A *int16 `json:"a,string"`
+					B *int16 `json:"b,string"`
+				}
+			}{A: nil, B: nil},
+		},
+
+		// PtrHeadInt16PtrNilDoubleMultiFieldsNotRoot
 		{
 			name:     "PtrHeadInt16PtrNilDoubleMultiFieldsNotRoot",
 			expected: `null`,
@@ -750,6 +2217,42 @@ null
 				}
 			})(nil),
 		},
+		{
+			name:     "PtrHeadInt16PtrNilDoubleMultiFieldsNotRootOmitEmpty",
+			expected: `null`,
+			indentExpected: `
+null
+`,
+			data: (*struct {
+				A *struct {
+					A *int16 `json:"a,omitempty"`
+					B *int16 `json:"b,omitempty"`
+				}
+				B *struct {
+					A *int16 `json:"a,omitempty"`
+					B *int16 `json:"b,omitempty"`
+				}
+			})(nil),
+		},
+		{
+			name:     "PtrHeadInt16PtrNilDoubleMultiFieldsNotRootString",
+			expected: `null`,
+			indentExpected: `
+null
+`,
+			data: (*struct {
+				A *struct {
+					A *int16 `json:"a,string"`
+					B *int16 `json:"b,string"`
+				}
+				B *struct {
+					A *int16 `json:"a,string"`
+					B *int16 `json:"b,string"`
+				}
+			})(nil),
+		},
+
+		// AnonymousHeadInt16
 		{
 			name:     "AnonymousHeadInt16",
 			expected: `{"a":1,"b":2}`,
@@ -767,6 +2270,42 @@ null
 				B:           2,
 			},
 		},
+		{
+			name:     "AnonymousHeadInt16OmitEmpty",
+			expected: `{"a":1,"b":2}`,
+			indentExpected: `
+{
+  "a": 1,
+  "b": 2
+}
+`,
+			data: struct {
+				structInt16OmitEmpty
+				B int16 `json:"b,omitempty"`
+			}{
+				structInt16OmitEmpty: structInt16OmitEmpty{A: 1},
+				B:                    2,
+			},
+		},
+		{
+			name:     "AnonymousHeadInt16String",
+			expected: `{"a":"1","b":"2"}`,
+			indentExpected: `
+{
+  "a": "1",
+  "b": "2"
+}
+`,
+			data: struct {
+				structInt16String
+				B int16 `json:"b,string"`
+			}{
+				structInt16String: structInt16String{A: 1},
+				B:                 2,
+			},
+		},
+
+		// PtrAnonymousHeadInt16
 		{
 			name:     "PtrAnonymousHeadInt16",
 			expected: `{"a":1,"b":2}`,
@@ -784,6 +2323,42 @@ null
 				B:           2,
 			},
 		},
+		{
+			name:     "PtrAnonymousHeadInt16OmitEmpty",
+			expected: `{"a":1,"b":2}`,
+			indentExpected: `
+{
+  "a": 1,
+  "b": 2
+}
+`,
+			data: struct {
+				*structInt16OmitEmpty
+				B int16 `json:"b,omitempty"`
+			}{
+				structInt16OmitEmpty: &structInt16OmitEmpty{A: 1},
+				B:                    2,
+			},
+		},
+		{
+			name:     "PtrAnonymousHeadInt16String",
+			expected: `{"a":"1","b":"2"}`,
+			indentExpected: `
+{
+  "a": "1",
+  "b": "2"
+}
+`,
+			data: struct {
+				*structInt16String
+				B int16 `json:"b,string"`
+			}{
+				structInt16String: &structInt16String{A: 1},
+				B:                 2,
+			},
+		},
+
+		// NilPtrAnonymousHeadInt16
 		{
 			name:     "NilPtrAnonymousHeadInt16",
 			expected: `{"b":2}`,
@@ -800,6 +2375,40 @@ null
 				B:           2,
 			},
 		},
+		{
+			name:     "NilPtrAnonymousHeadInt16OmitEmpty",
+			expected: `{"b":2}`,
+			indentExpected: `
+{
+  "b": 2
+}
+`,
+			data: struct {
+				*structInt16OmitEmpty
+				B int16 `json:"b,omitempty"`
+			}{
+				structInt16OmitEmpty: nil,
+				B:                    2,
+			},
+		},
+		{
+			name:     "NilPtrAnonymousHeadInt16String",
+			expected: `{"b":"2"}`,
+			indentExpected: `
+{
+  "b": "2"
+}
+`,
+			data: struct {
+				*structInt16String
+				B int16 `json:"b,string"`
+			}{
+				structInt16String: nil,
+				B:                 2,
+			},
+		},
+
+		// AnonymousHeadInt16Ptr
 		{
 			name:     "AnonymousHeadInt16Ptr",
 			expected: `{"a":1,"b":2}`,
@@ -817,6 +2426,42 @@ null
 				B:              int16ptr(2),
 			},
 		},
+		{
+			name:     "AnonymousHeadInt16PtrOmitEmpty",
+			expected: `{"a":1,"b":2}`,
+			indentExpected: `
+{
+  "a": 1,
+  "b": 2
+}
+`,
+			data: struct {
+				structInt16PtrOmitEmpty
+				B *int16 `json:"b,omitempty"`
+			}{
+				structInt16PtrOmitEmpty: structInt16PtrOmitEmpty{A: int16ptr(1)},
+				B:                       int16ptr(2),
+			},
+		},
+		{
+			name:     "AnonymousHeadInt16PtrString",
+			expected: `{"a":"1","b":"2"}`,
+			indentExpected: `
+{
+  "a": "1",
+  "b": "2"
+}
+`,
+			data: struct {
+				structInt16PtrString
+				B *int16 `json:"b,string"`
+			}{
+				structInt16PtrString: structInt16PtrString{A: int16ptr(1)},
+				B:                    int16ptr(2),
+			},
+		},
+
+		// AnonymousHeadInt16PtrNil
 		{
 			name:     "AnonymousHeadInt16PtrNil",
 			expected: `{"a":null,"b":2}`,
@@ -834,6 +2479,41 @@ null
 				B:              int16ptr(2),
 			},
 		},
+		{
+			name:     "AnonymousHeadInt16PtrNilOmitEmpty",
+			expected: `{"b":2}`,
+			indentExpected: `
+{
+  "b": 2
+}
+`,
+			data: struct {
+				structInt16PtrOmitEmpty
+				B *int16 `json:"b,omitempty"`
+			}{
+				structInt16PtrOmitEmpty: structInt16PtrOmitEmpty{A: nil},
+				B:                       int16ptr(2),
+			},
+		},
+		{
+			name:     "AnonymousHeadInt16PtrNilString",
+			expected: `{"a":null,"b":"2"}`,
+			indentExpected: `
+{
+  "a": null,
+  "b": "2"
+}
+`,
+			data: struct {
+				structInt16PtrString
+				B *int16 `json:"b,string"`
+			}{
+				structInt16PtrString: structInt16PtrString{A: nil},
+				B:                    int16ptr(2),
+			},
+		},
+
+		// PtrAnonymousHeadInt16Ptr
 		{
 			name:     "PtrAnonymousHeadInt16Ptr",
 			expected: `{"a":1,"b":2}`,
@@ -851,6 +2531,42 @@ null
 				B:              int16ptr(2),
 			},
 		},
+		{
+			name:     "PtrAnonymousHeadInt16PtrOmitEmpty",
+			expected: `{"a":1,"b":2}`,
+			indentExpected: `
+{
+  "a": 1,
+  "b": 2
+}
+`,
+			data: struct {
+				*structInt16PtrOmitEmpty
+				B *int16 `json:"b,omitempty"`
+			}{
+				structInt16PtrOmitEmpty: &structInt16PtrOmitEmpty{A: int16ptr(1)},
+				B:                       int16ptr(2),
+			},
+		},
+		{
+			name:     "PtrAnonymousHeadInt16PtrString",
+			expected: `{"a":"1","b":"2"}`,
+			indentExpected: `
+{
+  "a": "1",
+  "b": "2"
+}
+`,
+			data: struct {
+				*structInt16PtrString
+				B *int16 `json:"b,string"`
+			}{
+				structInt16PtrString: &structInt16PtrString{A: int16ptr(1)},
+				B:                    int16ptr(2),
+			},
+		},
+
+		// NilPtrAnonymousHeadInt16Ptr
 		{
 			name:     "NilPtrAnonymousHeadInt16Ptr",
 			expected: `{"b":2}`,
@@ -867,6 +2583,40 @@ null
 				B:              int16ptr(2),
 			},
 		},
+		{
+			name:     "NilPtrAnonymousHeadInt16PtrOmitEmpty",
+			expected: `{"b":2}`,
+			indentExpected: `
+{
+  "b": 2
+}
+`,
+			data: struct {
+				*structInt16PtrOmitEmpty
+				B *int16 `json:"b,omitempty"`
+			}{
+				structInt16PtrOmitEmpty: nil,
+				B:                       int16ptr(2),
+			},
+		},
+		{
+			name:     "NilPtrAnonymousHeadInt16PtrString",
+			expected: `{"b":"2"}`,
+			indentExpected: `
+{
+  "b": "2"
+}
+`,
+			data: struct {
+				*structInt16PtrString
+				B *int16 `json:"b,string"`
+			}{
+				structInt16PtrString: nil,
+				B:                    int16ptr(2),
+			},
+		},
+
+		// AnonymousHeadInt16Only
 		{
 			name:     "AnonymousHeadInt16Only",
 			expected: `{"a":1}`,
@@ -881,6 +2631,36 @@ null
 				structInt16: structInt16{A: 1},
 			},
 		},
+		{
+			name:     "AnonymousHeadInt16OnlyOmitEmpty",
+			expected: `{"a":1}`,
+			indentExpected: `
+{
+  "a": 1
+}
+`,
+			data: struct {
+				structInt16OmitEmpty
+			}{
+				structInt16OmitEmpty: structInt16OmitEmpty{A: 1},
+			},
+		},
+		{
+			name:     "AnonymousHeadInt16OnlyString",
+			expected: `{"a":"1"}`,
+			indentExpected: `
+{
+  "a": "1"
+}
+`,
+			data: struct {
+				structInt16String
+			}{
+				structInt16String: structInt16String{A: 1},
+			},
+		},
+
+		// PtrAnonymousHeadInt16Only
 		{
 			name:     "PtrAnonymousHeadInt16Only",
 			expected: `{"a":1}`,
@@ -895,6 +2675,36 @@ null
 				structInt16: &structInt16{A: 1},
 			},
 		},
+		{
+			name:     "PtrAnonymousHeadInt16OnlyOmitEmpty",
+			expected: `{"a":1}`,
+			indentExpected: `
+{
+  "a": 1
+}
+`,
+			data: struct {
+				*structInt16OmitEmpty
+			}{
+				structInt16OmitEmpty: &structInt16OmitEmpty{A: 1},
+			},
+		},
+		{
+			name:     "PtrAnonymousHeadInt16OnlyString",
+			expected: `{"a":"1"}`,
+			indentExpected: `
+{
+  "a": "1"
+}
+`,
+			data: struct {
+				*structInt16String
+			}{
+				structInt16String: &structInt16String{A: 1},
+			},
+		},
+
+		// NilPtrAnonymousHeadInt16Only
 		{
 			name:     "NilPtrAnonymousHeadInt16Only",
 			expected: `{}`,
@@ -907,6 +2717,32 @@ null
 				structInt16: nil,
 			},
 		},
+		{
+			name:     "NilPtrAnonymousHeadInt16OnlyOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: struct {
+				*structInt16OmitEmpty
+			}{
+				structInt16OmitEmpty: nil,
+			},
+		},
+		{
+			name:     "NilPtrAnonymousHeadInt16OnlyString",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: struct {
+				*structInt16String
+			}{
+				structInt16String: nil,
+			},
+		},
+
+		// AnonymousHeadInt16PtrOnly
 		{
 			name:     "AnonymousHeadInt16PtrOnly",
 			expected: `{"a":1}`,
@@ -921,6 +2757,36 @@ null
 				structInt16Ptr: structInt16Ptr{A: int16ptr(1)},
 			},
 		},
+		{
+			name:     "AnonymousHeadInt16PtrOnlyOmitEmpty",
+			expected: `{"a":1}`,
+			indentExpected: `
+{
+  "a": 1
+}
+`,
+			data: struct {
+				structInt16PtrOmitEmpty
+			}{
+				structInt16PtrOmitEmpty: structInt16PtrOmitEmpty{A: int16ptr(1)},
+			},
+		},
+		{
+			name:     "AnonymousHeadInt16PtrOnlyString",
+			expected: `{"a":"1"}`,
+			indentExpected: `
+{
+  "a": "1"
+}
+`,
+			data: struct {
+				structInt16PtrString
+			}{
+				structInt16PtrString: structInt16PtrString{A: int16ptr(1)},
+			},
+		},
+
+		// AnonymousHeadInt16PtrNilOnly
 		{
 			name:     "AnonymousHeadInt16PtrNilOnly",
 			expected: `{"a":null}`,
@@ -935,6 +2801,34 @@ null
 				structInt16Ptr: structInt16Ptr{A: nil},
 			},
 		},
+		{
+			name:     "AnonymousHeadInt16PtrNilOnlyOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: struct {
+				structInt16PtrOmitEmpty
+			}{
+				structInt16PtrOmitEmpty: structInt16PtrOmitEmpty{A: nil},
+			},
+		},
+		{
+			name:     "AnonymousHeadInt16PtrNilOnlyString",
+			expected: `{"a":null}`,
+			indentExpected: `
+{
+  "a": null
+}
+`,
+			data: struct {
+				structInt16PtrString
+			}{
+				structInt16PtrString: structInt16PtrString{A: nil},
+			},
+		},
+
+		// PtrAnonymousHeadInt16PtrOnly
 		{
 			name:     "PtrAnonymousHeadInt16PtrOnly",
 			expected: `{"a":1}`,
@@ -949,6 +2843,36 @@ null
 				structInt16Ptr: &structInt16Ptr{A: int16ptr(1)},
 			},
 		},
+		{
+			name:     "PtrAnonymousHeadInt16PtrOnlyOmitEmpty",
+			expected: `{"a":1}`,
+			indentExpected: `
+{
+  "a": 1
+}
+`,
+			data: struct {
+				*structInt16PtrOmitEmpty
+			}{
+				structInt16PtrOmitEmpty: &structInt16PtrOmitEmpty{A: int16ptr(1)},
+			},
+		},
+		{
+			name:     "PtrAnonymousHeadInt16PtrOnlyString",
+			expected: `{"a":"1"}`,
+			indentExpected: `
+{
+  "a": "1"
+}
+`,
+			data: struct {
+				*structInt16PtrString
+			}{
+				structInt16PtrString: &structInt16PtrString{A: int16ptr(1)},
+			},
+		},
+
+		// NilPtrAnonymousHeadInt16PtrOnly
 		{
 			name:     "NilPtrAnonymousHeadInt16PtrOnly",
 			expected: `{}`,
@@ -961,6 +2885,30 @@ null
 				structInt16Ptr: nil,
 			},
 		},
+		{
+			name:     "NilPtrAnonymousHeadInt16PtrOnlyOmitEmpty",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: struct {
+				*structInt16PtrOmitEmpty
+			}{
+				structInt16PtrOmitEmpty: nil,
+			},
+		},
+		{
+			name:     "NilPtrAnonymousHeadInt16PtrOnlyString",
+			expected: `{}`,
+			indentExpected: `
+{}
+`,
+			data: struct {
+				*structInt16PtrString
+			}{
+				structInt16PtrString: nil,
+			},
+		},
 	}
 	for _, test := range tests {
 		for _, indent := range []bool{true, false} {
diff --git a/encode_vm.go b/encode_vm.go
index e5b7deb..f709239 100644
--- a/encode_vm.go
+++ b/encode_vm.go
@@ -1561,6 +1561,51 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 				b = encodeComma(b)
 				code = code.next
 			}
+		case opStructFieldPtrHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr != 0 {
+				store(ctxptr, code.idx, e.ptrToPtr(ptr))
+			}
+			fallthrough
+		case opStructFieldHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				b = encodeNull(b)
+				b = encodeComma(b)
+				code = code.end.next
+			} else {
+				b = append(b, '{')
+				v := e.ptrToInt16(ptr + code.offset)
+				if v == 0 {
+					code = code.nextField
+				} else {
+					b = append(b, code.key...)
+					b = appendInt(b, int64(v))
+					b = encodeComma(b)
+					code = code.next
+				}
+			}
+		case opStructFieldPtrHeadStringTagInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr != 0 {
+				store(ctxptr, code.idx, e.ptrToPtr(ptr))
+			}
+			fallthrough
+		case opStructFieldHeadStringTagInt16:
+			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.key...)
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+				b = append(b, '"')
+				b = encodeComma(b)
+				code = code.next
+			}
 		case opStructFieldPtrHeadInt16Only, opStructFieldHeadInt16Only:
 			p := load(ctxptr, code.idx)
 			b = append(b, '{')
@@ -1568,6 +1613,25 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			b = appendInt(b, int64(e.ptrToInt16(p)))
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldPtrHeadOmitEmptyInt16Only, opStructFieldHeadOmitEmptyInt16Only:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{')
+			v := int64(e.ptrToInt16(p))
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendInt(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldPtrHeadStringTagInt16Only, opStructFieldHeadStringTagInt16Only:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{')
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendInt(b, int64(e.ptrToInt16(p)))
+			b = append(b, '"')
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldPtrHeadInt16Ptr:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -1590,6 +1654,49 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldPtrHeadOmitEmptyInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldHeadOmitEmptyInt16Ptr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				b = encodeNull(b)
+				b = encodeComma(b)
+				code = code.end.next
+			} else {
+				b = append(b, '{')
+				p = e.ptrToPtr(p)
+				if p != 0 {
+					b = append(b, code.key...)
+					b = appendInt(b, int64(e.ptrToInt16(p)))
+					b = encodeComma(b)
+				}
+				code = code.next
+			}
+		case opStructFieldPtrHeadStringTagInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldHeadStringTagInt16Ptr:
+			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 = append(b, '"')
+					b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+					b = append(b, '"')
+				}
+			}
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldPtrHeadInt16PtrOnly:
 			p := load(ctxptr, code.idx)
 			if p == 0 {
@@ -1611,6 +1718,69 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldPtrHeadOmitEmptyInt16PtrOnly:
+			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 opStructFieldHeadOmitEmptyInt16PtrOnly:
+			b = append(b, '{')
+			p := load(ctxptr, code.idx)
+			if p != 0 {
+				b = append(b, code.key...)
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldPtrHeadStringTagInt16PtrOnly:
+			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 opStructFieldHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{')
+			b = append(b, code.key...)
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = append(b, '"')
+			}
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldHeadInt16NPtr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '{')
+				b = append(b, code.key...)
+				for i := 0; i < code.ptrNum; i++ {
+					if p == 0 {
+						break
+					}
+					p = e.ptrToPtr(p)
+				}
+				if p == 0 {
+					b = encodeNull(b)
+				} else {
+					b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				}
+			}
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldPtrAnonymousHeadInt16:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -1624,6 +1794,45 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 				b = encodeComma(b)
 				code = code.next
 			}
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr != 0 {
+				store(ctxptr, code.idx, e.ptrToPtr(ptr))
+			}
+			fallthrough
+		case opStructFieldAnonymousHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				v := e.ptrToInt16(ptr + code.offset)
+				if v == 0 {
+					code = code.nextField
+				} else {
+					b = append(b, code.key...)
+					b = appendInt(b, int64(v))
+					b = encodeComma(b)
+					code = code.next
+				}
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr != 0 {
+				store(ctxptr, code.idx, e.ptrToPtr(ptr))
+			}
+			fallthrough
+		case opStructFieldAnonymousHeadStringTagInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				b = append(b, code.key...)
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+				b = append(b, '"')
+				b = encodeComma(b)
+				code = code.next
+			}
 		case opStructFieldPtrAnonymousHeadInt16Only, opStructFieldAnonymousHeadInt16Only:
 			ptr := load(ctxptr, code.idx)
 			if ptr == 0 {
@@ -1634,6 +1843,33 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 				b = encodeComma(b)
 				code = code.next
 			}
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16Only, opStructFieldAnonymousHeadOmitEmptyInt16Only:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				v := e.ptrToInt16(ptr + code.offset)
+				if v == 0 {
+					code = code.nextField
+				} else {
+					b = append(b, code.key...)
+					b = appendInt(b, int64(v))
+					b = encodeComma(b)
+					code = code.next
+				}
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16Only, opStructFieldAnonymousHeadStringTagInt16Only:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				b = append(b, code.key...)
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+				b = append(b, '"')
+				b = encodeComma(b)
+				code = code.next
+			}
 		case opStructFieldPtrAnonymousHeadInt16Ptr:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -1652,6 +1888,44 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldAnonymousHeadOmitEmptyInt16Ptr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			p = e.ptrToPtr(p)
+			if p == 0 {
+				code = code.nextField
+			} else {
+				b = append(b, code.key...)
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+				b = encodeComma(b)
+				code = code.next
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldAnonymousHeadStringTagInt16Ptr:
+			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 {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = append(b, '"')
+			}
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldPtrAnonymousHeadInt16PtrOnly:
 			p := load(ctxptr, code.idx)
 			if p == 0 {
@@ -1670,6 +1944,44 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			store(ctxptr, code.idx, e.ptrToPtr(p))
+			fallthrough
+		case opStructFieldAnonymousHeadOmitEmptyInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.nextField
+			} else {
+				b = append(b, code.key...)
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = encodeComma(b)
+				code = code.next
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			store(ctxptr, code.idx, e.ptrToPtr(p))
+			fallthrough
+		case opStructFieldAnonymousHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			b = append(b, code.key...)
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = append(b, '"')
+			}
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldPtrHeadInt32:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -3293,51 +3605,6 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 				b = encodeComma(b)
 				code = code.next
 			}
-		case opStructFieldPtrHeadOmitEmptyInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr != 0 {
-				store(ctxptr, code.idx, e.ptrToPtr(ptr))
-			}
-			fallthrough
-		case opStructFieldHeadOmitEmptyInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr == 0 {
-				b = encodeNull(b)
-				b = encodeComma(b)
-				code = code.end.next
-			} else {
-				b = append(b, '{')
-				v := e.ptrToInt16(ptr + code.offset)
-				if v == 0 {
-					code = code.nextField
-				} else {
-					b = append(b, code.key...)
-					b = appendInt(b, int64(v))
-					b = encodeComma(b)
-					code = code.next
-				}
-			}
-		case opStructFieldPtrAnonymousHeadOmitEmptyInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr != 0 {
-				store(ctxptr, code.idx, e.ptrToPtr(ptr))
-			}
-			fallthrough
-		case opStructFieldAnonymousHeadOmitEmptyInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr == 0 {
-				code = code.end.next
-			} else {
-				v := e.ptrToInt16(ptr + code.offset)
-				if v == 0 {
-					code = code.nextField
-				} else {
-					b = append(b, code.key...)
-					b = appendInt(b, int64(v))
-					b = encodeComma(b)
-					code = code.next
-				}
-			}
 		case opStructFieldPtrHeadOmitEmptyInt32:
 			ptr := load(ctxptr, code.idx)
 			if ptr != 0 {
@@ -4076,45 +4343,6 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 				code = code.next
 				store(ctxptr, code.idx, ptr+code.offset)
 			}
-		case opStructFieldPtrHeadStringTagInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr != 0 {
-				store(ctxptr, code.idx, e.ptrToPtr(ptr))
-			}
-			fallthrough
-		case opStructFieldHeadStringTagInt16:
-			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.key...)
-				b = append(b, '"')
-				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-				b = append(b, '"')
-				b = encodeComma(b)
-				code = code.next
-			}
-		case opStructFieldPtrAnonymousHeadStringTagInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr != 0 {
-				store(ctxptr, code.idx, e.ptrToPtr(ptr))
-			}
-			fallthrough
-		case opStructFieldAnonymousHeadStringTagInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr == 0 {
-				code = code.end.next
-			} else {
-				b = append(b, code.key...)
-				b = append(b, '"')
-				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-				b = append(b, '"')
-				b = encodeComma(b)
-				code = code.next
-			}
 		case opStructFieldPtrHeadStringTagInt32:
 			ptr := load(ctxptr, code.idx)
 			if ptr != 0 {
@@ -4734,6 +4962,22 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			ptr := load(ctxptr, code.headIdx) + code.offset
 			code = code.next
 			store(ctxptr, code.idx, ptr)
+		case opStructFieldOmitEmpty:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 || **(**uintptr)(unsafe.Pointer(&p)) == 0 {
+				code = code.nextField
+			} else {
+				b = append(b, code.key...)
+				code = code.next
+				store(ctxptr, code.idx, p)
+			}
+		case opStructFieldStringTag:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			b = append(b, code.key...)
+			code = code.next
+			store(ctxptr, code.idx, p)
 		case opStructFieldInt:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
@@ -4819,6 +5063,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldInt16:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyInt16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt16(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendInt(b, int64(v))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagInt16:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldInt16Ptr:
 			b = append(b, code.key...)
 			ptr := load(ctxptr, code.headIdx)
@@ -4830,10 +5097,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldInt16:
+		case opStructFieldInt32:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyInt32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt32(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendInt(b, int64(v))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagInt32:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldInt32Ptr:
@@ -4847,10 +5131,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldInt32:
+		case opStructFieldInt64:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyInt64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt64(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendInt(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagInt64:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldInt64Ptr:
@@ -4864,10 +5165,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldInt64:
+		case opStructFieldUint:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyUint:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendUint(b, uint64(v))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldUintPtr:
@@ -4881,10 +5199,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldUint:
+		case opStructFieldUint8:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyUint8:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint8(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendUint(b, uint64(v))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint8:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldUint8Ptr:
@@ -4898,10 +5233,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldUint8:
+		case opStructFieldUint16:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyUint16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint16(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendUint(b, uint64(v))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint16:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldUint16Ptr:
@@ -4915,10 +5267,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldUint16:
+		case opStructFieldUint32:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyUint32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint32(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendUint(b, uint64(v))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint32:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldUint32Ptr:
@@ -4932,10 +5301,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldUint32:
+		case opStructFieldUint64:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyUint64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint64(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendUint(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint64:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint64(ptr+code.offset)))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldUint64Ptr:
@@ -4949,10 +5335,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldUint64:
+		case opStructFieldFloat32:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
+			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat32(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = encodeFloat32(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldFloat32Ptr:
@@ -4966,10 +5369,38 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldFloat32:
+		case opStructFieldFloat64:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			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 opStructFieldOmitEmptyFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if v != 0 {
+				if math.IsInf(v, 0) || math.IsNaN(v) {
+					return nil, errUnsupportedFloat(v)
+				}
+				b = append(b, code.key...)
+				b = encodeFloat64(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if math.IsInf(v, 0) || math.IsNaN(v) {
+				return nil, errUnsupportedFloat(v)
+			}
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = encodeFloat64(b, v)
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldFloat64Ptr:
@@ -4989,14 +5420,26 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			b = encodeFloat64(b, v)
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldFloat64:
+		case opStructFieldString:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if math.IsInf(v, 0) || math.IsNaN(v) {
-				return nil, errUnsupportedFloat(v)
+			b = encodeNoEscapedString(b, e.ptrToString(ptr+code.offset))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyString:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToString(ptr + code.offset)
+			if v != "" {
+				b = append(b, code.key...)
+				b = encodeNoEscapedString(b, v)
+				b = encodeComma(b)
 			}
-			b = encodeFloat64(b, v)
+			code = code.next
+		case opStructFieldStringTagString:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			s := e.ptrToString(ptr + code.offset)
+			b = encodeNoEscapedString(b, string(encodeNoEscapedString([]byte{}, s)))
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldStringPtr:
@@ -5010,10 +5453,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldString:
+		case opStructFieldBool:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = encodeNoEscapedString(b, e.ptrToString(ptr+code.offset))
+			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyBool:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBool(ptr + code.offset)
+			if v {
+				b = append(b, code.key...)
+				b = encodeBool(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagBool:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldBoolPtr:
@@ -5027,18 +5487,28 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldBool:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
-			b = encodeComma(b)
-			code = code.next
 		case opStructFieldBytes:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
 			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyBytes:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBytes(ptr + code.offset)
+			if len(v) > 0 {
+				b = append(b, code.key...)
+				b = encodeByteSlice(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagBytes:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBytes(ptr + code.offset)
+			b = append(b, code.key...)
+			b = encodeByteSlice(b, v)
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
@@ -5055,178 +5525,22 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			b = append(b, buf.Bytes()...)
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldMarshalText:
+		case opStructFieldStringTagMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
 			p := ptr + code.offset
 			v := e.ptrToInterface(code, p)
-			bytes, err := v.(encoding.TextMarshaler).MarshalText()
+			bb, err := v.(Marshaler).MarshalJSON()
 			if err != nil {
 				return nil, errMarshaler(code, err)
 			}
-			b = encodeNoEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
+			var buf bytes.Buffer
+			if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil {
+				return nil, err
+			}
+			b = append(b, code.key...)
+			b = encodeNoEscapedString(b, buf.String())
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldArray:
-			b = append(b, code.key...)
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldSlice:
-			b = append(b, code.key...)
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldMap:
-			b = append(b, code.key...)
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldMapLoad:
-			b = append(b, code.key...)
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldStruct:
-			b = append(b, code.key...)
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldOmitEmpty:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 || **(**uintptr)(unsafe.Pointer(&p)) == 0 {
-				code = code.nextField
-			} else {
-				b = append(b, code.key...)
-				code = code.next
-				store(ctxptr, code.idx, p)
-			}
-		case opStructFieldOmitEmptyInt16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt16(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendInt(b, int64(v))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyInt32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt32(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendInt(b, int64(v))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyInt64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt64(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendInt(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendUint(b, uint64(v))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint8:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint8(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendUint(b, uint64(v))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint16(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendUint(b, uint64(v))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint32(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendUint(b, uint64(v))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint64(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendUint(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat32(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = encodeFloat32(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if v != 0 {
-				if math.IsInf(v, 0) || math.IsNaN(v) {
-					return nil, errUnsupportedFloat(v)
-				}
-				b = append(b, code.key...)
-				b = encodeFloat64(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyString:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToString(ptr + code.offset)
-			if v != "" {
-				b = append(b, code.key...)
-				b = encodeNoEscapedString(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyBool:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBool(ptr + code.offset)
-			if v {
-				b = append(b, code.key...)
-				b = encodeBool(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyBytes:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBytes(ptr + code.offset)
-			if len(v) > 0 {
-				b = append(b, code.key...)
-				b = encodeByteSlice(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
 		case opStructFieldOmitEmptyMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			p := ptr + code.offset
@@ -5245,190 +5559,16 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 				b = encodeComma(b)
 			}
 			code = code.next
-		case opStructFieldOmitEmptyMarshalText:
+		case opStructFieldMarshalText:
 			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
 			p := ptr + code.offset
 			v := e.ptrToInterface(code, p)
-			if v != nil {
-				bytes, err := v.(encoding.TextMarshaler).MarshalText()
-				if err != nil {
-					return nil, errMarshaler(code, err)
-				}
-				b = append(b, code.key...)
-				b = encodeNoEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyArray:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			array := e.ptrToSlice(p)
-			if p == 0 || uintptr(array.data) == 0 {
-				code = code.nextField
-			} else {
-				code = code.next
-			}
-		case opStructFieldOmitEmptySlice:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			slice := e.ptrToSlice(p)
-			if p == 0 || uintptr(slice.data) == 0 {
-				code = code.nextField
-			} else {
-				code = code.next
-			}
-		case opStructFieldOmitEmptyMap:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				code = code.nextField
-			} else {
-				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
-				if mlen == 0 {
-					code = code.nextField
-				} else {
-					code = code.next
-				}
-			}
-		case opStructFieldOmitEmptyMapLoad:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				code = code.nextField
-			} else {
-				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
-				if mlen == 0 {
-					code = code.nextField
-				} else {
-					code = code.next
-				}
-			}
-		case opStructFieldStringTag:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			b = append(b, code.key...)
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldStringTagInt16:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagInt32:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagInt64:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagUint:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagUint8:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagUint16:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagUint32:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagUint64:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint64(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if math.IsInf(v, 0) || math.IsNaN(v) {
-				return nil, errUnsupportedFloat(v)
-			}
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = encodeFloat64(b, v)
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagString:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			s := e.ptrToString(ptr + code.offset)
-			b = encodeNoEscapedString(b, string(encodeNoEscapedString([]byte{}, s)))
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagBool:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagBytes:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBytes(ptr + code.offset)
-			b = append(b, code.key...)
-			b = encodeByteSlice(b, v)
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagMarshalJSON:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			v := e.ptrToInterface(code, p)
-			bb, err := v.(Marshaler).MarshalJSON()
+			bytes, err := v.(encoding.TextMarshaler).MarshalText()
 			if err != nil {
 				return nil, errMarshaler(code, err)
 			}
-			var buf bytes.Buffer
-			if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil {
-				return nil, err
-			}
-			b = append(b, code.key...)
-			b = encodeNoEscapedString(b, buf.String())
+			b = encodeNoEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldStringTagMarshalText:
@@ -5443,6 +5583,94 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			b = encodeNoEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyMarshalText:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			v := e.ptrToInterface(code, p)
+			if v != nil {
+				bytes, err := v.(encoding.TextMarshaler).MarshalText()
+				if err != nil {
+					return nil, errMarshaler(code, err)
+				}
+				b = append(b, code.key...)
+				b = encodeNoEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldArray:
+			b = append(b, code.key...)
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			code = code.next
+			store(ctxptr, code.idx, p)
+		case opStructFieldOmitEmptyArray:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			array := e.ptrToSlice(p)
+			if p == 0 || uintptr(array.data) == 0 {
+				code = code.nextField
+			} else {
+				code = code.next
+			}
+		case opStructFieldSlice:
+			b = append(b, code.key...)
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			code = code.next
+			store(ctxptr, code.idx, p)
+		case opStructFieldOmitEmptySlice:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			slice := e.ptrToSlice(p)
+			if p == 0 || uintptr(slice.data) == 0 {
+				code = code.nextField
+			} else {
+				code = code.next
+			}
+		case opStructFieldMap:
+			b = append(b, code.key...)
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			code = code.next
+			store(ctxptr, code.idx, p)
+		case opStructFieldOmitEmptyMap:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				code = code.nextField
+			} else {
+				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
+				if mlen == 0 {
+					code = code.nextField
+				} else {
+					code = code.next
+				}
+			}
+		case opStructFieldMapLoad:
+			b = append(b, code.key...)
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			code = code.next
+			store(ctxptr, code.idx, p)
+		case opStructFieldOmitEmptyMapLoad:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				code = code.nextField
+			} else {
+				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
+				if mlen == 0 {
+					code = code.nextField
+				} else {
+					code = code.next
+				}
+			}
+		case opStructFieldStruct:
+			b = append(b, code.key...)
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			code = code.next
+			store(ctxptr, code.idx, p)
 		case opStructEnd:
 			last := len(b) - 1
 			if b[last] == ',' {
@@ -5600,6 +5828,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = appendStructEnd(b)
 			code = code.next
+		case opStructEndInt16:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyInt16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt16(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendInt(b, int64(v))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagInt16:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = append(b, '"')
+			b = appendStructEnd(b)
+			code = code.next
 		case opStructEndInt16Ptr:
 			b = append(b, code.key...)
 			ptr := load(ctxptr, code.headIdx)
@@ -5611,10 +5862,66 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndInt16:
+		case opStructEndOmitEmptyInt16Ptr:
+			ptr := load(ctxptr, code.headIdx)
+			p := e.ptrToPtr(ptr + code.offset)
+			if p != 0 {
+				b = append(b, code.key...)
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagInt16Ptr:
+			b = append(b, code.key...)
+			ptr := load(ctxptr, code.headIdx)
+			p := e.ptrToPtr(ptr + code.offset)
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+				b = append(b, '"')
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndInt16NPtr:
+			b = append(b, code.key...)
+			ptr := load(ctxptr, code.headIdx)
+			p := e.ptrToPtr(ptr + code.offset)
+			for i := 0; i < code.ptrNum-1; i++ {
+				if p == 0 {
+					break
+				}
+				p = e.ptrToPtr(p)
+			}
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndInt32:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyInt32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt32(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendInt(b, int64(v))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagInt32:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndInt32Ptr:
@@ -5628,10 +5935,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndInt32:
+		case opStructEndInt64:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyInt64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt64(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendInt(b, v)
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagInt64:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndInt64Ptr:
@@ -5645,10 +5969,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndInt64:
+		case opStructEndUint:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyUint:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendUint(b, uint64(v))
+				b = appendStructEnd(b)
+			}
+			code = code.next
+		case opStructEndStringTagUint:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndUintPtr:
@@ -5662,10 +6003,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndUint:
+		case opStructEndUint8:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyUint8:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint8(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendUint(b, uint64(v))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagUint8:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndUint8Ptr:
@@ -5679,10 +6037,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndUint8:
+		case opStructEndUint16:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyUint16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint16(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendUint(b, uint64(v))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagUint16:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndUint16Ptr:
@@ -5696,10 +6071,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndUint16:
+		case opStructEndUint32:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyUint32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint32(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendUint(b, uint64(v))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagUint32:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndUint32Ptr:
@@ -5713,10 +6105,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndUint32:
+		case opStructEndUint64:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyUint64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint64(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = appendUint(b, v)
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagUint64:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint64(ptr+code.offset)))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndUint64Ptr:
@@ -5730,10 +6139,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndUint64:
+		case opStructEndFloat32:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
+			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat32(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.key...)
+				b = encodeFloat32(b, v)
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndFloat32Ptr:
@@ -5747,10 +6173,38 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndFloat32:
+		case opStructEndFloat64:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			v := e.ptrToFloat64(ptr + code.offset)
+			if math.IsInf(v, 0) || math.IsNaN(v) {
+				return nil, errUnsupportedFloat(v)
+			}
+			b = encodeFloat64(b, v)
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if v != 0 {
+				if math.IsInf(v, 0) || math.IsNaN(v) {
+					return nil, errUnsupportedFloat(v)
+				}
+				b = append(b, code.key...)
+				b = encodeFloat64(b, v)
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if math.IsInf(v, 0) || math.IsNaN(v) {
+				return nil, errUnsupportedFloat(v)
+			}
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = encodeFloat64(b, v)
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndFloat64Ptr:
@@ -5770,14 +6224,26 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			b = encodeFloat64(b, v)
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndFloat64:
+		case opStructEndString:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if math.IsInf(v, 0) || math.IsNaN(v) {
-				return nil, errUnsupportedFloat(v)
+			b = encodeNoEscapedString(b, e.ptrToString(ptr+code.offset))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyString:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToString(ptr + code.offset)
+			if v != "" {
+				b = append(b, code.key...)
+				b = encodeNoEscapedString(b, v)
 			}
-			b = encodeFloat64(b, v)
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagString:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			s := e.ptrToString(ptr + code.offset)
+			b = encodeNoEscapedString(b, string(encodeNoEscapedString([]byte{}, s)))
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndStringPtr:
@@ -5791,10 +6257,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndString:
+		case opStructEndBool:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
-			b = encodeNoEscapedString(b, e.ptrToString(ptr+code.offset))
+			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyBool:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBool(ptr + code.offset)
+			if v {
+				b = append(b, code.key...)
+				b = encodeBool(b, v)
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagBool:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			b = append(b, '"')
+			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndBoolPtr:
@@ -5808,18 +6291,28 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndBool:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
-			b = appendStructEnd(b)
-			code = code.next
 		case opStructEndBytes:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
 			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
 			b = appendStructEnd(b)
 			code = code.next
+		case opStructEndOmitEmptyBytes:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBytes(ptr + code.offset)
+			if len(v) > 0 {
+				b = append(b, code.key...)
+				b = encodeByteSlice(b, v)
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagBytes:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBytes(ptr + code.offset)
+			b = append(b, code.key...)
+			b = encodeByteSlice(b, v)
+			b = appendStructEnd(b)
+			code = code.next
 		case opStructEndMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.key...)
@@ -5836,138 +6329,6 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			b = append(b, buf.Bytes()...)
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndMarshalText:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			p := ptr + code.offset
-			v := e.ptrToInterface(code, p)
-			bytes, err := v.(encoding.TextMarshaler).MarshalText()
-			if err != nil {
-				return nil, errMarshaler(code, err)
-			}
-			b = encodeNoEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyInt16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt16(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendInt(b, int64(v))
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyInt32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt32(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendInt(b, int64(v))
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyInt64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt64(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendInt(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyUint:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendUint(b, uint64(v))
-				b = appendStructEnd(b)
-			}
-			code = code.next
-		case opStructEndOmitEmptyUint8:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint8(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendUint(b, uint64(v))
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyUint16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint16(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendUint(b, uint64(v))
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyUint32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint32(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendUint(b, uint64(v))
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyUint64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint64(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = appendUint(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat32(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.key...)
-				b = encodeFloat32(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if v != 0 {
-				if math.IsInf(v, 0) || math.IsNaN(v) {
-					return nil, errUnsupportedFloat(v)
-				}
-				b = append(b, code.key...)
-				b = encodeFloat64(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyString:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToString(ptr + code.offset)
-			if v != "" {
-				b = append(b, code.key...)
-				b = encodeNoEscapedString(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyBool:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBool(ptr + code.offset)
-			if v {
-				b = append(b, code.key...)
-				b = encodeBool(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyBytes:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBytes(ptr + code.offset)
-			if len(v) > 0 {
-				b = append(b, code.key...)
-				b = encodeByteSlice(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
 		case opStructEndOmitEmptyMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			p := ptr + code.offset
@@ -5986,126 +6347,6 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndOmitEmptyMarshalText:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			v := e.ptrToInterface(code, p)
-			if v != nil {
-				bytes, err := v.(encoding.TextMarshaler).MarshalText()
-				if err != nil {
-					return nil, errMarshaler(code, err)
-				}
-				b = append(b, code.key...)
-				b = encodeNoEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagInt16:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagInt32:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagInt64:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagUint:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagUint8:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagUint16:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagUint32:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagUint64:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint64(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if math.IsInf(v, 0) || math.IsNaN(v) {
-				return nil, errUnsupportedFloat(v)
-			}
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = encodeFloat64(b, v)
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagString:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			s := e.ptrToString(ptr + code.offset)
-			b = encodeNoEscapedString(b, string(encodeNoEscapedString([]byte{}, s)))
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagBool:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.key...)
-			b = append(b, '"')
-			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagBytes:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBytes(ptr + code.offset)
-			b = append(b, code.key...)
-			b = encodeByteSlice(b, v)
-			b = appendStructEnd(b)
-			code = code.next
 		case opStructEndStringTagMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			p := ptr + code.offset
@@ -6122,6 +6363,32 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
 			b = encodeNoEscapedString(b, buf.String())
 			b = appendStructEnd(b)
 			code = code.next
+		case opStructEndMarshalText:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.key...)
+			p := ptr + code.offset
+			v := e.ptrToInterface(code, p)
+			bytes, err := v.(encoding.TextMarshaler).MarshalText()
+			if err != nil {
+				return nil, errMarshaler(code, err)
+			}
+			b = encodeNoEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyMarshalText:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			v := e.ptrToInterface(code, p)
+			if v != nil {
+				bytes, err := v.(encoding.TextMarshaler).MarshalText()
+				if err != nil {
+					return nil, errMarshaler(code, err)
+				}
+				b = append(b, code.key...)
+				b = encodeNoEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
+			}
+			b = appendStructEnd(b)
+			code = code.next
 		case opStructEndStringTagMarshalText:
 			ptr := load(ctxptr, code.headIdx)
 			p := ptr + code.offset
diff --git a/encode_vm_escaped.go b/encode_vm_escaped.go
index 97d43b6..d368f64 100644
--- a/encode_vm_escaped.go
+++ b/encode_vm_escaped.go
@@ -1521,6 +1521,51 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 				b = encodeComma(b)
 				code = code.next
 			}
+		case opStructFieldPtrHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr != 0 {
+				store(ctxptr, code.idx, e.ptrToPtr(ptr))
+			}
+			fallthrough
+		case opStructFieldHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				b = encodeNull(b)
+				b = encodeComma(b)
+				code = code.end.next
+			} else {
+				b = append(b, '{')
+				v := e.ptrToInt16(ptr + code.offset)
+				if v == 0 {
+					code = code.nextField
+				} else {
+					b = append(b, code.escapedKey...)
+					b = appendInt(b, int64(v))
+					b = encodeComma(b)
+					code = code.next
+				}
+			}
+		case opStructFieldPtrHeadStringTagInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr != 0 {
+				store(ctxptr, code.idx, e.ptrToPtr(ptr))
+			}
+			fallthrough
+		case opStructFieldHeadStringTagInt16:
+			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 = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+				b = append(b, '"')
+				b = encodeComma(b)
+				code = code.next
+			}
 		case opStructFieldPtrHeadInt16Only, opStructFieldHeadInt16Only:
 			p := load(ctxptr, code.idx)
 			b = append(b, '{')
@@ -1528,6 +1573,25 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			b = appendInt(b, int64(e.ptrToInt16(p)))
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldPtrHeadOmitEmptyInt16Only, opStructFieldHeadOmitEmptyInt16Only:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{')
+			v := int64(e.ptrToInt16(p))
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendInt(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldPtrHeadStringTagInt16Only, opStructFieldHeadStringTagInt16Only:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{')
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendInt(b, int64(e.ptrToInt16(p)))
+			b = append(b, '"')
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldPtrHeadInt16Ptr:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -1550,6 +1614,49 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldPtrHeadOmitEmptyInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldHeadOmitEmptyInt16Ptr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				b = encodeNull(b)
+				b = encodeComma(b)
+				code = code.end.next
+			} else {
+				b = append(b, '{')
+				p = e.ptrToPtr(p)
+				if p != 0 {
+					b = append(b, code.escapedKey...)
+					b = appendInt(b, int64(e.ptrToInt16(p)))
+					b = encodeComma(b)
+				}
+				code = code.next
+			}
+		case opStructFieldPtrHeadStringTagInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldHeadStringTagInt16Ptr:
+			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 {
+					b = append(b, '"')
+					b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+					b = append(b, '"')
+				}
+			}
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldPtrHeadInt16PtrOnly:
 			p := load(ctxptr, code.idx)
 			if p == 0 {
@@ -1571,6 +1678,69 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldPtrHeadOmitEmptyInt16PtrOnly:
+			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 opStructFieldHeadOmitEmptyInt16PtrOnly:
+			b = append(b, '{')
+			p := load(ctxptr, code.idx)
+			if p != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldPtrHeadStringTagInt16PtrOnly:
+			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 opStructFieldHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{')
+			b = append(b, code.escapedKey...)
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = append(b, '"')
+			}
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldHeadInt16NPtr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '{')
+				b = append(b, code.escapedKey...)
+				for i := 0; i < code.ptrNum; i++ {
+					if p == 0 {
+						break
+					}
+					p = e.ptrToPtr(p)
+				}
+				if p == 0 {
+					b = encodeNull(b)
+				} else {
+					b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				}
+			}
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldPtrAnonymousHeadInt16:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -1584,6 +1754,45 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 				b = encodeComma(b)
 				code = code.next
 			}
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr != 0 {
+				store(ctxptr, code.idx, e.ptrToPtr(ptr))
+			}
+			fallthrough
+		case opStructFieldAnonymousHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				v := e.ptrToInt16(ptr + code.offset)
+				if v == 0 {
+					code = code.nextField
+				} else {
+					b = append(b, code.escapedKey...)
+					b = appendInt(b, int64(v))
+					b = encodeComma(b)
+					code = code.next
+				}
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr != 0 {
+				store(ctxptr, code.idx, e.ptrToPtr(ptr))
+			}
+			fallthrough
+		case opStructFieldAnonymousHeadStringTagInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				b = append(b, code.escapedKey...)
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+				b = append(b, '"')
+				b = encodeComma(b)
+				code = code.next
+			}
 		case opStructFieldPtrAnonymousHeadInt16Only, opStructFieldAnonymousHeadInt16Only:
 			ptr := load(ctxptr, code.idx)
 			if ptr == 0 {
@@ -1594,6 +1803,33 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 				b = encodeComma(b)
 				code = code.next
 			}
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16Only, opStructFieldAnonymousHeadOmitEmptyInt16Only:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				v := e.ptrToInt16(ptr + code.offset)
+				if v == 0 {
+					code = code.nextField
+				} else {
+					b = append(b, code.escapedKey...)
+					b = appendInt(b, int64(v))
+					b = encodeComma(b)
+					code = code.next
+				}
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16Only, opStructFieldAnonymousHeadStringTagInt16Only:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				b = append(b, code.escapedKey...)
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+				b = append(b, '"')
+				b = encodeComma(b)
+				code = code.next
+			}
 		case opStructFieldPtrAnonymousHeadInt16Ptr:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -1612,6 +1848,44 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldAnonymousHeadOmitEmptyInt16Ptr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			p = e.ptrToPtr(p)
+			if p == 0 {
+				code = code.nextField
+			} else {
+				b = append(b, code.escapedKey...)
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+				b = encodeComma(b)
+				code = code.next
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldAnonymousHeadStringTagInt16Ptr:
+			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 = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = append(b, '"')
+			}
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldPtrAnonymousHeadInt16PtrOnly:
 			p := load(ctxptr, code.idx)
 			if p == 0 {
@@ -1630,6 +1904,44 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			store(ctxptr, code.idx, e.ptrToPtr(p))
+			fallthrough
+		case opStructFieldAnonymousHeadOmitEmptyInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.nextField
+			} else {
+				b = append(b, code.escapedKey...)
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = encodeComma(b)
+				code = code.next
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			store(ctxptr, code.idx, e.ptrToPtr(p))
+			fallthrough
+		case opStructFieldAnonymousHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			b = append(b, code.escapedKey...)
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = append(b, '"')
+			}
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldPtrHeadInt32:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -3260,51 +3572,6 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 				b = encodeComma(b)
 				code = code.next
 			}
-		case opStructFieldPtrHeadOmitEmptyInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr != 0 {
-				store(ctxptr, code.idx, e.ptrToPtr(ptr))
-			}
-			fallthrough
-		case opStructFieldHeadOmitEmptyInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr == 0 {
-				b = encodeNull(b)
-				b = encodeComma(b)
-				code = code.end.next
-			} else {
-				b = append(b, '{')
-				v := e.ptrToInt16(ptr + code.offset)
-				if v == 0 {
-					code = code.nextField
-				} else {
-					b = append(b, code.escapedKey...)
-					b = appendInt(b, int64(v))
-					b = encodeComma(b)
-					code = code.next
-				}
-			}
-		case opStructFieldPtrAnonymousHeadOmitEmptyInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr != 0 {
-				store(ctxptr, code.idx, e.ptrToPtr(ptr))
-			}
-			fallthrough
-		case opStructFieldAnonymousHeadOmitEmptyInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr == 0 {
-				code = code.end.next
-			} else {
-				v := e.ptrToInt16(ptr + code.offset)
-				if v == 0 {
-					code = code.nextField
-				} else {
-					b = append(b, code.escapedKey...)
-					b = appendInt(b, int64(v))
-					b = encodeComma(b)
-					code = code.next
-				}
-			}
 		case opStructFieldPtrHeadOmitEmptyInt32:
 			ptr := load(ctxptr, code.idx)
 			if ptr != 0 {
@@ -4043,45 +4310,6 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 				code = code.next
 				store(ctxptr, code.idx, ptr+code.offset)
 			}
-		case opStructFieldPtrHeadStringTagInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr != 0 {
-				store(ctxptr, code.idx, e.ptrToPtr(ptr))
-			}
-			fallthrough
-		case opStructFieldHeadStringTagInt16:
-			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 = append(b, '"')
-				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-				b = append(b, '"')
-				b = encodeComma(b)
-				code = code.next
-			}
-		case opStructFieldPtrAnonymousHeadStringTagInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr != 0 {
-				store(ctxptr, code.idx, e.ptrToPtr(ptr))
-			}
-			fallthrough
-		case opStructFieldAnonymousHeadStringTagInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr == 0 {
-				code = code.end.next
-			} else {
-				b = append(b, code.escapedKey...)
-				b = append(b, '"')
-				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-				b = append(b, '"')
-				b = encodeComma(b)
-				code = code.next
-			}
 		case opStructFieldPtrHeadStringTagInt32:
 			ptr := load(ctxptr, code.idx)
 			if ptr != 0 {
@@ -4760,6 +4988,22 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			ptr := load(ctxptr, code.headIdx) + code.offset
 			code = code.next
 			store(ctxptr, code.idx, ptr)
+		case opStructFieldOmitEmpty:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 || **(**uintptr)(unsafe.Pointer(&p)) == 0 {
+				code = code.nextField
+			} else {
+				b = append(b, code.escapedKey...)
+				code = code.next
+				store(ctxptr, code.idx, p)
+			}
+		case opStructFieldStringTag:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			b = append(b, code.escapedKey...)
+			code = code.next
+			store(ctxptr, code.idx, p)
 		case opStructFieldInt:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
@@ -4845,6 +5089,29 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldInt16:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyInt16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt16(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendInt(b, int64(v))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagInt16:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldInt16Ptr:
 			b = append(b, code.escapedKey...)
 			ptr := load(ctxptr, code.headIdx)
@@ -4856,10 +5123,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldInt16:
+		case opStructFieldInt32:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyInt32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt32(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendInt(b, int64(v))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagInt32:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldInt32Ptr:
@@ -4873,10 +5157,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldInt32:
+		case opStructFieldInt64:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyInt64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt64(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendInt(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagInt64:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldInt64Ptr:
@@ -4890,10 +5191,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldInt64:
+		case opStructFieldUint:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyUint:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendUint(b, uint64(v))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldUintPtr:
@@ -4907,10 +5225,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldUint:
+		case opStructFieldUint8:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyUint8:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint8(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendUint(b, uint64(v))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint8:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldUint8Ptr:
@@ -4924,10 +5259,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldUint8:
+		case opStructFieldUint16:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyUint16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint16(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendUint(b, uint64(v))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint16:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldUint16Ptr:
@@ -4941,10 +5293,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldUint16:
+		case opStructFieldUint32:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyUint32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint32(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendUint(b, uint64(v))
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint32:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldUint32Ptr:
@@ -4958,10 +5327,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldUint32:
+		case opStructFieldUint64:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyUint64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint64(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendUint(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint64:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint64(ptr+code.offset)))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldUint64Ptr:
@@ -4975,10 +5361,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldUint64:
+		case opStructFieldFloat32:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
+			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat32(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = encodeFloat32(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldFloat32Ptr:
@@ -4992,10 +5395,38 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldFloat32:
+		case opStructFieldFloat64:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			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 opStructFieldOmitEmptyFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if v != 0 {
+				if math.IsInf(v, 0) || math.IsNaN(v) {
+					return nil, errUnsupportedFloat(v)
+				}
+				b = append(b, code.escapedKey...)
+				b = encodeFloat64(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if math.IsInf(v, 0) || math.IsNaN(v) {
+				return nil, errUnsupportedFloat(v)
+			}
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = encodeFloat64(b, v)
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldFloat64Ptr:
@@ -5015,14 +5446,26 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			b = encodeFloat64(b, v)
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldFloat64:
+		case opStructFieldString:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if math.IsInf(v, 0) || math.IsNaN(v) {
-				return nil, errUnsupportedFloat(v)
+			b = encodeEscapedString(b, e.ptrToString(ptr+code.offset))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyString:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToString(ptr + code.offset)
+			if v != "" {
+				b = append(b, code.escapedKey...)
+				b = encodeEscapedString(b, v)
+				b = encodeComma(b)
 			}
-			b = encodeFloat64(b, v)
+			code = code.next
+		case opStructFieldStringTagString:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			s := e.ptrToString(ptr + code.offset)
+			b = encodeEscapedString(b, string(encodeEscapedString([]byte{}, s)))
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldStringPtr:
@@ -5036,10 +5479,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldString:
+		case opStructFieldBool:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = encodeEscapedString(b, e.ptrToString(ptr+code.offset))
+			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyBool:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBool(ptr + code.offset)
+			if v {
+				b = append(b, code.escapedKey...)
+				b = encodeBool(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagBool:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
+			b = append(b, '"')
 			b = encodeComma(b)
 			code = code.next
 		case opStructFieldBoolPtr:
@@ -5053,18 +5513,28 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldBool:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
-			b = encodeComma(b)
-			code = code.next
 		case opStructFieldBytes:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
 			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyBytes:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBytes(ptr + code.offset)
+			if len(v) > 0 {
+				b = append(b, code.escapedKey...)
+				b = encodeByteSlice(b, v)
+				b = encodeComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagBytes:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBytes(ptr + code.offset)
+			b = append(b, code.escapedKey...)
+			b = encodeByteSlice(b, v)
+			b = encodeComma(b)
+			code = code.next
 		case opStructFieldMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
@@ -5081,178 +5551,6 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			b = append(b, buf.Bytes()...)
 			b = encodeComma(b)
 			code = code.next
-		case opStructFieldMarshalText:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			p := ptr + code.offset
-			v := e.ptrToInterface(code, p)
-			bytes, err := v.(encoding.TextMarshaler).MarshalText()
-			if err != nil {
-				return nil, errMarshaler(code, err)
-			}
-			b = encodeEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldArray:
-			b = append(b, code.escapedKey...)
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldSlice:
-			b = append(b, code.escapedKey...)
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldMap:
-			b = append(b, code.escapedKey...)
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldMapLoad:
-			b = append(b, code.escapedKey...)
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldStruct:
-			b = append(b, code.escapedKey...)
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldOmitEmpty:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 || **(**uintptr)(unsafe.Pointer(&p)) == 0 {
-				code = code.nextField
-			} else {
-				b = append(b, code.escapedKey...)
-				code = code.next
-				store(ctxptr, code.idx, p)
-			}
-		case opStructFieldOmitEmptyInt16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt16(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendInt(b, int64(v))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyInt32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt32(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendInt(b, int64(v))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyInt64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt64(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendInt(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendUint(b, uint64(v))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint8:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint8(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendUint(b, uint64(v))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint16(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendUint(b, uint64(v))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint32(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendUint(b, uint64(v))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint64(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendUint(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat32(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = encodeFloat32(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if v != 0 {
-				if math.IsInf(v, 0) || math.IsNaN(v) {
-					return nil, errUnsupportedFloat(v)
-				}
-				b = append(b, code.escapedKey...)
-				b = encodeFloat64(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyString:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToString(ptr + code.offset)
-			if v != "" {
-				b = append(b, code.escapedKey...)
-				b = encodeEscapedString(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyBool:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBool(ptr + code.offset)
-			if v {
-				b = append(b, code.escapedKey...)
-				b = encodeBool(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyBytes:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBytes(ptr + code.offset)
-			if len(v) > 0 {
-				b = append(b, code.escapedKey...)
-				b = encodeByteSlice(b, v)
-				b = encodeComma(b)
-			}
-			code = code.next
 		case opStructFieldOmitEmptyMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			p := ptr + code.offset
@@ -5271,176 +5569,6 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 				b = encodeComma(b)
 			}
 			code = code.next
-		case opStructFieldOmitEmptyMarshalText:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			v := e.ptrToInterface(code, p)
-			if v != nil {
-				bytes, err := v.(encoding.TextMarshaler).MarshalText()
-				if err != nil {
-					return nil, errMarshaler(code, err)
-				}
-				b = append(b, code.escapedKey...)
-				b = encodeEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
-				b = encodeComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyArray:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			array := e.ptrToSlice(p)
-			if p == 0 || uintptr(array.data) == 0 {
-				code = code.nextField
-			} else {
-				code = code.next
-			}
-		case opStructFieldOmitEmptySlice:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			slice := e.ptrToSlice(p)
-			if p == 0 || uintptr(slice.data) == 0 {
-				code = code.nextField
-			} else {
-				code = code.next
-			}
-		case opStructFieldOmitEmptyMap:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				code = code.nextField
-			} else {
-				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
-				if mlen == 0 {
-					code = code.nextField
-				} else {
-					code = code.next
-				}
-			}
-		case opStructFieldOmitEmptyMapLoad:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				code = code.nextField
-			} else {
-				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
-				if mlen == 0 {
-					code = code.nextField
-				} else {
-					code = code.next
-				}
-			}
-		case opStructFieldStringTag:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			b = append(b, code.escapedKey...)
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldStringTagInt16:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagInt32:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagInt64:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagUint:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagUint8:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagUint16:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagUint32:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagUint64:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint64(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if math.IsInf(v, 0) || math.IsNaN(v) {
-				return nil, errUnsupportedFloat(v)
-			}
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = encodeFloat64(b, v)
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagString:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			s := e.ptrToString(ptr + code.offset)
-			b = encodeEscapedString(b, string(encodeEscapedString([]byte{}, s)))
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagBool:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeComma(b)
-			code = code.next
-		case opStructFieldStringTagBytes:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBytes(ptr + code.offset)
-			b = append(b, code.escapedKey...)
-			b = encodeByteSlice(b, v)
-			b = encodeComma(b)
-			code = code.next
 		case opStructFieldStringTagMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			p := ptr + code.offset
@@ -5457,6 +5585,32 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			b = encodeEscapedString(b, buf.String())
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldMarshalText:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			p := ptr + code.offset
+			v := e.ptrToInterface(code, p)
+			bytes, err := v.(encoding.TextMarshaler).MarshalText()
+			if err != nil {
+				return nil, errMarshaler(code, err)
+			}
+			b = encodeEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
+			b = encodeComma(b)
+			code = code.next
+		case opStructFieldOmitEmptyMarshalText:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			v := e.ptrToInterface(code, p)
+			if v != nil {
+				bytes, err := v.(encoding.TextMarshaler).MarshalText()
+				if err != nil {
+					return nil, errMarshaler(code, err)
+				}
+				b = append(b, code.escapedKey...)
+				b = encodeEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
+				b = encodeComma(b)
+			}
+			code = code.next
 		case opStructFieldStringTagMarshalText:
 			ptr := load(ctxptr, code.headIdx)
 			p := ptr + code.offset
@@ -5469,6 +5623,80 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			b = encodeEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
 			b = encodeComma(b)
 			code = code.next
+		case opStructFieldArray:
+			b = append(b, code.escapedKey...)
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			code = code.next
+			store(ctxptr, code.idx, p)
+		case opStructFieldOmitEmptyArray:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			array := e.ptrToSlice(p)
+			if p == 0 || uintptr(array.data) == 0 {
+				code = code.nextField
+			} else {
+				code = code.next
+			}
+		case opStructFieldSlice:
+			b = append(b, code.escapedKey...)
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			code = code.next
+			store(ctxptr, code.idx, p)
+		case opStructFieldOmitEmptySlice:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			slice := e.ptrToSlice(p)
+			if p == 0 || uintptr(slice.data) == 0 {
+				code = code.nextField
+			} else {
+				code = code.next
+			}
+		case opStructFieldMap:
+			b = append(b, code.escapedKey...)
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			code = code.next
+			store(ctxptr, code.idx, p)
+		case opStructFieldOmitEmptyMap:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				code = code.nextField
+			} else {
+				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
+				if mlen == 0 {
+					code = code.nextField
+				} else {
+					code = code.next
+				}
+			}
+		case opStructFieldMapLoad:
+			b = append(b, code.escapedKey...)
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			code = code.next
+			store(ctxptr, code.idx, p)
+		case opStructFieldOmitEmptyMapLoad:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				code = code.nextField
+			} else {
+				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
+				if mlen == 0 {
+					code = code.nextField
+				} else {
+					code = code.next
+				}
+			}
+		case opStructFieldStruct:
+			b = append(b, code.escapedKey...)
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			code = code.next
+			store(ctxptr, code.idx, p)
 		case opStructEnd:
 			last := len(b) - 1
 			if b[last] == ',' {
@@ -5626,6 +5854,29 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = appendStructEnd(b)
 			code = code.next
+		case opStructEndInt16:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyInt16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt16(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendInt(b, int64(v))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagInt16:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = append(b, '"')
+			b = appendStructEnd(b)
+			code = code.next
 		case opStructEndInt16Ptr:
 			b = append(b, code.escapedKey...)
 			ptr := load(ctxptr, code.headIdx)
@@ -5637,10 +5888,66 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndInt16:
+		case opStructEndOmitEmptyInt16Ptr:
+			ptr := load(ctxptr, code.headIdx)
+			p := e.ptrToPtr(ptr + code.offset)
+			if p != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagInt16Ptr:
+			b = append(b, code.escapedKey...)
+			ptr := load(ctxptr, code.headIdx)
+			p := e.ptrToPtr(ptr + code.offset)
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+				b = append(b, '"')
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndInt16NPtr:
+			b = append(b, code.escapedKey...)
+			ptr := load(ctxptr, code.headIdx)
+			p := e.ptrToPtr(ptr + code.offset)
+			for i := 0; i < code.ptrNum-1; i++ {
+				if p == 0 {
+					break
+				}
+				p = e.ptrToPtr(p)
+			}
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndInt32:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyInt32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt32(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendInt(b, int64(v))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagInt32:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndInt32Ptr:
@@ -5654,10 +5961,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndInt32:
+		case opStructEndInt64:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyInt64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt64(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendInt(b, v)
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagInt64:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndInt64Ptr:
@@ -5671,10 +5995,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndInt64:
+		case opStructEndUint:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyUint:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendUint(b, uint64(v))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagUint:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndUintPtr:
@@ -5688,10 +6029,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndUint:
+		case opStructEndUint8:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyUint8:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint8(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendUint(b, uint64(v))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagUint8:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndUint8Ptr:
@@ -5705,10 +6063,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndUint8:
+		case opStructEndUint16:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyUint16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint16(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendUint(b, uint64(v))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagUint16:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndUint16Ptr:
@@ -5722,10 +6097,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndUint16:
+		case opStructEndUint32:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyUint32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint32(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendUint(b, uint64(v))
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagUint32:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndUint32Ptr:
@@ -5739,10 +6131,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndUint32:
+		case opStructEndUint64:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyUint64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint64(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = appendUint(b, v)
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagUint64:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = appendUint(b, uint64(e.ptrToUint64(ptr+code.offset)))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndUint64Ptr:
@@ -5756,10 +6165,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndUint64:
+		case opStructEndFloat32:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
+			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat32(ptr + code.offset)
+			if v != 0 {
+				b = append(b, code.escapedKey...)
+				b = encodeFloat32(b, v)
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndFloat32Ptr:
@@ -5773,10 +6199,38 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndFloat32:
+		case opStructEndFloat64:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			v := e.ptrToFloat64(ptr + code.offset)
+			if math.IsInf(v, 0) || math.IsNaN(v) {
+				return nil, errUnsupportedFloat(v)
+			}
+			b = encodeFloat64(b, v)
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if v != 0 {
+				if math.IsInf(v, 0) || math.IsNaN(v) {
+					return nil, errUnsupportedFloat(v)
+				}
+				b = append(b, code.escapedKey...)
+				b = encodeFloat64(b, v)
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if math.IsInf(v, 0) || math.IsNaN(v) {
+				return nil, errUnsupportedFloat(v)
+			}
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = encodeFloat64(b, v)
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndFloat64Ptr:
@@ -5796,14 +6250,26 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			b = encodeFloat64(b, v)
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndFloat64:
+		case opStructEndString:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if math.IsInf(v, 0) || math.IsNaN(v) {
-				return nil, errUnsupportedFloat(v)
+			b = encodeEscapedString(b, e.ptrToString(ptr+code.offset))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyString:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToString(ptr + code.offset)
+			if v != "" {
+				b = append(b, code.escapedKey...)
+				b = encodeEscapedString(b, v)
 			}
-			b = encodeFloat64(b, v)
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagString:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			s := e.ptrToString(ptr + code.offset)
+			b = encodeEscapedString(b, string(encodeEscapedString([]byte{}, s)))
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndStringPtr:
@@ -5817,10 +6283,27 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndString:
+		case opStructEndBool:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
-			b = encodeEscapedString(b, e.ptrToString(ptr+code.offset))
+			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyBool:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBool(ptr + code.offset)
+			if v {
+				b = append(b, code.escapedKey...)
+				b = encodeBool(b, v)
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagBool:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			b = append(b, '"')
+			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
+			b = append(b, '"')
 			b = appendStructEnd(b)
 			code = code.next
 		case opStructEndBoolPtr:
@@ -5834,18 +6317,28 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndBool:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
-			b = appendStructEnd(b)
-			code = code.next
 		case opStructEndBytes:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
 			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
 			b = appendStructEnd(b)
 			code = code.next
+		case opStructEndOmitEmptyBytes:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBytes(ptr + code.offset)
+			if len(v) > 0 {
+				b = append(b, code.escapedKey...)
+				b = encodeByteSlice(b, v)
+			}
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndStringTagBytes:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBytes(ptr + code.offset)
+			b = append(b, code.escapedKey...)
+			b = encodeByteSlice(b, v)
+			b = appendStructEnd(b)
+			code = code.next
 		case opStructEndMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			b = append(b, code.escapedKey...)
@@ -5862,138 +6355,6 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			b = append(b, buf.Bytes()...)
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndMarshalText:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			p := ptr + code.offset
-			v := e.ptrToInterface(code, p)
-			bytes, err := v.(encoding.TextMarshaler).MarshalText()
-			if err != nil {
-				return nil, errMarshaler(code, err)
-			}
-			b = encodeEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyInt16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt16(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendInt(b, int64(v))
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyInt32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt32(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendInt(b, int64(v))
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyInt64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt64(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendInt(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyUint:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendUint(b, uint64(v))
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyUint8:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint8(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendUint(b, uint64(v))
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyUint16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint16(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendUint(b, uint64(v))
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyUint32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint32(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendUint(b, uint64(v))
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyUint64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint64(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = appendUint(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat32(ptr + code.offset)
-			if v != 0 {
-				b = append(b, code.escapedKey...)
-				b = encodeFloat32(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if v != 0 {
-				if math.IsInf(v, 0) || math.IsNaN(v) {
-					return nil, errUnsupportedFloat(v)
-				}
-				b = append(b, code.escapedKey...)
-				b = encodeFloat64(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyString:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToString(ptr + code.offset)
-			if v != "" {
-				b = append(b, code.escapedKey...)
-				b = encodeEscapedString(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyBool:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBool(ptr + code.offset)
-			if v {
-				b = append(b, code.escapedKey...)
-				b = encodeBool(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndOmitEmptyBytes:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBytes(ptr + code.offset)
-			if len(v) > 0 {
-				b = append(b, code.escapedKey...)
-				b = encodeByteSlice(b, v)
-			}
-			b = appendStructEnd(b)
-			code = code.next
 		case opStructEndOmitEmptyMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			p := ptr + code.offset
@@ -6012,126 +6373,6 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			}
 			b = appendStructEnd(b)
 			code = code.next
-		case opStructEndOmitEmptyMarshalText:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			v := e.ptrToInterface(code, p)
-			if v != nil {
-				bytes, err := v.(encoding.TextMarshaler).MarshalText()
-				if err != nil {
-					return nil, errMarshaler(code, err)
-				}
-				b = append(b, code.escapedKey...)
-				b = encodeEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
-			}
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagInt16:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagInt32:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagInt64:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagUint:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagUint8:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagUint16:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagUint32:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagUint64:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = appendUint(b, uint64(e.ptrToUint64(ptr+code.offset)))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if math.IsInf(v, 0) || math.IsNaN(v) {
-				return nil, errUnsupportedFloat(v)
-			}
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = encodeFloat64(b, v)
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagString:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			s := e.ptrToString(ptr + code.offset)
-			b = encodeEscapedString(b, string(encodeEscapedString([]byte{}, s)))
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagBool:
-			ptr := load(ctxptr, code.headIdx)
-			b = append(b, code.escapedKey...)
-			b = append(b, '"')
-			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
-			b = append(b, '"')
-			b = appendStructEnd(b)
-			code = code.next
-		case opStructEndStringTagBytes:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBytes(ptr + code.offset)
-			b = append(b, code.escapedKey...)
-			b = encodeByteSlice(b, v)
-			b = appendStructEnd(b)
-			code = code.next
 		case opStructEndStringTagMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			p := ptr + code.offset
@@ -6148,6 +6389,32 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode)
 			b = encodeEscapedString(b, buf.String())
 			b = appendStructEnd(b)
 			code = code.next
+		case opStructEndMarshalText:
+			ptr := load(ctxptr, code.headIdx)
+			b = append(b, code.escapedKey...)
+			p := ptr + code.offset
+			v := e.ptrToInterface(code, p)
+			bytes, err := v.(encoding.TextMarshaler).MarshalText()
+			if err != nil {
+				return nil, errMarshaler(code, err)
+			}
+			b = encodeEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
+			b = appendStructEnd(b)
+			code = code.next
+		case opStructEndOmitEmptyMarshalText:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			v := e.ptrToInterface(code, p)
+			if v != nil {
+				bytes, err := v.(encoding.TextMarshaler).MarshalText()
+				if err != nil {
+					return nil, errMarshaler(code, err)
+				}
+				b = append(b, code.escapedKey...)
+				b = encodeEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
+			}
+			b = appendStructEnd(b)
+			code = code.next
 		case opStructEndStringTagMarshalText:
 			ptr := load(ctxptr, code.headIdx)
 			p := ptr + code.offset
diff --git a/encode_vm_escaped_indent.go b/encode_vm_escaped_indent.go
index 89f3e40..dc352cc 100644
--- a/encode_vm_escaped_indent.go
+++ b/encode_vm_escaped_indent.go
@@ -1644,6 +1644,54 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 				b = encodeIndentComma(b)
 				code = code.next
 			}
+		case opStructFieldPtrHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr != 0 {
+				store(ctxptr, code.idx, e.ptrToPtr(ptr))
+			}
+			fallthrough
+		case opStructFieldHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.end.next
+			} else {
+				b = append(b, '{', '\n')
+				v := e.ptrToInt16(ptr + code.offset)
+				if v == 0 {
+					code = code.nextField
+				} else {
+					b = e.encodeIndent(b, code.indent+1)
+					b = append(b, code.escapedKey...)
+					b = append(b, ' ')
+					b = appendInt(b, int64(v))
+					b = encodeIndentComma(b)
+					code = code.next
+				}
+			}
+		case opStructFieldPtrHeadStringTagInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr != 0 {
+				store(ctxptr, code.idx, e.ptrToPtr(ptr))
+			}
+			fallthrough
+		case opStructFieldHeadStringTagInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.end.next
+			} else {
+				b = append(b, '{', '\n')
+				b = e.encodeIndent(b, code.indent+1)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ', '"')
+				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+				b = append(b, '"')
+				b = encodeIndentComma(b)
+				code = code.next
+			}
 		case opStructFieldPtrHeadInt16Only, opStructFieldHeadInt16Only:
 			p := load(ctxptr, code.idx)
 			b = append(b, '{', '\n')
@@ -1653,6 +1701,28 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendInt(b, int64(e.ptrToInt16(p)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldPtrHeadOmitEmptyInt16Only, opStructFieldHeadOmitEmptyInt16Only:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{', '\n')
+			v := int64(e.ptrToInt16(p))
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent+1)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendInt(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldPtrHeadStringTagInt16Only, opStructFieldHeadStringTagInt16Only:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{', '\n')
+			b = e.encodeIndent(b, code.indent+1)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, int64(e.ptrToInt16(p)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldPtrHeadInt16Ptr:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -1677,6 +1747,53 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			}
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldPtrHeadOmitEmptyInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldHeadOmitEmptyInt16Ptr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.end.next
+			} else {
+				b = append(b, '{', '\n')
+				p = e.ptrToPtr(p)
+				if p != 0 {
+					b = e.encodeIndent(b, code.indent+1)
+					b = append(b, code.escapedKey...)
+					b = append(b, ' ')
+					b = appendInt(b, int64(e.ptrToInt16(p)))
+					b = encodeIndentComma(b)
+				}
+				code = code.next
+			}
+		case opStructFieldPtrHeadStringTagInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldHeadStringTagInt16Ptr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.end.next
+				break
+			} else {
+				b = append(b, '{', '\n')
+				b = e.encodeIndent(b, code.indent+1)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				p = e.ptrToPtr(p)
+				if p == 0 {
+					b = encodeNull(b)
+				} else {
+					b = append(b, '"')
+					b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+					b = append(b, '"')
+				}
+			}
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldPtrHeadInt16PtrOnly:
 			p := load(ctxptr, code.idx)
 			if p == 0 {
@@ -1700,6 +1817,52 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			}
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldPtrHeadOmitEmptyInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.end.next
+				break
+			}
+			store(ctxptr, code.idx, e.ptrToPtr(p))
+			fallthrough
+		case opStructFieldHeadOmitEmptyInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{', '\n')
+			if p != 0 {
+				b = e.encodeIndent(b, code.indent+1)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldPtrHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.end.next
+				break
+			}
+			store(ctxptr, code.idx, e.ptrToPtr(p))
+			fallthrough
+		case opStructFieldHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{', '\n')
+			b = e.encodeIndent(b, code.indent+1)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = append(b, '"')
+			}
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldHeadInt16NPtr:
 			p := load(ctxptr, code.idx)
 			if p == 0 {
@@ -1738,6 +1901,43 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 				b = encodeIndentComma(b)
 				code = code.next
 			}
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldAnonymousHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				v := e.ptrToInt16(ptr + code.offset)
+				if v == 0 {
+					code = code.nextField
+				} else {
+					b = e.encodeIndent(b, code.indent)
+					b = append(b, code.escapedKey...)
+					b = append(b, ' ')
+					b = appendInt(b, int64(v))
+					b = encodeIndentComma(b)
+					code = code.next
+				}
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldAnonymousHeadStringTagInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+				b = append(b, '"')
+				b = encodeIndentComma(b)
+				code = code.next
+			}
 		case opStructFieldPtrAnonymousHeadInt16Only, opStructFieldAnonymousHeadInt16Only:
 			ptr := load(ctxptr, code.idx)
 			if ptr == 0 {
@@ -1750,6 +1950,37 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 				b = encodeIndentComma(b)
 				code = code.next
 			}
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16Only, opStructFieldAnonymousHeadOmitEmptyInt16Only:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				v := e.ptrToInt16(ptr + code.offset)
+				if v == 0 {
+					code = code.nextField
+				} else {
+					b = e.encodeIndent(b, code.indent)
+					b = append(b, code.escapedKey...)
+					b = append(b, ' ')
+					b = appendInt(b, int64(v))
+					b = encodeIndentComma(b)
+					code = code.next
+				}
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16Only, opStructFieldAnonymousHeadStringTagInt16Only:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+				b = append(b, '"')
+				b = encodeIndentComma(b)
+				code = code.next
+			}
 		case opStructFieldPtrAnonymousHeadInt16Ptr:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -1770,6 +2001,48 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			}
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldAnonymousHeadOmitEmptyInt16Ptr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			p = e.ptrToPtr(p)
+			if p == 0 {
+				code = code.nextField
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+				b = encodeIndentComma(b)
+				code = code.next
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldAnonymousHeadStringTagInt16Ptr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			p = e.ptrToPtr(p)
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = append(b, '"')
+			}
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldPtrAnonymousHeadInt16PtrOnly:
 			p := load(ctxptr, code.idx)
 			if p == 0 {
@@ -1790,6 +2063,48 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			}
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			store(ctxptr, code.idx, e.ptrToPtr(p))
+			fallthrough
+		case opStructFieldAnonymousHeadOmitEmptyInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.nextField
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = encodeIndentComma(b)
+				code = code.next
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			store(ctxptr, code.idx, e.ptrToPtr(p))
+			fallthrough
+		case opStructFieldAnonymousHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = append(b, '"')
+			}
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldPtrHeadInt32:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -3362,34 +3677,6 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 				b = encodeIndentComma(b)
 				code = code.next
 			}
-		case opStructFieldPtrHeadOmitEmptyInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr != 0 {
-				store(ctxptr, code.idx, e.ptrToPtr(ptr))
-			}
-			fallthrough
-		case opStructFieldHeadOmitEmptyInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr == 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = encodeNull(b)
-				b = encodeIndentComma(b)
-				code = code.end.next
-			} else {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, '{', '\n')
-				v := e.ptrToInt16(ptr + code.offset)
-				if v == 0 {
-					code = code.nextField
-				} else {
-					b = e.encodeIndent(b, code.indent+1)
-					b = append(b, code.escapedKey...)
-					b = append(b, ' ')
-					b = appendInt(b, int64(v))
-					b = encodeIndentComma(b)
-					code = code.next
-				}
-			}
 		case opStructFieldPtrHeadOmitEmptyInt32:
 			ptr := load(ctxptr, code.idx)
 			if ptr != 0 {
@@ -3750,29 +4037,6 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 				code = code.next
 				store(ctxptr, code.idx, p)
 			}
-		case opStructFieldPtrHeadStringTagInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr != 0 {
-				store(ctxptr, code.idx, e.ptrToPtr(ptr))
-			}
-			fallthrough
-		case opStructFieldHeadStringTagInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr == 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = encodeNull(b)
-				b = encodeIndentComma(b)
-				code = code.end.next
-			} else {
-				b = append(b, '{', '\n')
-				b = e.encodeIndent(b, code.indent+1)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ', '"')
-				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-				b = append(b, '"')
-				b = encodeIndentComma(b)
-				code = code.next
-			}
 		case opStructFieldPtrHeadStringTagInt32:
 			ptr := load(ctxptr, code.idx)
 			if ptr != 0 {
@@ -4060,6 +4324,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			p := ptr + code.offset
 			code = code.next
 			store(ctxptr, code.idx, p)
+		case opStructFieldOmitEmpty:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 || **(**uintptr)(unsafe.Pointer(&p)) == 0 {
+				code = code.nextField
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				code = code.next
+				store(ctxptr, code.idx, p)
+			}
+		case opStructFieldStringTag:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			code = code.next
+			store(ctxptr, code.idx, p)
 		case opStructFieldInt:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4124,6 +4408,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyInt16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt16(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(v))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagInt16:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldInt32:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4132,6 +4436,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyInt32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt32(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(v))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagInt32:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldInt64:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4140,6 +4464,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyInt64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt64(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendInt(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagInt64:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldUint:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4148,6 +4492,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyUint:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldUint8:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4156,6 +4520,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyUint8:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint8(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint8:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldUint16:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4164,6 +4548,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyUint16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint16(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint16:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldUint32:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4172,6 +4576,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyUint32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint32(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint32:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldUint64:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4180,6 +4604,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyUint64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint64(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendUint(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint64:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldFloat32:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4188,6 +4632,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat32(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = encodeFloat32(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldFloat64:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4200,6 +4664,33 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = encodeFloat64(b, v)
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if v != 0 {
+				if math.IsInf(v, 0) || math.IsNaN(v) {
+					return nil, errUnsupportedFloat(v)
+				}
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = encodeFloat64(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if math.IsInf(v, 0) || math.IsNaN(v) {
+				return nil, errUnsupportedFloat(v)
+			}
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = encodeFloat64(b, v)
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldString:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4208,6 +4699,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = encodeEscapedString(b, e.ptrToString(ptr+code.offset))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyString:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToString(ptr + code.offset)
+			if v != "" {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = encodeEscapedString(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagString:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			s := e.ptrToString(ptr + code.offset)
+			b = encodeEscapedString(b, string(encodeEscapedString([]byte{}, s)))
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldBool:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4216,6 +4727,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyBool:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBool(ptr + code.offset)
+			if v {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = encodeBool(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagBool:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldBytes:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4224,6 +4755,25 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyBytes:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBytes(ptr + code.offset)
+			if len(v) > 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = encodeByteSlice(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagBytes:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldMarshalJSON:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4242,454 +4792,6 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = append(b, buf.Bytes()...)
 			b = encodeIndentComma(b)
 			code = code.next
-		case opStructFieldArray:
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ')
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			array := e.ptrToSlice(p)
-			if p == 0 || uintptr(array.data) == 0 {
-				b = encodeNull(b)
-				b = encodeIndentComma(b)
-				code = code.nextField
-			} else {
-				code = code.next
-			}
-		case opStructFieldSlice:
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ')
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			slice := e.ptrToSlice(p)
-			if p == 0 || uintptr(slice.data) == 0 {
-				b = encodeNull(b)
-				b = encodeIndentComma(b)
-				code = code.nextField
-			} else {
-				code = code.next
-			}
-		case opStructFieldMap:
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ')
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				b = encodeNull(b)
-				code = code.nextField
-			} else {
-				p = e.ptrToPtr(p)
-				mlen := maplen(e.ptrToUnsafePtr(p))
-				if mlen == 0 {
-					b = append(b, '{', '}', ',', '\n')
-					mapCode := code.next
-					code = mapCode.end.next
-				} else {
-					code = code.next
-				}
-			}
-		case opStructFieldMapLoad:
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ')
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				b = encodeNull(b)
-				code = code.nextField
-			} else {
-				p = e.ptrToPtr(p)
-				mlen := maplen(e.ptrToUnsafePtr(p))
-				if mlen == 0 {
-					b = append(b, '{', '}', ',', '\n')
-					code = code.nextField
-				} else {
-					code = code.next
-				}
-			}
-		case opStructFieldStruct:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ')
-			if p == 0 {
-				b = append(b, '{', '}', ',', '\n')
-				code = code.nextField
-			} else {
-				headCode := code.next
-				if headCode.next == headCode.end {
-					// not exists fields
-					b = append(b, '{', '}', ',', '\n')
-					code = code.nextField
-				} else {
-					code = code.next
-					store(ctxptr, code.idx, p)
-				}
-			}
-		case opStructFieldOmitEmpty:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 || **(**uintptr)(unsafe.Pointer(&p)) == 0 {
-				code = code.nextField
-			} else {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				code = code.next
-				store(ctxptr, code.idx, p)
-			}
-		case opStructFieldOmitEmptyInt16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt16(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendInt(b, int64(v))
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyInt32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt32(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendInt(b, int64(v))
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyInt64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt64(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendInt(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint8:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint8(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint16(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint32(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint64(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendUint(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat32(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = encodeFloat32(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if v != 0 {
-				if math.IsInf(v, 0) || math.IsNaN(v) {
-					return nil, errUnsupportedFloat(v)
-				}
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = encodeFloat64(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyString:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToString(ptr + code.offset)
-			if v != "" {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = encodeEscapedString(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyBool:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBool(ptr + code.offset)
-			if v {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = encodeBool(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyBytes:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBytes(ptr + code.offset)
-			if len(v) > 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = encodeByteSlice(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyArray:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			array := e.ptrToSlice(p)
-			if p == 0 || uintptr(array.data) == 0 {
-				code = code.nextField
-			} else {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				code = code.next
-			}
-		case opStructFieldOmitEmptySlice:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			slice := e.ptrToSlice(p)
-			if p == 0 || uintptr(slice.data) == 0 {
-				code = code.nextField
-			} else {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				code = code.next
-			}
-		case opStructFieldOmitEmptyMap:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				code = code.nextField
-			} else {
-				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
-				if mlen == 0 {
-					code = code.nextField
-				} else {
-					b = e.encodeIndent(b, code.indent)
-					b = append(b, code.escapedKey...)
-					b = append(b, ' ')
-					code = code.next
-				}
-			}
-		case opStructFieldOmitEmptyMapLoad:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				code = code.nextField
-			} else {
-				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
-				if mlen == 0 {
-					code = code.nextField
-				} else {
-					b = e.encodeIndent(b, code.indent)
-					b = append(b, code.escapedKey...)
-					b = append(b, ' ')
-					code = code.next
-				}
-			}
-		case opStructFieldOmitEmptyStruct:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				code = code.nextField
-			} else {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				headCode := code.next
-				if headCode.next == headCode.end {
-					// not exists fields
-					b = append(b, '{', '}', ',', '\n')
-					code = code.nextField
-				} else {
-					code = code.next
-					store(ctxptr, code.idx, p)
-				}
-			}
-		case opStructFieldStringTag:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ')
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldStringTagInt16:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagInt32:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagInt64:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagUint:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagUint8:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagUint16:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagUint32:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagUint64:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if math.IsInf(v, 0) || math.IsNaN(v) {
-				return nil, errUnsupportedFloat(v)
-			}
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = encodeFloat64(b, v)
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagString:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ')
-			s := e.ptrToString(ptr + code.offset)
-			b = encodeEscapedString(b, string(encodeEscapedString([]byte{}, s)))
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagBool:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagBytes:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ')
-			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
-			b = encodeIndentComma(b)
-			code = code.next
 		case opStructFieldStringTagMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			b = e.encodeIndent(b, code.indent)
@@ -4722,6 +4824,168 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = encodeEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldArray:
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			array := e.ptrToSlice(p)
+			if p == 0 || uintptr(array.data) == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.nextField
+			} else {
+				code = code.next
+			}
+		case opStructFieldOmitEmptyArray:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			array := e.ptrToSlice(p)
+			if p == 0 || uintptr(array.data) == 0 {
+				code = code.nextField
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				code = code.next
+			}
+		case opStructFieldSlice:
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			slice := e.ptrToSlice(p)
+			if p == 0 || uintptr(slice.data) == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.nextField
+			} else {
+				code = code.next
+			}
+		case opStructFieldOmitEmptySlice:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			slice := e.ptrToSlice(p)
+			if p == 0 || uintptr(slice.data) == 0 {
+				code = code.nextField
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				code = code.next
+			}
+		case opStructFieldMap:
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				b = encodeNull(b)
+				code = code.nextField
+			} else {
+				p = e.ptrToPtr(p)
+				mlen := maplen(e.ptrToUnsafePtr(p))
+				if mlen == 0 {
+					b = append(b, '{', '}', ',', '\n')
+					mapCode := code.next
+					code = mapCode.end.next
+				} else {
+					code = code.next
+				}
+			}
+		case opStructFieldOmitEmptyMap:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				code = code.nextField
+			} else {
+				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
+				if mlen == 0 {
+					code = code.nextField
+				} else {
+					b = e.encodeIndent(b, code.indent)
+					b = append(b, code.escapedKey...)
+					b = append(b, ' ')
+					code = code.next
+				}
+			}
+		case opStructFieldMapLoad:
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				b = encodeNull(b)
+				code = code.nextField
+			} else {
+				p = e.ptrToPtr(p)
+				mlen := maplen(e.ptrToUnsafePtr(p))
+				if mlen == 0 {
+					b = append(b, '{', '}', ',', '\n')
+					code = code.nextField
+				} else {
+					code = code.next
+				}
+			}
+		case opStructFieldOmitEmptyMapLoad:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				code = code.nextField
+			} else {
+				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
+				if mlen == 0 {
+					code = code.nextField
+				} else {
+					b = e.encodeIndent(b, code.indent)
+					b = append(b, code.escapedKey...)
+					b = append(b, ' ')
+					code = code.next
+				}
+			}
+		case opStructFieldStruct:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			if p == 0 {
+				b = append(b, '{', '}', ',', '\n')
+				code = code.nextField
+			} else {
+				headCode := code.next
+				if headCode.next == headCode.end {
+					// not exists fields
+					b = append(b, '{', '}', ',', '\n')
+					code = code.nextField
+				} else {
+					code = code.next
+					store(ctxptr, code.idx, p)
+				}
+			}
+		case opStructFieldOmitEmptyStruct:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				code = code.nextField
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				headCode := code.next
+				if headCode.next == headCode.end {
+					// not exists fields
+					b = append(b, '{', '}', ',', '\n')
+					code = code.nextField
+				} else {
+					code = code.next
+					store(ctxptr, code.idx, p)
+				}
+			}
 		case opStructAnonymousEnd:
 			code = code.next
 		case opStructEnd:
@@ -4919,6 +5183,35 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyInt16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt16(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(v))
+				b = e.appendStructEndIndent(b, code.indent-1)
+			} else {
+				last := len(b) - 1
+				if b[last-1] == '{' {
+					// doesn't exist any fields
+					b[last] = '}'
+				} else {
+					b = append(b, '}')
+				}
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructEndStringTagInt16:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndInt16Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4932,6 +5225,41 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			}
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyInt16Ptr:
+			ptr := load(ctxptr, code.headIdx)
+			p := e.ptrToPtr(ptr + code.offset)
+			if p != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+				b = e.appendStructEndIndent(b, code.indent-1)
+			} else {
+				last := len(b) - 1
+				if b[last-1] == '{' {
+					// doesn't exist any fields
+					b[last] = '}'
+				} else {
+					b = append(b, '}')
+				}
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructEndStringTagInt16Ptr:
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			ptr := load(ctxptr, code.headIdx)
+			p := e.ptrToPtr(ptr + code.offset)
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+				b = append(b, '"')
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndInt32:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4940,6 +5268,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyInt32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt32(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(v))
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagInt32:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndInt32Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4961,6 +5309,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyInt64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt64(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendInt(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagInt64:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndInt64Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -4982,6 +5350,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyUint:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagUint:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndUintPtr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -5003,6 +5391,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyUint8:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint8(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagUint8:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndUint8Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -5024,6 +5432,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyUint16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint16(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagUint16:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndUint16Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -5045,6 +5473,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyUint32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint32(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagUint32:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndUint32Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -5066,6 +5514,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyUint64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint64(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = appendUint(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagUint64:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndUint64Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -5087,6 +5555,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat32(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = encodeFloat32(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndFloat32Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -5112,6 +5600,33 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = encodeFloat64(b, v)
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if v != 0 {
+				if math.IsInf(v, 0) || math.IsNaN(v) {
+					return nil, errUnsupportedFloat(v)
+				}
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = encodeFloat64(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if math.IsInf(v, 0) || math.IsNaN(v) {
+				return nil, errUnsupportedFloat(v)
+			}
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = encodeFloat64(b, v)
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndFloat64Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -5137,6 +5652,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = encodeEscapedString(b, e.ptrToString(ptr+code.offset))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyString:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToString(ptr + code.offset)
+			if v != "" {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = encodeEscapedString(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagString:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			s := e.ptrToString(ptr + code.offset)
+			b = encodeEscapedString(b, string(encodeEscapedString([]byte{}, s)))
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndBool:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -5145,6 +5680,26 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyBool:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBool(ptr + code.offset)
+			if v {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = encodeBool(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagBool:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ', '"')
+			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndBytes:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -5153,6 +5708,25 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyBytes:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBytes(ptr + code.offset)
+			if len(v) > 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = encodeByteSlice(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagBytes:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.escapedKey...)
+			b = append(b, ' ')
+			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndMarshalJSON:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.escapedKey...)
@@ -5171,272 +5745,6 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *op
 			b = append(b, buf.Bytes()...)
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
-		case opStructEndOmitEmptyInt16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt16(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendInt(b, int64(v))
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyInt32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt32(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendInt(b, int64(v))
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyInt64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt64(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendInt(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyUint:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyUint8:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint8(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyUint16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint16(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyUint32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint32(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyUint64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint64(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = appendUint(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat32(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = encodeFloat32(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if v != 0 {
-				if math.IsInf(v, 0) || math.IsNaN(v) {
-					return nil, errUnsupportedFloat(v)
-				}
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = encodeFloat64(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyString:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToString(ptr + code.offset)
-			if v != "" {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = encodeEscapedString(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyBool:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBool(ptr + code.offset)
-			if v {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = encodeBool(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyBytes:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBytes(ptr + code.offset)
-			if len(v) > 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.escapedKey...)
-				b = append(b, ' ')
-				b = encodeByteSlice(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagInt16:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagInt32:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagInt64:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagUint:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagUint8:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagUint16:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagUint32:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagUint64:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if math.IsInf(v, 0) || math.IsNaN(v) {
-				return nil, errUnsupportedFloat(v)
-			}
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = encodeFloat64(b, v)
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagString:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ')
-			s := e.ptrToString(ptr + code.offset)
-			b = encodeEscapedString(b, string(encodeEscapedString([]byte{}, s)))
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagBool:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ', '"')
-			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagBytes:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.escapedKey...)
-			b = append(b, ' ')
-			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
 		case opStructEndStringTagMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			b = e.encodeIndent(b, code.indent)
diff --git a/encode_vm_indent.go b/encode_vm_indent.go
index eee093c..236cd7c 100644
--- a/encode_vm_indent.go
+++ b/encode_vm_indent.go
@@ -1644,6 +1644,54 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 				b = encodeIndentComma(b)
 				code = code.next
 			}
+		case opStructFieldPtrHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr != 0 {
+				store(ctxptr, code.idx, e.ptrToPtr(ptr))
+			}
+			fallthrough
+		case opStructFieldHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.end.next
+			} else {
+				b = append(b, '{', '\n')
+				v := e.ptrToInt16(ptr + code.offset)
+				if v == 0 {
+					code = code.nextField
+				} else {
+					b = e.encodeIndent(b, code.indent+1)
+					b = append(b, code.key...)
+					b = append(b, ' ')
+					b = appendInt(b, int64(v))
+					b = encodeIndentComma(b)
+					code = code.next
+				}
+			}
+		case opStructFieldPtrHeadStringTagInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr != 0 {
+				store(ctxptr, code.idx, e.ptrToPtr(ptr))
+			}
+			fallthrough
+		case opStructFieldHeadStringTagInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.end.next
+			} else {
+				b = append(b, '{', '\n')
+				b = e.encodeIndent(b, code.indent+1)
+				b = append(b, code.key...)
+				b = append(b, ' ', '"')
+				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+				b = append(b, '"')
+				b = encodeIndentComma(b)
+				code = code.next
+			}
 		case opStructFieldPtrHeadInt16Only, opStructFieldHeadInt16Only:
 			p := load(ctxptr, code.idx)
 			b = append(b, '{', '\n')
@@ -1653,6 +1701,28 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendInt(b, int64(e.ptrToInt16(p)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldPtrHeadOmitEmptyInt16Only, opStructFieldHeadOmitEmptyInt16Only:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{', '\n')
+			v := int64(e.ptrToInt16(p))
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent+1)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendInt(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldPtrHeadStringTagInt16Only, opStructFieldHeadStringTagInt16Only:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{', '\n')
+			b = e.encodeIndent(b, code.indent+1)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, int64(e.ptrToInt16(p)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldPtrHeadInt16Ptr:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -1677,6 +1747,53 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			}
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldPtrHeadOmitEmptyInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldHeadOmitEmptyInt16Ptr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.end.next
+			} else {
+				b = append(b, '{', '\n')
+				p = e.ptrToPtr(p)
+				if p != 0 {
+					b = e.encodeIndent(b, code.indent+1)
+					b = append(b, code.key...)
+					b = append(b, ' ')
+					b = appendInt(b, int64(e.ptrToInt16(p)))
+					b = encodeIndentComma(b)
+				}
+				code = code.next
+			}
+		case opStructFieldPtrHeadStringTagInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldHeadStringTagInt16Ptr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.end.next
+				break
+			} else {
+				b = append(b, '{', '\n')
+				b = e.encodeIndent(b, code.indent+1)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				p = e.ptrToPtr(p)
+				if p == 0 {
+					b = encodeNull(b)
+				} else {
+					b = append(b, '"')
+					b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+					b = append(b, '"')
+				}
+			}
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldPtrHeadInt16PtrOnly:
 			p := load(ctxptr, code.idx)
 			if p == 0 {
@@ -1700,6 +1817,52 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			}
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldPtrHeadOmitEmptyInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.end.next
+				break
+			}
+			store(ctxptr, code.idx, e.ptrToPtr(p))
+			fallthrough
+		case opStructFieldHeadOmitEmptyInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{', '\n')
+			if p != 0 {
+				b = e.encodeIndent(b, code.indent+1)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldPtrHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.end.next
+				break
+			}
+			store(ctxptr, code.idx, e.ptrToPtr(p))
+			fallthrough
+		case opStructFieldHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			b = append(b, '{', '\n')
+			b = e.encodeIndent(b, code.indent+1)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = append(b, '"')
+			}
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldHeadInt16NPtr:
 			p := load(ctxptr, code.idx)
 			if p == 0 {
@@ -1738,6 +1901,43 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 				b = encodeIndentComma(b)
 				code = code.next
 			}
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldAnonymousHeadOmitEmptyInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				v := e.ptrToInt16(ptr + code.offset)
+				if v == 0 {
+					code = code.nextField
+				} else {
+					b = e.encodeIndent(b, code.indent)
+					b = append(b, code.key...)
+					b = append(b, ' ')
+					b = appendInt(b, int64(v))
+					b = encodeIndentComma(b)
+					code = code.next
+				}
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldAnonymousHeadStringTagInt16:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.escapedKey...)
+				b = append(b, ' ')
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+				b = append(b, '"')
+				b = encodeIndentComma(b)
+				code = code.next
+			}
 		case opStructFieldPtrAnonymousHeadInt16Only, opStructFieldAnonymousHeadInt16Only:
 			ptr := load(ctxptr, code.idx)
 			if ptr == 0 {
@@ -1750,6 +1950,37 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 				b = encodeIndentComma(b)
 				code = code.next
 			}
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16Only, opStructFieldAnonymousHeadOmitEmptyInt16Only:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				v := e.ptrToInt16(ptr + code.offset)
+				if v == 0 {
+					code = code.nextField
+				} else {
+					b = e.encodeIndent(b, code.indent)
+					b = append(b, code.key...)
+					b = append(b, ' ')
+					b = appendInt(b, int64(v))
+					b = encodeIndentComma(b)
+					code = code.next
+				}
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16Only, opStructFieldAnonymousHeadStringTagInt16Only:
+			ptr := load(ctxptr, code.idx)
+			if ptr == 0 {
+				code = code.end.next
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+				b = append(b, '"')
+				b = encodeIndentComma(b)
+				code = code.next
+			}
 		case opStructFieldPtrAnonymousHeadInt16Ptr:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -1770,6 +2001,48 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			}
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldAnonymousHeadOmitEmptyInt16Ptr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			p = e.ptrToPtr(p)
+			if p == 0 {
+				code = code.nextField
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+				b = encodeIndentComma(b)
+				code = code.next
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16Ptr:
+			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
+			fallthrough
+		case opStructFieldAnonymousHeadStringTagInt16Ptr:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			p = e.ptrToPtr(p)
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = append(b, '"')
+			}
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldPtrAnonymousHeadInt16PtrOnly:
 			p := load(ctxptr, code.idx)
 			if p == 0 {
@@ -1790,6 +2063,48 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			}
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldPtrAnonymousHeadOmitEmptyInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			store(ctxptr, code.idx, e.ptrToPtr(p))
+			fallthrough
+		case opStructFieldAnonymousHeadOmitEmptyInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.nextField
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = encodeIndentComma(b)
+				code = code.next
+			}
+		case opStructFieldPtrAnonymousHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			if p == 0 {
+				code = code.end.next
+				break
+			}
+			store(ctxptr, code.idx, e.ptrToPtr(p))
+			fallthrough
+		case opStructFieldAnonymousHeadStringTagInt16PtrOnly:
+			p := load(ctxptr, code.idx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p+code.offset)))
+				b = append(b, '"')
+			}
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldPtrHeadInt32:
 			store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
 			fallthrough
@@ -3362,34 +3677,6 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 				b = encodeIndentComma(b)
 				code = code.next
 			}
-		case opStructFieldPtrHeadOmitEmptyInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr != 0 {
-				store(ctxptr, code.idx, e.ptrToPtr(ptr))
-			}
-			fallthrough
-		case opStructFieldHeadOmitEmptyInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr == 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = encodeNull(b)
-				b = encodeIndentComma(b)
-				code = code.end.next
-			} else {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, '{', '\n')
-				v := e.ptrToInt16(ptr + code.offset)
-				if v == 0 {
-					code = code.nextField
-				} else {
-					b = e.encodeIndent(b, code.indent+1)
-					b = append(b, code.key...)
-					b = append(b, ' ')
-					b = appendInt(b, int64(v))
-					b = encodeIndentComma(b)
-					code = code.next
-				}
-			}
 		case opStructFieldPtrHeadOmitEmptyInt32:
 			ptr := load(ctxptr, code.idx)
 			if ptr != 0 {
@@ -3750,29 +4037,6 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 				code = code.next
 				store(ctxptr, code.idx, p)
 			}
-		case opStructFieldPtrHeadStringTagInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr != 0 {
-				store(ctxptr, code.idx, e.ptrToPtr(ptr))
-			}
-			fallthrough
-		case opStructFieldHeadStringTagInt16:
-			ptr := load(ctxptr, code.idx)
-			if ptr == 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = encodeNull(b)
-				b = encodeIndentComma(b)
-				code = code.end.next
-			} else {
-				b = append(b, '{', '\n')
-				b = e.encodeIndent(b, code.indent+1)
-				b = append(b, code.key...)
-				b = append(b, ' ', '"')
-				b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-				b = append(b, '"')
-				b = encodeIndentComma(b)
-				code = code.next
-			}
 		case opStructFieldPtrHeadStringTagInt32:
 			ptr := load(ctxptr, code.idx)
 			if ptr != 0 {
@@ -4060,6 +4324,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			p := ptr + code.offset
 			code = code.next
 			store(ctxptr, code.idx, p)
+		case opStructFieldOmitEmpty:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 || **(**uintptr)(unsafe.Pointer(&p)) == 0 {
+				code = code.nextField
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				code = code.next
+				store(ctxptr, code.idx, p)
+			}
+		case opStructFieldStringTag:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			code = code.next
+			store(ctxptr, code.idx, p)
 		case opStructFieldInt:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4116,7 +4400,6 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = append(b, '"')
 			b = encodeIndentComma(b)
 			code = code.next
-
 		case opStructFieldInt16:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4125,6 +4408,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyInt16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt16(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(v))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagInt16:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldInt32:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4133,6 +4436,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyInt32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt32(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(v))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagInt32:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldInt64:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4141,6 +4464,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyInt64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt64(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendInt(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagInt64:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldUint:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4149,6 +4492,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyUint:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldUint8:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4157,6 +4520,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyUint8:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint8(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint8:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldUint16:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4165,6 +4548,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyUint16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint16(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint16:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldUint32:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4173,6 +4576,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyUint32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint32(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint32:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldUint64:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4181,6 +4604,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyUint64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint64(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendUint(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagUint64:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldFloat32:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4189,6 +4632,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat32(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = encodeFloat32(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldFloat64:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4201,6 +4664,33 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = encodeFloat64(b, v)
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if v != 0 {
+				if math.IsInf(v, 0) || math.IsNaN(v) {
+					return nil, errUnsupportedFloat(v)
+				}
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = encodeFloat64(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if math.IsInf(v, 0) || math.IsNaN(v) {
+				return nil, errUnsupportedFloat(v)
+			}
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = encodeFloat64(b, v)
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldString:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4209,6 +4699,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = encodeNoEscapedString(b, e.ptrToString(ptr+code.offset))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyString:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToString(ptr + code.offset)
+			if v != "" {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = encodeNoEscapedString(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagString:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			s := e.ptrToString(ptr + code.offset)
+			b = encodeNoEscapedString(b, string(encodeNoEscapedString([]byte{}, s)))
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldBool:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4217,6 +4727,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyBool:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBool(ptr + code.offset)
+			if v {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = encodeBool(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagBool:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
+			b = append(b, '"')
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldBytes:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4225,6 +4755,25 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldOmitEmptyBytes:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBytes(ptr + code.offset)
+			if len(v) > 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = encodeByteSlice(b, v)
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructFieldStringTagBytes:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
+			b = encodeIndentComma(b)
+			code = code.next
 		case opStructFieldMarshalJSON:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4243,454 +4792,6 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = append(b, buf.Bytes()...)
 			b = encodeIndentComma(b)
 			code = code.next
-		case opStructFieldArray:
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ')
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			array := e.ptrToSlice(p)
-			if p == 0 || uintptr(array.data) == 0 {
-				b = encodeNull(b)
-				b = encodeIndentComma(b)
-				code = code.nextField
-			} else {
-				code = code.next
-			}
-		case opStructFieldSlice:
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ')
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			slice := e.ptrToSlice(p)
-			if p == 0 || uintptr(slice.data) == 0 {
-				b = encodeNull(b)
-				b = encodeIndentComma(b)
-				code = code.nextField
-			} else {
-				code = code.next
-			}
-		case opStructFieldMap:
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ')
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				b = encodeNull(b)
-				code = code.nextField
-			} else {
-				p = e.ptrToPtr(p)
-				mlen := maplen(e.ptrToUnsafePtr(p))
-				if mlen == 0 {
-					b = append(b, '{', '}', ',', '\n')
-					mapCode := code.next
-					code = mapCode.end.next
-				} else {
-					code = code.next
-				}
-			}
-		case opStructFieldMapLoad:
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ')
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				b = encodeNull(b)
-				code = code.nextField
-			} else {
-				p = e.ptrToPtr(p)
-				mlen := maplen(e.ptrToUnsafePtr(p))
-				if mlen == 0 {
-					b = append(b, '{', '}', ',', '\n')
-					code = code.nextField
-				} else {
-					code = code.next
-				}
-			}
-		case opStructFieldStruct:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ')
-			if p == 0 {
-				b = append(b, '{', '}', ',', '\n')
-				code = code.nextField
-			} else {
-				headCode := code.next
-				if headCode.next == headCode.end {
-					// not exists fields
-					b = append(b, '{', '}', ',', '\n')
-					code = code.nextField
-				} else {
-					code = code.next
-					store(ctxptr, code.idx, p)
-				}
-			}
-		case opStructFieldOmitEmpty:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 || **(**uintptr)(unsafe.Pointer(&p)) == 0 {
-				code = code.nextField
-			} else {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				code = code.next
-				store(ctxptr, code.idx, p)
-			}
-		case opStructFieldOmitEmptyInt16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt16(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendInt(b, int64(v))
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyInt32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt32(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendInt(b, int64(v))
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyInt64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt64(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendInt(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint8:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint8(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint16(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint32(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyUint64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint64(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendUint(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat32(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = encodeFloat32(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if v != 0 {
-				if math.IsInf(v, 0) || math.IsNaN(v) {
-					return nil, errUnsupportedFloat(v)
-				}
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = encodeFloat64(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyString:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToString(ptr + code.offset)
-			if v != "" {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = encodeNoEscapedString(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyBool:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBool(ptr + code.offset)
-			if v {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = encodeBool(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyBytes:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBytes(ptr + code.offset)
-			if len(v) > 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = encodeByteSlice(b, v)
-				b = encodeIndentComma(b)
-			}
-			code = code.next
-		case opStructFieldOmitEmptyArray:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			array := e.ptrToSlice(p)
-			if p == 0 || uintptr(array.data) == 0 {
-				code = code.nextField
-			} else {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				code = code.next
-			}
-		case opStructFieldOmitEmptySlice:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			slice := e.ptrToSlice(p)
-			if p == 0 || uintptr(slice.data) == 0 {
-				code = code.nextField
-			} else {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				code = code.next
-			}
-		case opStructFieldOmitEmptyMap:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				code = code.nextField
-			} else {
-				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
-				if mlen == 0 {
-					code = code.nextField
-				} else {
-					b = e.encodeIndent(b, code.indent)
-					b = append(b, code.key...)
-					b = append(b, ' ')
-					code = code.next
-				}
-			}
-		case opStructFieldOmitEmptyMapLoad:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				code = code.nextField
-			} else {
-				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
-				if mlen == 0 {
-					code = code.nextField
-				} else {
-					b = e.encodeIndent(b, code.indent)
-					b = append(b, code.key...)
-					b = append(b, ' ')
-					code = code.next
-				}
-			}
-		case opStructFieldOmitEmptyStruct:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			if p == 0 {
-				code = code.nextField
-			} else {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				headCode := code.next
-				if headCode.next == headCode.end {
-					// not exists fields
-					b = append(b, '{', '}', ',', '\n')
-					code = code.nextField
-				} else {
-					code = code.next
-					store(ctxptr, code.idx, p)
-				}
-			}
-		case opStructFieldStringTag:
-			ptr := load(ctxptr, code.headIdx)
-			p := ptr + code.offset
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ')
-			code = code.next
-			store(ctxptr, code.idx, p)
-		case opStructFieldStringTagInt16:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagInt32:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagInt64:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagUint:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagUint8:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagUint16:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagUint32:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagUint64:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if math.IsInf(v, 0) || math.IsNaN(v) {
-				return nil, errUnsupportedFloat(v)
-			}
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = encodeFloat64(b, v)
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagString:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ')
-			s := e.ptrToString(ptr + code.offset)
-			b = encodeNoEscapedString(b, string(encodeNoEscapedString([]byte{}, s)))
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagBool:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
-			b = append(b, '"')
-			b = encodeIndentComma(b)
-			code = code.next
-		case opStructFieldStringTagBytes:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ')
-			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
-			b = encodeIndentComma(b)
-			code = code.next
 		case opStructFieldStringTagMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			b = e.encodeIndent(b, code.indent)
@@ -4723,6 +4824,168 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = encodeNoEscapedString(b, *(*string)(unsafe.Pointer(&bytes)))
 			b = encodeIndentComma(b)
 			code = code.next
+		case opStructFieldArray:
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			array := e.ptrToSlice(p)
+			if p == 0 || uintptr(array.data) == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.nextField
+			} else {
+				code = code.next
+			}
+		case opStructFieldOmitEmptyArray:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			array := e.ptrToSlice(p)
+			if p == 0 || uintptr(array.data) == 0 {
+				code = code.nextField
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				code = code.next
+			}
+		case opStructFieldSlice:
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			slice := e.ptrToSlice(p)
+			if p == 0 || uintptr(slice.data) == 0 {
+				b = encodeNull(b)
+				b = encodeIndentComma(b)
+				code = code.nextField
+			} else {
+				code = code.next
+			}
+		case opStructFieldOmitEmptySlice:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			slice := e.ptrToSlice(p)
+			if p == 0 || uintptr(slice.data) == 0 {
+				code = code.nextField
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				code = code.next
+			}
+		case opStructFieldMap:
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				b = encodeNull(b)
+				code = code.nextField
+			} else {
+				p = e.ptrToPtr(p)
+				mlen := maplen(e.ptrToUnsafePtr(p))
+				if mlen == 0 {
+					b = append(b, '{', '}', ',', '\n')
+					mapCode := code.next
+					code = mapCode.end.next
+				} else {
+					code = code.next
+				}
+			}
+		case opStructFieldOmitEmptyMap:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				code = code.nextField
+			} else {
+				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
+				if mlen == 0 {
+					code = code.nextField
+				} else {
+					b = e.encodeIndent(b, code.indent)
+					b = append(b, code.key...)
+					b = append(b, ' ')
+					code = code.next
+				}
+			}
+		case opStructFieldMapLoad:
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				b = encodeNull(b)
+				code = code.nextField
+			} else {
+				p = e.ptrToPtr(p)
+				mlen := maplen(e.ptrToUnsafePtr(p))
+				if mlen == 0 {
+					b = append(b, '{', '}', ',', '\n')
+					code = code.nextField
+				} else {
+					code = code.next
+				}
+			}
+		case opStructFieldOmitEmptyMapLoad:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				code = code.nextField
+			} else {
+				mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
+				if mlen == 0 {
+					code = code.nextField
+				} else {
+					b = e.encodeIndent(b, code.indent)
+					b = append(b, code.key...)
+					b = append(b, ' ')
+					code = code.next
+				}
+			}
+		case opStructFieldStruct:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			if p == 0 {
+				b = append(b, '{', '}', ',', '\n')
+				code = code.nextField
+			} else {
+				headCode := code.next
+				if headCode.next == headCode.end {
+					// not exists fields
+					b = append(b, '{', '}', ',', '\n')
+					code = code.nextField
+				} else {
+					code = code.next
+					store(ctxptr, code.idx, p)
+				}
+			}
+		case opStructFieldOmitEmptyStruct:
+			ptr := load(ctxptr, code.headIdx)
+			p := ptr + code.offset
+			if p == 0 {
+				code = code.nextField
+			} else {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				headCode := code.next
+				if headCode.next == headCode.end {
+					// not exists fields
+					b = append(b, '{', '}', ',', '\n')
+					code = code.nextField
+				} else {
+					code = code.next
+					store(ctxptr, code.idx, p)
+				}
+			}
 		case opStructAnonymousEnd:
 			code = code.next
 		case opStructEnd:
@@ -4920,6 +5183,35 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyInt16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt16(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(v))
+				b = e.appendStructEndIndent(b, code.indent-1)
+			} else {
+				last := len(b) - 1
+				if b[last-1] == '{' {
+					// doesn't exist any fields
+					b[last] = '}'
+				} else {
+					b = append(b, '}')
+				}
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructEndStringTagInt16:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndInt16Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4933,6 +5225,41 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			}
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyInt16Ptr:
+			ptr := load(ctxptr, code.headIdx)
+			p := e.ptrToPtr(ptr + code.offset)
+			if p != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+				b = e.appendStructEndIndent(b, code.indent-1)
+			} else {
+				last := len(b) - 1
+				if b[last-1] == '{' {
+					// doesn't exist any fields
+					b[last] = '}'
+				} else {
+					b = append(b, '}')
+				}
+				b = encodeIndentComma(b)
+			}
+			code = code.next
+		case opStructEndStringTagInt16Ptr:
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			ptr := load(ctxptr, code.headIdx)
+			p := e.ptrToPtr(ptr + code.offset)
+			if p == 0 {
+				b = encodeNull(b)
+			} else {
+				b = append(b, '"')
+				b = appendInt(b, int64(e.ptrToInt16(p)))
+				b = append(b, '"')
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndInt32:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4941,6 +5268,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyInt32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt32(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendInt(b, int64(v))
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagInt32:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndInt32Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4962,6 +5309,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndStringTagInt64:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndOmitEmptyInt64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToInt64(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendInt(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndInt64Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -4983,6 +5350,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyUint:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagUint:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndUintPtr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -5004,6 +5391,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyUint8:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint8(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagUint8:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndUint8Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -5025,6 +5432,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyUint16:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint16(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagUint16:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndUint16Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -5046,6 +5473,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyUint32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint32(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendUint(b, uint64(v))
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagUint32:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndUint32Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -5067,6 +5514,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndStringTagUint64:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndOmitEmptyUint64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToUint64(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = appendUint(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndUint64Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -5088,6 +5555,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat32(ptr + code.offset)
+			if v != 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = encodeFloat32(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagFloat32:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndFloat32Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -5113,6 +5600,33 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = encodeFloat64(b, v)
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if v != 0 {
+				if math.IsInf(v, 0) || math.IsNaN(v) {
+					return nil, errUnsupportedFloat(v)
+				}
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = encodeFloat64(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagFloat64:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToFloat64(ptr + code.offset)
+			if math.IsInf(v, 0) || math.IsNaN(v) {
+				return nil, errUnsupportedFloat(v)
+			}
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = encodeFloat64(b, v)
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndFloat64Ptr:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -5138,6 +5652,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = encodeNoEscapedString(b, e.ptrToString(ptr+code.offset))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyString:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToString(ptr + code.offset)
+			if v != "" {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = encodeNoEscapedString(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagString:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			s := e.ptrToString(ptr + code.offset)
+			b = encodeNoEscapedString(b, string(encodeNoEscapedString([]byte{}, s)))
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndBool:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -5146,6 +5680,26 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyBool:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBool(ptr + code.offset)
+			if v {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = encodeBool(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagBool:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ', '"')
+			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
+			b = append(b, '"')
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndBytes:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -5154,6 +5708,25 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
+		case opStructEndOmitEmptyBytes:
+			ptr := load(ctxptr, code.headIdx)
+			v := e.ptrToBytes(ptr + code.offset)
+			if len(v) > 0 {
+				b = e.encodeIndent(b, code.indent)
+				b = append(b, code.key...)
+				b = append(b, ' ')
+				b = encodeByteSlice(b, v)
+			}
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
+		case opStructEndStringTagBytes:
+			ptr := load(ctxptr, code.headIdx)
+			b = e.encodeIndent(b, code.indent)
+			b = append(b, code.key...)
+			b = append(b, ' ')
+			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
+			b = e.appendStructEndIndent(b, code.indent-1)
+			code = code.next
 		case opStructEndMarshalJSON:
 			b = e.encodeIndent(b, code.indent)
 			b = append(b, code.key...)
@@ -5172,272 +5745,6 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) (
 			b = append(b, buf.Bytes()...)
 			b = e.appendStructEndIndent(b, code.indent-1)
 			code = code.next
-		case opStructEndOmitEmptyInt16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt16(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendInt(b, int64(v))
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyInt32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt32(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendInt(b, int64(v))
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyInt64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToInt64(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendInt(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyUint:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyUint8:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint8(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyUint16:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint16(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyUint32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint32(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendUint(b, uint64(v))
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyUint64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToUint64(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = appendUint(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat32(ptr + code.offset)
-			if v != 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = encodeFloat32(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if v != 0 {
-				if math.IsInf(v, 0) || math.IsNaN(v) {
-					return nil, errUnsupportedFloat(v)
-				}
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = encodeFloat64(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyString:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToString(ptr + code.offset)
-			if v != "" {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = encodeNoEscapedString(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyBool:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBool(ptr + code.offset)
-			if v {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = encodeBool(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndOmitEmptyBytes:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToBytes(ptr + code.offset)
-			if len(v) > 0 {
-				b = e.encodeIndent(b, code.indent)
-				b = append(b, code.key...)
-				b = append(b, ' ')
-				b = encodeByteSlice(b, v)
-			}
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagInt16:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagInt32:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagInt64:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendInt(b, e.ptrToInt64(ptr+code.offset))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagUint:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagUint8:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagUint16:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagUint32:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagUint64:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = appendUint(b, e.ptrToUint64(ptr+code.offset))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagFloat32:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagFloat64:
-			ptr := load(ctxptr, code.headIdx)
-			v := e.ptrToFloat64(ptr + code.offset)
-			if math.IsInf(v, 0) || math.IsNaN(v) {
-				return nil, errUnsupportedFloat(v)
-			}
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = encodeFloat64(b, v)
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagString:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ')
-			s := e.ptrToString(ptr + code.offset)
-			b = encodeNoEscapedString(b, string(encodeNoEscapedString([]byte{}, s)))
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagBool:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ', '"')
-			b = encodeBool(b, e.ptrToBool(ptr+code.offset))
-			b = append(b, '"')
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
-		case opStructEndStringTagBytes:
-			ptr := load(ctxptr, code.headIdx)
-			b = e.encodeIndent(b, code.indent)
-			b = append(b, code.key...)
-			b = append(b, ' ')
-			b = encodeByteSlice(b, e.ptrToBytes(ptr+code.offset))
-			b = e.appendStructEndIndent(b, code.indent-1)
-			code = code.next
 		case opStructEndStringTagMarshalJSON:
 			ptr := load(ctxptr, code.headIdx)
 			b = e.encodeIndent(b, code.indent)