diff options
| author | 2022-09-28 18:30:40 +0100 | |
|---|---|---|
| committer | 2022-09-28 18:30:40 +0100 | |
| commit | a156188b3eb5cb3da44aa1b7452265f5fa38a607 (patch) | |
| tree | 7097fa48d56fbabc7c2c8750b1f3bc9321d71c0f /vendor/github.com/goccy/go-json/internal/encoder | |
| parent | [bugfix] Fix emphasis being added to emoji shortcodes with markdown parsing (... (diff) | |
| download | gotosocial-a156188b3eb5cb3da44aa1b7452265f5fa38a607.tar.xz | |
[chore] update dependencies, bump to Go 1.19.1 (#826)
* update dependencies, bump Go version to 1.19
* bump test image Go version
* update golangci-lint
* update gotosocial-drone-build
* sign
* linting, go fmt
* update swagger docs
* update swagger docs
* whitespace
* update contributing.md
* fuckin whoopsie doopsie
* linterino, linteroni
* fix followrequest test not starting processor
* fix other api/client tests not starting processor
* fix remaining tests where processor not started
* bump go-runners version
* don't check last-webfingered-at, processor may have updated this
* update swagger command
* update bun to latest version
* fix embed to work the same as before with new bun
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
Diffstat (limited to 'vendor/github.com/goccy/go-json/internal/encoder')
33 files changed, 26784 insertions, 0 deletions
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/code.go b/vendor/github.com/goccy/go-json/internal/encoder/code.go new file mode 100644 index 000000000..8d62a9cd5 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/code.go @@ -0,0 +1,1017 @@ +package encoder + +import ( +	"fmt" +	"reflect" +	"unsafe" + +	"github.com/goccy/go-json/internal/runtime" +) + +type Code interface { +	Kind() CodeKind +	ToOpcode(*compileContext) Opcodes +	Filter(*FieldQuery) Code +} + +type AnonymousCode interface { +	ToAnonymousOpcode(*compileContext) Opcodes +} + +type Opcodes []*Opcode + +func (o Opcodes) First() *Opcode { +	if len(o) == 0 { +		return nil +	} +	return o[0] +} + +func (o Opcodes) Last() *Opcode { +	if len(o) == 0 { +		return nil +	} +	return o[len(o)-1] +} + +func (o Opcodes) Add(codes ...*Opcode) Opcodes { +	return append(o, codes...) +} + +type CodeKind int + +const ( +	CodeKindInterface CodeKind = iota +	CodeKindPtr +	CodeKindInt +	CodeKindUint +	CodeKindFloat +	CodeKindString +	CodeKindBool +	CodeKindStruct +	CodeKindMap +	CodeKindSlice +	CodeKindArray +	CodeKindBytes +	CodeKindMarshalJSON +	CodeKindMarshalText +	CodeKindRecursive +) + +type IntCode struct { +	typ      *runtime.Type +	bitSize  uint8 +	isString bool +	isPtr    bool +} + +func (c *IntCode) Kind() CodeKind { +	return CodeKindInt +} + +func (c *IntCode) ToOpcode(ctx *compileContext) Opcodes { +	var code *Opcode +	switch { +	case c.isPtr: +		code = newOpCode(ctx, c.typ, OpIntPtr) +	case c.isString: +		code = newOpCode(ctx, c.typ, OpIntString) +	default: +		code = newOpCode(ctx, c.typ, OpInt) +	} +	code.NumBitSize = c.bitSize +	ctx.incIndex() +	return Opcodes{code} +} + +func (c *IntCode) Filter(_ *FieldQuery) Code { +	return c +} + +type UintCode struct { +	typ      *runtime.Type +	bitSize  uint8 +	isString bool +	isPtr    bool +} + +func (c *UintCode) Kind() CodeKind { +	return CodeKindUint +} + +func (c *UintCode) ToOpcode(ctx *compileContext) Opcodes { +	var code *Opcode +	switch { +	case c.isPtr: +		code = newOpCode(ctx, c.typ, OpUintPtr) +	case c.isString: +		code = newOpCode(ctx, c.typ, OpUintString) +	default: +		code = newOpCode(ctx, c.typ, OpUint) +	} +	code.NumBitSize = c.bitSize +	ctx.incIndex() +	return Opcodes{code} +} + +func (c *UintCode) Filter(_ *FieldQuery) Code { +	return c +} + +type FloatCode struct { +	typ     *runtime.Type +	bitSize uint8 +	isPtr   bool +} + +func (c *FloatCode) Kind() CodeKind { +	return CodeKindFloat +} + +func (c *FloatCode) ToOpcode(ctx *compileContext) Opcodes { +	var code *Opcode +	switch { +	case c.isPtr: +		switch c.bitSize { +		case 32: +			code = newOpCode(ctx, c.typ, OpFloat32Ptr) +		default: +			code = newOpCode(ctx, c.typ, OpFloat64Ptr) +		} +	default: +		switch c.bitSize { +		case 32: +			code = newOpCode(ctx, c.typ, OpFloat32) +		default: +			code = newOpCode(ctx, c.typ, OpFloat64) +		} +	} +	ctx.incIndex() +	return Opcodes{code} +} + +func (c *FloatCode) Filter(_ *FieldQuery) Code { +	return c +} + +type StringCode struct { +	typ   *runtime.Type +	isPtr bool +} + +func (c *StringCode) Kind() CodeKind { +	return CodeKindString +} + +func (c *StringCode) ToOpcode(ctx *compileContext) Opcodes { +	isJSONNumberType := c.typ == runtime.Type2RType(jsonNumberType) +	var code *Opcode +	if c.isPtr { +		if isJSONNumberType { +			code = newOpCode(ctx, c.typ, OpNumberPtr) +		} else { +			code = newOpCode(ctx, c.typ, OpStringPtr) +		} +	} else { +		if isJSONNumberType { +			code = newOpCode(ctx, c.typ, OpNumber) +		} else { +			code = newOpCode(ctx, c.typ, OpString) +		} +	} +	ctx.incIndex() +	return Opcodes{code} +} + +func (c *StringCode) Filter(_ *FieldQuery) Code { +	return c +} + +type BoolCode struct { +	typ   *runtime.Type +	isPtr bool +} + +func (c *BoolCode) Kind() CodeKind { +	return CodeKindBool +} + +func (c *BoolCode) ToOpcode(ctx *compileContext) Opcodes { +	var code *Opcode +	switch { +	case c.isPtr: +		code = newOpCode(ctx, c.typ, OpBoolPtr) +	default: +		code = newOpCode(ctx, c.typ, OpBool) +	} +	ctx.incIndex() +	return Opcodes{code} +} + +func (c *BoolCode) Filter(_ *FieldQuery) Code { +	return c +} + +type BytesCode struct { +	typ   *runtime.Type +	isPtr bool +} + +func (c *BytesCode) Kind() CodeKind { +	return CodeKindBytes +} + +func (c *BytesCode) ToOpcode(ctx *compileContext) Opcodes { +	var code *Opcode +	switch { +	case c.isPtr: +		code = newOpCode(ctx, c.typ, OpBytesPtr) +	default: +		code = newOpCode(ctx, c.typ, OpBytes) +	} +	ctx.incIndex() +	return Opcodes{code} +} + +func (c *BytesCode) Filter(_ *FieldQuery) Code { +	return c +} + +type SliceCode struct { +	typ   *runtime.Type +	value Code +} + +func (c *SliceCode) Kind() CodeKind { +	return CodeKindSlice +} + +func (c *SliceCode) ToOpcode(ctx *compileContext) Opcodes { +	// header => opcode => elem => end +	//             ^        | +	//             |________| +	size := c.typ.Elem().Size() +	header := newSliceHeaderCode(ctx, c.typ) +	ctx.incIndex() + +	ctx.incIndent() +	codes := c.value.ToOpcode(ctx) +	ctx.decIndent() + +	codes.First().Flags |= IndirectFlags +	elemCode := newSliceElemCode(ctx, c.typ.Elem(), header, size) +	ctx.incIndex() +	end := newOpCode(ctx, c.typ, OpSliceEnd) +	ctx.incIndex() +	header.End = end +	header.Next = codes.First() +	codes.Last().Next = elemCode +	elemCode.Next = codes.First() +	elemCode.End = end +	return Opcodes{header}.Add(codes...).Add(elemCode).Add(end) +} + +func (c *SliceCode) Filter(_ *FieldQuery) Code { +	return c +} + +type ArrayCode struct { +	typ   *runtime.Type +	value Code +} + +func (c *ArrayCode) Kind() CodeKind { +	return CodeKindArray +} + +func (c *ArrayCode) ToOpcode(ctx *compileContext) Opcodes { +	// header => opcode => elem => end +	//             ^        | +	//             |________| +	elem := c.typ.Elem() +	alen := c.typ.Len() +	size := elem.Size() + +	header := newArrayHeaderCode(ctx, c.typ, alen) +	ctx.incIndex() + +	ctx.incIndent() +	codes := c.value.ToOpcode(ctx) +	ctx.decIndent() + +	codes.First().Flags |= IndirectFlags + +	elemCode := newArrayElemCode(ctx, elem, header, alen, size) +	ctx.incIndex() + +	end := newOpCode(ctx, c.typ, OpArrayEnd) +	ctx.incIndex() + +	header.End = end +	header.Next = codes.First() +	codes.Last().Next = elemCode +	elemCode.Next = codes.First() +	elemCode.End = end + +	return Opcodes{header}.Add(codes...).Add(elemCode).Add(end) +} + +func (c *ArrayCode) Filter(_ *FieldQuery) Code { +	return c +} + +type MapCode struct { +	typ   *runtime.Type +	key   Code +	value Code +} + +func (c *MapCode) Kind() CodeKind { +	return CodeKindMap +} + +func (c *MapCode) ToOpcode(ctx *compileContext) Opcodes { +	// header => code => value => code => key => code => value => code => end +	//                                     ^                       | +	//                                     |_______________________| +	header := newMapHeaderCode(ctx, c.typ) +	ctx.incIndex() + +	keyCodes := c.key.ToOpcode(ctx) + +	value := newMapValueCode(ctx, c.typ.Elem(), header) +	ctx.incIndex() + +	ctx.incIndent() +	valueCodes := c.value.ToOpcode(ctx) +	ctx.decIndent() + +	valueCodes.First().Flags |= IndirectFlags + +	key := newMapKeyCode(ctx, c.typ.Key(), header) +	ctx.incIndex() + +	end := newMapEndCode(ctx, c.typ, header) +	ctx.incIndex() + +	header.Next = keyCodes.First() +	keyCodes.Last().Next = value +	value.Next = valueCodes.First() +	valueCodes.Last().Next = key +	key.Next = keyCodes.First() + +	header.End = end +	key.End = end +	value.End = end +	return Opcodes{header}.Add(keyCodes...).Add(value).Add(valueCodes...).Add(key).Add(end) +} + +func (c *MapCode) Filter(_ *FieldQuery) Code { +	return c +} + +type StructCode struct { +	typ                       *runtime.Type +	fields                    []*StructFieldCode +	isPtr                     bool +	disableIndirectConversion bool +	isIndirect                bool +	isRecursive               bool +} + +func (c *StructCode) Kind() CodeKind { +	return CodeKindStruct +} + +func (c *StructCode) lastFieldCode(field *StructFieldCode, firstField *Opcode) *Opcode { +	if isEmbeddedStruct(field) { +		return c.lastAnonymousFieldCode(firstField) +	} +	lastField := firstField +	for lastField.NextField != nil { +		lastField = lastField.NextField +	} +	return lastField +} + +func (c *StructCode) lastAnonymousFieldCode(firstField *Opcode) *Opcode { +	// firstField is special StructHead operation for anonymous structure. +	// So, StructHead's next operation is truly struct head operation. +	lastField := firstField.Next +	for lastField.NextField != nil { +		lastField = lastField.NextField +	} +	return lastField +} + +func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes { +	// header => code => structField => code => end +	//                        ^          | +	//                        |__________| +	if c.isRecursive { +		recursive := newRecursiveCode(ctx, c.typ, &CompiledCode{}) +		recursive.Type = c.typ +		ctx.incIndex() +		*ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive) +		return Opcodes{recursive} +	} +	codes := Opcodes{} +	var prevField *Opcode +	ctx.incIndent() +	for idx, field := range c.fields { +		isFirstField := idx == 0 +		isEndField := idx == len(c.fields)-1 +		fieldCodes := field.ToOpcode(ctx, isFirstField, isEndField) +		for _, code := range fieldCodes { +			if c.isIndirect { +				code.Flags |= IndirectFlags +			} +		} +		firstField := fieldCodes.First() +		if len(codes) > 0 { +			codes.Last().Next = firstField +			firstField.Idx = codes.First().Idx +		} +		if prevField != nil { +			prevField.NextField = firstField +		} +		if isEndField { +			endField := fieldCodes.Last() +			if isEmbeddedStruct(field) { +				firstField.End = endField +				lastField := c.lastAnonymousFieldCode(firstField) +				lastField.NextField = endField +			} +			if len(codes) > 0 { +				codes.First().End = endField +			} else { +				firstField.End = endField +			} +			codes = codes.Add(fieldCodes...) +			break +		} +		prevField = c.lastFieldCode(field, firstField) +		codes = codes.Add(fieldCodes...) +	} +	if len(codes) == 0 { +		head := &Opcode{ +			Op:         OpStructHead, +			Idx:        opcodeOffset(ctx.ptrIndex), +			Type:       c.typ, +			DisplayIdx: ctx.opcodeIndex, +			Indent:     ctx.indent, +		} +		ctx.incOpcodeIndex() +		end := &Opcode{ +			Op:         OpStructEnd, +			Idx:        opcodeOffset(ctx.ptrIndex), +			DisplayIdx: ctx.opcodeIndex, +			Indent:     ctx.indent, +		} +		head.NextField = end +		head.Next = end +		head.End = end +		codes = codes.Add(head, end) +		ctx.incIndex() +	} +	ctx.decIndent() +	ctx.structTypeToCodes[uintptr(unsafe.Pointer(c.typ))] = codes +	return codes +} + +func (c *StructCode) ToAnonymousOpcode(ctx *compileContext) Opcodes { +	// header => code => structField => code => end +	//                        ^          | +	//                        |__________| +	if c.isRecursive { +		recursive := newRecursiveCode(ctx, c.typ, &CompiledCode{}) +		recursive.Type = c.typ +		ctx.incIndex() +		*ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive) +		return Opcodes{recursive} +	} +	codes := Opcodes{} +	var prevField *Opcode +	for idx, field := range c.fields { +		isFirstField := idx == 0 +		isEndField := idx == len(c.fields)-1 +		fieldCodes := field.ToAnonymousOpcode(ctx, isFirstField, isEndField) +		for _, code := range fieldCodes { +			if c.isIndirect { +				code.Flags |= IndirectFlags +			} +		} +		firstField := fieldCodes.First() +		if len(codes) > 0 { +			codes.Last().Next = firstField +			firstField.Idx = codes.First().Idx +		} +		if prevField != nil { +			prevField.NextField = firstField +		} +		if isEndField { +			lastField := fieldCodes.Last() +			if len(codes) > 0 { +				codes.First().End = lastField +			} else { +				firstField.End = lastField +			} +		} +		prevField = firstField +		codes = codes.Add(fieldCodes...) +	} +	return codes +} + +func (c *StructCode) removeFieldsByTags(tags runtime.StructTags) { +	fields := make([]*StructFieldCode, 0, len(c.fields)) +	for _, field := range c.fields { +		if field.isAnonymous { +			structCode := field.getAnonymousStruct() +			if structCode != nil && !structCode.isRecursive { +				structCode.removeFieldsByTags(tags) +				if len(structCode.fields) > 0 { +					fields = append(fields, field) +				} +				continue +			} +		} +		if tags.ExistsKey(field.key) { +			continue +		} +		fields = append(fields, field) +	} +	c.fields = fields +} + +func (c *StructCode) enableIndirect() { +	if c.isIndirect { +		return +	} +	c.isIndirect = true +	if len(c.fields) == 0 { +		return +	} +	structCode := c.fields[0].getStruct() +	if structCode == nil { +		return +	} +	structCode.enableIndirect() +} + +func (c *StructCode) Filter(query *FieldQuery) Code { +	fieldMap := map[string]*FieldQuery{} +	for _, field := range query.Fields { +		fieldMap[field.Name] = field +	} +	fields := make([]*StructFieldCode, 0, len(c.fields)) +	for _, field := range c.fields { +		query, exists := fieldMap[field.key] +		if !exists { +			continue +		} +		fieldCode := &StructFieldCode{ +			typ:                field.typ, +			key:                field.key, +			tag:                field.tag, +			value:              field.value, +			offset:             field.offset, +			isAnonymous:        field.isAnonymous, +			isTaggedKey:        field.isTaggedKey, +			isNilableType:      field.isNilableType, +			isNilCheck:         field.isNilCheck, +			isAddrForMarshaler: field.isAddrForMarshaler, +			isNextOpPtrType:    field.isNextOpPtrType, +		} +		if len(query.Fields) > 0 { +			fieldCode.value = fieldCode.value.Filter(query) +		} +		fields = append(fields, fieldCode) +	} +	return &StructCode{ +		typ:                       c.typ, +		fields:                    fields, +		isPtr:                     c.isPtr, +		disableIndirectConversion: c.disableIndirectConversion, +		isIndirect:                c.isIndirect, +		isRecursive:               c.isRecursive, +	} +} + +type StructFieldCode struct { +	typ                *runtime.Type +	key                string +	tag                *runtime.StructTag +	value              Code +	offset             uintptr +	isAnonymous        bool +	isTaggedKey        bool +	isNilableType      bool +	isNilCheck         bool +	isAddrForMarshaler bool +	isNextOpPtrType    bool +	isMarshalerContext bool +} + +func (c *StructFieldCode) getStruct() *StructCode { +	value := c.value +	ptr, ok := value.(*PtrCode) +	if ok { +		value = ptr.value +	} +	structCode, ok := value.(*StructCode) +	if ok { +		return structCode +	} +	return nil +} + +func (c *StructFieldCode) getAnonymousStruct() *StructCode { +	if !c.isAnonymous { +		return nil +	} +	return c.getStruct() +} + +func optimizeStructHeader(code *Opcode, tag *runtime.StructTag) OpType { +	headType := code.ToHeaderType(tag.IsString) +	if tag.IsOmitEmpty { +		headType = headType.HeadToOmitEmptyHead() +	} +	return headType +} + +func optimizeStructField(code *Opcode, tag *runtime.StructTag) OpType { +	fieldType := code.ToFieldType(tag.IsString) +	if tag.IsOmitEmpty { +		fieldType = fieldType.FieldToOmitEmptyField() +	} +	return fieldType +} + +func (c *StructFieldCode) headerOpcodes(ctx *compileContext, field *Opcode, valueCodes Opcodes) Opcodes { +	value := valueCodes.First() +	op := optimizeStructHeader(value, c.tag) +	field.Op = op +	if value.Flags&MarshalerContextFlags != 0 { +		field.Flags |= MarshalerContextFlags +	} +	field.NumBitSize = value.NumBitSize +	field.PtrNum = value.PtrNum +	field.FieldQuery = value.FieldQuery +	fieldCodes := Opcodes{field} +	if op.IsMultipleOpHead() { +		field.Next = value +		fieldCodes = fieldCodes.Add(valueCodes...) +	} else { +		ctx.decIndex() +	} +	return fieldCodes +} + +func (c *StructFieldCode) fieldOpcodes(ctx *compileContext, field *Opcode, valueCodes Opcodes) Opcodes { +	value := valueCodes.First() +	op := optimizeStructField(value, c.tag) +	field.Op = op +	if value.Flags&MarshalerContextFlags != 0 { +		field.Flags |= MarshalerContextFlags +	} +	field.NumBitSize = value.NumBitSize +	field.PtrNum = value.PtrNum +	field.FieldQuery = value.FieldQuery + +	fieldCodes := Opcodes{field} +	if op.IsMultipleOpField() { +		field.Next = value +		fieldCodes = fieldCodes.Add(valueCodes...) +	} else { +		ctx.decIndex() +	} +	return fieldCodes +} + +func (c *StructFieldCode) addStructEndCode(ctx *compileContext, codes Opcodes) Opcodes { +	end := &Opcode{ +		Op:         OpStructEnd, +		Idx:        opcodeOffset(ctx.ptrIndex), +		DisplayIdx: ctx.opcodeIndex, +		Indent:     ctx.indent, +	} +	codes.Last().Next = end +	codes.First().NextField = end +	codes = codes.Add(end) +	ctx.incOpcodeIndex() +	return codes +} + +func (c *StructFieldCode) structKey(ctx *compileContext) string { +	if ctx.escapeKey { +		rctx := &RuntimeContext{Option: &Option{Flag: HTMLEscapeOption}} +		return fmt.Sprintf(`%s:`, string(AppendString(rctx, []byte{}, c.key))) +	} +	return fmt.Sprintf(`"%s":`, c.key) +} + +func (c *StructFieldCode) flags() OpFlags { +	var flags OpFlags +	if c.isTaggedKey { +		flags |= IsTaggedKeyFlags +	} +	if c.isNilableType { +		flags |= IsNilableTypeFlags +	} +	if c.isNilCheck { +		flags |= NilCheckFlags +	} +	if c.isAddrForMarshaler { +		flags |= AddrForMarshalerFlags +	} +	if c.isNextOpPtrType { +		flags |= IsNextOpPtrTypeFlags +	} +	if c.isAnonymous { +		flags |= AnonymousKeyFlags +	} +	if c.isMarshalerContext { +		flags |= MarshalerContextFlags +	} +	return flags +} + +func (c *StructFieldCode) toValueOpcodes(ctx *compileContext) Opcodes { +	if c.isAnonymous { +		anonymCode, ok := c.value.(AnonymousCode) +		if ok { +			return anonymCode.ToAnonymousOpcode(ctx) +		} +	} +	return c.value.ToOpcode(ctx) +} + +func (c *StructFieldCode) ToOpcode(ctx *compileContext, isFirstField, isEndField bool) Opcodes { +	field := &Opcode{ +		Idx:        opcodeOffset(ctx.ptrIndex), +		Flags:      c.flags(), +		Key:        c.structKey(ctx), +		Offset:     uint32(c.offset), +		Type:       c.typ, +		DisplayIdx: ctx.opcodeIndex, +		Indent:     ctx.indent, +		DisplayKey: c.key, +	} +	ctx.incIndex() +	valueCodes := c.toValueOpcodes(ctx) +	if isFirstField { +		codes := c.headerOpcodes(ctx, field, valueCodes) +		if isEndField { +			codes = c.addStructEndCode(ctx, codes) +		} +		return codes +	} +	codes := c.fieldOpcodes(ctx, field, valueCodes) +	if isEndField { +		if isEnableStructEndOptimization(c.value) { +			field.Op = field.Op.FieldToEnd() +		} else { +			codes = c.addStructEndCode(ctx, codes) +		} +	} +	return codes +} + +func (c *StructFieldCode) ToAnonymousOpcode(ctx *compileContext, isFirstField, isEndField bool) Opcodes { +	field := &Opcode{ +		Idx:        opcodeOffset(ctx.ptrIndex), +		Flags:      c.flags() | AnonymousHeadFlags, +		Key:        c.structKey(ctx), +		Offset:     uint32(c.offset), +		Type:       c.typ, +		DisplayIdx: ctx.opcodeIndex, +		Indent:     ctx.indent, +		DisplayKey: c.key, +	} +	ctx.incIndex() +	valueCodes := c.toValueOpcodes(ctx) +	if isFirstField { +		return c.headerOpcodes(ctx, field, valueCodes) +	} +	return c.fieldOpcodes(ctx, field, valueCodes) +} + +func isEnableStructEndOptimization(value Code) bool { +	switch value.Kind() { +	case CodeKindInt, +		CodeKindUint, +		CodeKindFloat, +		CodeKindString, +		CodeKindBool, +		CodeKindBytes: +		return true +	case CodeKindPtr: +		return isEnableStructEndOptimization(value.(*PtrCode).value) +	default: +		return false +	} +} + +type InterfaceCode struct { +	typ        *runtime.Type +	fieldQuery *FieldQuery +	isPtr      bool +} + +func (c *InterfaceCode) Kind() CodeKind { +	return CodeKindInterface +} + +func (c *InterfaceCode) ToOpcode(ctx *compileContext) Opcodes { +	var code *Opcode +	switch { +	case c.isPtr: +		code = newOpCode(ctx, c.typ, OpInterfacePtr) +	default: +		code = newOpCode(ctx, c.typ, OpInterface) +	} +	code.FieldQuery = c.fieldQuery +	if c.typ.NumMethod() > 0 { +		code.Flags |= NonEmptyInterfaceFlags +	} +	ctx.incIndex() +	return Opcodes{code} +} + +func (c *InterfaceCode) Filter(query *FieldQuery) Code { +	return &InterfaceCode{ +		typ:        c.typ, +		fieldQuery: query, +		isPtr:      c.isPtr, +	} +} + +type MarshalJSONCode struct { +	typ                *runtime.Type +	fieldQuery         *FieldQuery +	isAddrForMarshaler bool +	isNilableType      bool +	isMarshalerContext bool +} + +func (c *MarshalJSONCode) Kind() CodeKind { +	return CodeKindMarshalJSON +} + +func (c *MarshalJSONCode) ToOpcode(ctx *compileContext) Opcodes { +	code := newOpCode(ctx, c.typ, OpMarshalJSON) +	code.FieldQuery = c.fieldQuery +	if c.isAddrForMarshaler { +		code.Flags |= AddrForMarshalerFlags +	} +	if c.isMarshalerContext { +		code.Flags |= MarshalerContextFlags +	} +	if c.isNilableType { +		code.Flags |= IsNilableTypeFlags +	} else { +		code.Flags &= ^IsNilableTypeFlags +	} +	ctx.incIndex() +	return Opcodes{code} +} + +func (c *MarshalJSONCode) Filter(query *FieldQuery) Code { +	return &MarshalJSONCode{ +		typ:                c.typ, +		fieldQuery:         query, +		isAddrForMarshaler: c.isAddrForMarshaler, +		isNilableType:      c.isNilableType, +		isMarshalerContext: c.isMarshalerContext, +	} +} + +type MarshalTextCode struct { +	typ                *runtime.Type +	fieldQuery         *FieldQuery +	isAddrForMarshaler bool +	isNilableType      bool +} + +func (c *MarshalTextCode) Kind() CodeKind { +	return CodeKindMarshalText +} + +func (c *MarshalTextCode) ToOpcode(ctx *compileContext) Opcodes { +	code := newOpCode(ctx, c.typ, OpMarshalText) +	code.FieldQuery = c.fieldQuery +	if c.isAddrForMarshaler { +		code.Flags |= AddrForMarshalerFlags +	} +	if c.isNilableType { +		code.Flags |= IsNilableTypeFlags +	} else { +		code.Flags &= ^IsNilableTypeFlags +	} +	ctx.incIndex() +	return Opcodes{code} +} + +func (c *MarshalTextCode) Filter(query *FieldQuery) Code { +	return &MarshalTextCode{ +		typ:                c.typ, +		fieldQuery:         query, +		isAddrForMarshaler: c.isAddrForMarshaler, +		isNilableType:      c.isNilableType, +	} +} + +type PtrCode struct { +	typ    *runtime.Type +	value  Code +	ptrNum uint8 +} + +func (c *PtrCode) Kind() CodeKind { +	return CodeKindPtr +} + +func (c *PtrCode) ToOpcode(ctx *compileContext) Opcodes { +	codes := c.value.ToOpcode(ctx) +	codes.First().Op = convertPtrOp(codes.First()) +	codes.First().PtrNum = c.ptrNum +	return codes +} + +func (c *PtrCode) ToAnonymousOpcode(ctx *compileContext) Opcodes { +	var codes Opcodes +	anonymCode, ok := c.value.(AnonymousCode) +	if ok { +		codes = anonymCode.ToAnonymousOpcode(ctx) +	} else { +		codes = c.value.ToOpcode(ctx) +	} +	codes.First().Op = convertPtrOp(codes.First()) +	codes.First().PtrNum = c.ptrNum +	return codes +} + +func (c *PtrCode) Filter(query *FieldQuery) Code { +	return &PtrCode{ +		typ:    c.typ, +		value:  c.value.Filter(query), +		ptrNum: c.ptrNum, +	} +} + +func convertPtrOp(code *Opcode) OpType { +	ptrHeadOp := code.Op.HeadToPtrHead() +	if code.Op != ptrHeadOp { +		if code.PtrNum > 0 { +			// ptr field and ptr head +			code.PtrNum-- +		} +		return ptrHeadOp +	} +	switch code.Op { +	case OpInt: +		return OpIntPtr +	case OpUint: +		return OpUintPtr +	case OpFloat32: +		return OpFloat32Ptr +	case OpFloat64: +		return OpFloat64Ptr +	case OpString: +		return OpStringPtr +	case OpBool: +		return OpBoolPtr +	case OpBytes: +		return OpBytesPtr +	case OpNumber: +		return OpNumberPtr +	case OpArray: +		return OpArrayPtr +	case OpSlice: +		return OpSlicePtr +	case OpMap: +		return OpMapPtr +	case OpMarshalJSON: +		return OpMarshalJSONPtr +	case OpMarshalText: +		return OpMarshalTextPtr +	case OpInterface: +		return OpInterfacePtr +	case OpRecursive: +		return OpRecursivePtr +	} +	return code.Op +} + +func isEmbeddedStruct(field *StructFieldCode) bool { +	if !field.isAnonymous { +		return false +	} +	t := field.typ +	if t.Kind() == reflect.Ptr { +		t = t.Elem() +	} +	return t.Kind() == reflect.Struct +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compact.go b/vendor/github.com/goccy/go-json/internal/encoder/compact.go new file mode 100644 index 000000000..0eb9545d8 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/compact.go @@ -0,0 +1,286 @@ +package encoder + +import ( +	"bytes" +	"fmt" +	"strconv" +	"unsafe" + +	"github.com/goccy/go-json/internal/errors" +) + +var ( +	isWhiteSpace = [256]bool{ +		' ':  true, +		'\n': true, +		'\t': true, +		'\r': true, +	} +	isHTMLEscapeChar = [256]bool{ +		'<': true, +		'>': true, +		'&': true, +	} +	nul = byte('\000') +) + +func Compact(buf *bytes.Buffer, src []byte, escape bool) error { +	if len(src) == 0 { +		return errors.ErrUnexpectedEndOfJSON("", 0) +	} +	buf.Grow(len(src)) +	dst := buf.Bytes() + +	ctx := TakeRuntimeContext() +	ctxBuf := ctx.Buf[:0] +	ctxBuf = append(append(ctxBuf, src...), nul) +	ctx.Buf = ctxBuf + +	if err := compactAndWrite(buf, dst, ctxBuf, escape); err != nil { +		ReleaseRuntimeContext(ctx) +		return err +	} +	ReleaseRuntimeContext(ctx) +	return nil +} + +func compactAndWrite(buf *bytes.Buffer, dst []byte, src []byte, escape bool) error { +	dst, err := compact(dst, src, escape) +	if err != nil { +		return err +	} +	if _, err := buf.Write(dst); err != nil { +		return err +	} +	return nil +} + +func compact(dst, src []byte, escape bool) ([]byte, error) { +	buf, cursor, err := compactValue(dst, src, 0, escape) +	if err != nil { +		return nil, err +	} +	if err := validateEndBuf(src, cursor); err != nil { +		return nil, err +	} +	return buf, nil +} + +func validateEndBuf(src []byte, cursor int64) error { +	for { +		switch src[cursor] { +		case ' ', '\t', '\n', '\r': +			cursor++ +			continue +		case nul: +			return nil +		} +		return errors.ErrSyntax( +			fmt.Sprintf("invalid character '%c' after top-level value", src[cursor]), +			cursor+1, +		) +	} +} + +func skipWhiteSpace(buf []byte, cursor int64) int64 { +LOOP: +	if isWhiteSpace[buf[cursor]] { +		cursor++ +		goto LOOP +	} +	return cursor +} + +func compactValue(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) { +	for { +		switch src[cursor] { +		case ' ', '\t', '\n', '\r': +			cursor++ +			continue +		case '{': +			return compactObject(dst, src, cursor, escape) +		case '}': +			return nil, 0, errors.ErrSyntax("unexpected character '}'", cursor) +		case '[': +			return compactArray(dst, src, cursor, escape) +		case ']': +			return nil, 0, errors.ErrSyntax("unexpected character ']'", cursor) +		case '"': +			return compactString(dst, src, cursor, escape) +		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': +			return compactNumber(dst, src, cursor) +		case 't': +			return compactTrue(dst, src, cursor) +		case 'f': +			return compactFalse(dst, src, cursor) +		case 'n': +			return compactNull(dst, src, cursor) +		default: +			return nil, 0, errors.ErrSyntax(fmt.Sprintf("unexpected character '%c'", src[cursor]), cursor) +		} +	} +} + +func compactObject(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) { +	if src[cursor] == '{' { +		dst = append(dst, '{') +	} else { +		return nil, 0, errors.ErrExpected("expected { character for object value", cursor) +	} +	cursor = skipWhiteSpace(src, cursor+1) +	if src[cursor] == '}' { +		dst = append(dst, '}') +		return dst, cursor + 1, nil +	} +	var err error +	for { +		cursor = skipWhiteSpace(src, cursor) +		dst, cursor, err = compactString(dst, src, cursor, escape) +		if err != nil { +			return nil, 0, err +		} +		cursor = skipWhiteSpace(src, cursor) +		if src[cursor] != ':' { +			return nil, 0, errors.ErrExpected("colon after object key", cursor) +		} +		dst = append(dst, ':') +		dst, cursor, err = compactValue(dst, src, cursor+1, escape) +		if err != nil { +			return nil, 0, err +		} +		cursor = skipWhiteSpace(src, cursor) +		switch src[cursor] { +		case '}': +			dst = append(dst, '}') +			cursor++ +			return dst, cursor, nil +		case ',': +			dst = append(dst, ',') +		default: +			return nil, 0, errors.ErrExpected("comma after object value", cursor) +		} +		cursor++ +	} +} + +func compactArray(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) { +	if src[cursor] == '[' { +		dst = append(dst, '[') +	} else { +		return nil, 0, errors.ErrExpected("expected [ character for array value", cursor) +	} +	cursor = skipWhiteSpace(src, cursor+1) +	if src[cursor] == ']' { +		dst = append(dst, ']') +		return dst, cursor + 1, nil +	} +	var err error +	for { +		dst, cursor, err = compactValue(dst, src, cursor, escape) +		if err != nil { +			return nil, 0, err +		} +		cursor = skipWhiteSpace(src, cursor) +		switch src[cursor] { +		case ']': +			dst = append(dst, ']') +			cursor++ +			return dst, cursor, nil +		case ',': +			dst = append(dst, ',') +		default: +			return nil, 0, errors.ErrExpected("comma after array value", cursor) +		} +		cursor++ +	} +} + +func compactString(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) { +	if src[cursor] != '"' { +		return nil, 0, errors.ErrInvalidCharacter(src[cursor], "string", cursor) +	} +	start := cursor +	for { +		cursor++ +		c := src[cursor] +		if escape { +			if isHTMLEscapeChar[c] { +				dst = append(dst, src[start:cursor]...) +				dst = append(dst, `\u00`...) +				dst = append(dst, hex[c>>4], hex[c&0xF]) +				start = cursor + 1 +			} else if c == 0xE2 && cursor+2 < int64(len(src)) && src[cursor+1] == 0x80 && src[cursor+2]&^1 == 0xA8 { +				dst = append(dst, src[start:cursor]...) +				dst = append(dst, `\u202`...) +				dst = append(dst, hex[src[cursor+2]&0xF]) +				cursor += 2 +				start = cursor + 3 +			} +		} +		switch c { +		case '\\': +			cursor++ +			if src[cursor] == nul { +				return nil, 0, errors.ErrUnexpectedEndOfJSON("string", int64(len(src))) +			} +		case '"': +			cursor++ +			return append(dst, src[start:cursor]...), cursor, nil +		case nul: +			return nil, 0, errors.ErrUnexpectedEndOfJSON("string", int64(len(src))) +		} +	} +} + +func compactNumber(dst, src []byte, cursor int64) ([]byte, int64, error) { +	start := cursor +	for { +		cursor++ +		if floatTable[src[cursor]] { +			continue +		} +		break +	} +	num := src[start:cursor] +	if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&num)), 64); err != nil { +		return nil, 0, err +	} +	dst = append(dst, num...) +	return dst, cursor, nil +} + +func compactTrue(dst, src []byte, cursor int64) ([]byte, int64, error) { +	if cursor+3 >= int64(len(src)) { +		return nil, 0, errors.ErrUnexpectedEndOfJSON("true", cursor) +	} +	if !bytes.Equal(src[cursor:cursor+4], []byte(`true`)) { +		return nil, 0, errors.ErrInvalidCharacter(src[cursor], "true", cursor) +	} +	dst = append(dst, "true"...) +	cursor += 4 +	return dst, cursor, nil +} + +func compactFalse(dst, src []byte, cursor int64) ([]byte, int64, error) { +	if cursor+4 >= int64(len(src)) { +		return nil, 0, errors.ErrUnexpectedEndOfJSON("false", cursor) +	} +	if !bytes.Equal(src[cursor:cursor+5], []byte(`false`)) { +		return nil, 0, errors.ErrInvalidCharacter(src[cursor], "false", cursor) +	} +	dst = append(dst, "false"...) +	cursor += 5 +	return dst, cursor, nil +} + +func compactNull(dst, src []byte, cursor int64) ([]byte, int64, error) { +	if cursor+3 >= int64(len(src)) { +		return nil, 0, errors.ErrUnexpectedEndOfJSON("null", cursor) +	} +	if !bytes.Equal(src[cursor:cursor+4], []byte(`null`)) { +		return nil, 0, errors.ErrInvalidCharacter(src[cursor], "null", cursor) +	} +	dst = append(dst, "null"...) +	cursor += 4 +	return dst, cursor, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compiler.go b/vendor/github.com/goccy/go-json/internal/encoder/compiler.go new file mode 100644 index 000000000..bf5e0f947 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/compiler.go @@ -0,0 +1,930 @@ +package encoder + +import ( +	"context" +	"encoding" +	"encoding/json" +	"reflect" +	"sync/atomic" +	"unsafe" + +	"github.com/goccy/go-json/internal/errors" +	"github.com/goccy/go-json/internal/runtime" +) + +type marshalerContext interface { +	MarshalJSON(context.Context) ([]byte, error) +} + +var ( +	marshalJSONType        = reflect.TypeOf((*json.Marshaler)(nil)).Elem() +	marshalJSONContextType = reflect.TypeOf((*marshalerContext)(nil)).Elem() +	marshalTextType        = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() +	jsonNumberType         = reflect.TypeOf(json.Number("")) +	cachedOpcodeSets       []*OpcodeSet +	cachedOpcodeMap        unsafe.Pointer // map[uintptr]*OpcodeSet +	typeAddr               *runtime.TypeAddr +) + +func init() { +	typeAddr = runtime.AnalyzeTypeAddr() +	if typeAddr == nil { +		typeAddr = &runtime.TypeAddr{} +	} +	cachedOpcodeSets = make([]*OpcodeSet, typeAddr.AddrRange>>typeAddr.AddrShift+1) +} + +func loadOpcodeMap() map[uintptr]*OpcodeSet { +	p := atomic.LoadPointer(&cachedOpcodeMap) +	return *(*map[uintptr]*OpcodeSet)(unsafe.Pointer(&p)) +} + +func storeOpcodeSet(typ uintptr, set *OpcodeSet, m map[uintptr]*OpcodeSet) { +	newOpcodeMap := make(map[uintptr]*OpcodeSet, len(m)+1) +	newOpcodeMap[typ] = set + +	for k, v := range m { +		newOpcodeMap[k] = v +	} + +	atomic.StorePointer(&cachedOpcodeMap, *(*unsafe.Pointer)(unsafe.Pointer(&newOpcodeMap))) +} + +func compileToGetCodeSetSlowPath(typeptr uintptr) (*OpcodeSet, error) { +	opcodeMap := loadOpcodeMap() +	if codeSet, exists := opcodeMap[typeptr]; exists { +		return codeSet, nil +	} +	codeSet, err := newCompiler().compile(typeptr) +	if err != nil { +		return nil, err +	} +	storeOpcodeSet(typeptr, codeSet, opcodeMap) +	return codeSet, nil +} + +func getFilteredCodeSetIfNeeded(ctx *RuntimeContext, codeSet *OpcodeSet) (*OpcodeSet, error) { +	if (ctx.Option.Flag & ContextOption) == 0 { +		return codeSet, nil +	} +	query := FieldQueryFromContext(ctx.Option.Context) +	if query == nil { +		return codeSet, nil +	} +	ctx.Option.Flag |= FieldQueryOption +	cacheCodeSet := codeSet.getQueryCache(query.Hash()) +	if cacheCodeSet != nil { +		return cacheCodeSet, nil +	} +	queryCodeSet, err := newCompiler().codeToOpcodeSet(codeSet.Type, codeSet.Code.Filter(query)) +	if err != nil { +		return nil, err +	} +	codeSet.setQueryCache(query.Hash(), queryCodeSet) +	return queryCodeSet, nil +} + +type Compiler struct { +	structTypeToCode map[uintptr]*StructCode +} + +func newCompiler() *Compiler { +	return &Compiler{ +		structTypeToCode: map[uintptr]*StructCode{}, +	} +} + +func (c *Compiler) compile(typeptr uintptr) (*OpcodeSet, error) { +	// noescape trick for header.typ ( reflect.*rtype ) +	typ := *(**runtime.Type)(unsafe.Pointer(&typeptr)) +	code, err := c.typeToCode(typ) +	if err != nil { +		return nil, err +	} +	return c.codeToOpcodeSet(typ, code) +} + +func (c *Compiler) codeToOpcodeSet(typ *runtime.Type, code Code) (*OpcodeSet, error) { +	noescapeKeyCode := c.codeToOpcode(&compileContext{ +		structTypeToCodes: map[uintptr]Opcodes{}, +		recursiveCodes:    &Opcodes{}, +	}, typ, code) +	if err := noescapeKeyCode.Validate(); err != nil { +		return nil, err +	} +	escapeKeyCode := c.codeToOpcode(&compileContext{ +		structTypeToCodes: map[uintptr]Opcodes{}, +		recursiveCodes:    &Opcodes{}, +		escapeKey:         true, +	}, typ, code) +	noescapeKeyCode = copyOpcode(noescapeKeyCode) +	escapeKeyCode = copyOpcode(escapeKeyCode) +	setTotalLengthToInterfaceOp(noescapeKeyCode) +	setTotalLengthToInterfaceOp(escapeKeyCode) +	interfaceNoescapeKeyCode := copyToInterfaceOpcode(noescapeKeyCode) +	interfaceEscapeKeyCode := copyToInterfaceOpcode(escapeKeyCode) +	codeLength := noescapeKeyCode.TotalLength() +	return &OpcodeSet{ +		Type:                     typ, +		NoescapeKeyCode:          noescapeKeyCode, +		EscapeKeyCode:            escapeKeyCode, +		InterfaceNoescapeKeyCode: interfaceNoescapeKeyCode, +		InterfaceEscapeKeyCode:   interfaceEscapeKeyCode, +		CodeLength:               codeLength, +		EndCode:                  ToEndCode(interfaceNoescapeKeyCode), +		Code:                     code, +		QueryCache:               map[string]*OpcodeSet{}, +	}, nil +} + +func (c *Compiler) typeToCode(typ *runtime.Type) (Code, error) { +	switch { +	case c.implementsMarshalJSON(typ): +		return c.marshalJSONCode(typ) +	case c.implementsMarshalText(typ): +		return c.marshalTextCode(typ) +	} + +	isPtr := false +	orgType := typ +	if typ.Kind() == reflect.Ptr { +		typ = typ.Elem() +		isPtr = true +	} +	switch { +	case c.implementsMarshalJSON(typ): +		return c.marshalJSONCode(orgType) +	case c.implementsMarshalText(typ): +		return c.marshalTextCode(orgType) +	} +	switch typ.Kind() { +	case reflect.Slice: +		elem := typ.Elem() +		if elem.Kind() == reflect.Uint8 { +			p := runtime.PtrTo(elem) +			if !c.implementsMarshalJSONType(p) && !p.Implements(marshalTextType) { +				return c.bytesCode(typ, isPtr) +			} +		} +		return c.sliceCode(typ) +	case reflect.Map: +		if isPtr { +			return c.ptrCode(runtime.PtrTo(typ)) +		} +		return c.mapCode(typ) +	case reflect.Struct: +		return c.structCode(typ, isPtr) +	case reflect.Int: +		return c.intCode(typ, isPtr) +	case reflect.Int8: +		return c.int8Code(typ, isPtr) +	case reflect.Int16: +		return c.int16Code(typ, isPtr) +	case reflect.Int32: +		return c.int32Code(typ, isPtr) +	case reflect.Int64: +		return c.int64Code(typ, isPtr) +	case reflect.Uint, reflect.Uintptr: +		return c.uintCode(typ, isPtr) +	case reflect.Uint8: +		return c.uint8Code(typ, isPtr) +	case reflect.Uint16: +		return c.uint16Code(typ, isPtr) +	case reflect.Uint32: +		return c.uint32Code(typ, isPtr) +	case reflect.Uint64: +		return c.uint64Code(typ, isPtr) +	case reflect.Float32: +		return c.float32Code(typ, isPtr) +	case reflect.Float64: +		return c.float64Code(typ, isPtr) +	case reflect.String: +		return c.stringCode(typ, isPtr) +	case reflect.Bool: +		return c.boolCode(typ, isPtr) +	case reflect.Interface: +		return c.interfaceCode(typ, isPtr) +	default: +		if isPtr && typ.Implements(marshalTextType) { +			typ = orgType +		} +		return c.typeToCodeWithPtr(typ, isPtr) +	} +} + +func (c *Compiler) typeToCodeWithPtr(typ *runtime.Type, isPtr bool) (Code, error) { +	switch { +	case c.implementsMarshalJSON(typ): +		return c.marshalJSONCode(typ) +	case c.implementsMarshalText(typ): +		return c.marshalTextCode(typ) +	} +	switch typ.Kind() { +	case reflect.Ptr: +		return c.ptrCode(typ) +	case reflect.Slice: +		elem := typ.Elem() +		if elem.Kind() == reflect.Uint8 { +			p := runtime.PtrTo(elem) +			if !c.implementsMarshalJSONType(p) && !p.Implements(marshalTextType) { +				return c.bytesCode(typ, false) +			} +		} +		return c.sliceCode(typ) +	case reflect.Array: +		return c.arrayCode(typ) +	case reflect.Map: +		return c.mapCode(typ) +	case reflect.Struct: +		return c.structCode(typ, isPtr) +	case reflect.Interface: +		return c.interfaceCode(typ, false) +	case reflect.Int: +		return c.intCode(typ, false) +	case reflect.Int8: +		return c.int8Code(typ, false) +	case reflect.Int16: +		return c.int16Code(typ, false) +	case reflect.Int32: +		return c.int32Code(typ, false) +	case reflect.Int64: +		return c.int64Code(typ, false) +	case reflect.Uint: +		return c.uintCode(typ, false) +	case reflect.Uint8: +		return c.uint8Code(typ, false) +	case reflect.Uint16: +		return c.uint16Code(typ, false) +	case reflect.Uint32: +		return c.uint32Code(typ, false) +	case reflect.Uint64: +		return c.uint64Code(typ, false) +	case reflect.Uintptr: +		return c.uintCode(typ, false) +	case reflect.Float32: +		return c.float32Code(typ, false) +	case reflect.Float64: +		return c.float64Code(typ, false) +	case reflect.String: +		return c.stringCode(typ, false) +	case reflect.Bool: +		return c.boolCode(typ, false) +	} +	return nil, &errors.UnsupportedTypeError{Type: runtime.RType2Type(typ)} +} + +const intSize = 32 << (^uint(0) >> 63) + +//nolint:unparam +func (c *Compiler) intCode(typ *runtime.Type, isPtr bool) (*IntCode, error) { +	return &IntCode{typ: typ, bitSize: intSize, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) int8Code(typ *runtime.Type, isPtr bool) (*IntCode, error) { +	return &IntCode{typ: typ, bitSize: 8, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) int16Code(typ *runtime.Type, isPtr bool) (*IntCode, error) { +	return &IntCode{typ: typ, bitSize: 16, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) int32Code(typ *runtime.Type, isPtr bool) (*IntCode, error) { +	return &IntCode{typ: typ, bitSize: 32, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) int64Code(typ *runtime.Type, isPtr bool) (*IntCode, error) { +	return &IntCode{typ: typ, bitSize: 64, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) uintCode(typ *runtime.Type, isPtr bool) (*UintCode, error) { +	return &UintCode{typ: typ, bitSize: intSize, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) uint8Code(typ *runtime.Type, isPtr bool) (*UintCode, error) { +	return &UintCode{typ: typ, bitSize: 8, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) uint16Code(typ *runtime.Type, isPtr bool) (*UintCode, error) { +	return &UintCode{typ: typ, bitSize: 16, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) uint32Code(typ *runtime.Type, isPtr bool) (*UintCode, error) { +	return &UintCode{typ: typ, bitSize: 32, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) uint64Code(typ *runtime.Type, isPtr bool) (*UintCode, error) { +	return &UintCode{typ: typ, bitSize: 64, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) float32Code(typ *runtime.Type, isPtr bool) (*FloatCode, error) { +	return &FloatCode{typ: typ, bitSize: 32, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) float64Code(typ *runtime.Type, isPtr bool) (*FloatCode, error) { +	return &FloatCode{typ: typ, bitSize: 64, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) stringCode(typ *runtime.Type, isPtr bool) (*StringCode, error) { +	return &StringCode{typ: typ, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) boolCode(typ *runtime.Type, isPtr bool) (*BoolCode, error) { +	return &BoolCode{typ: typ, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) intStringCode(typ *runtime.Type) (*IntCode, error) { +	return &IntCode{typ: typ, bitSize: intSize, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) int8StringCode(typ *runtime.Type) (*IntCode, error) { +	return &IntCode{typ: typ, bitSize: 8, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) int16StringCode(typ *runtime.Type) (*IntCode, error) { +	return &IntCode{typ: typ, bitSize: 16, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) int32StringCode(typ *runtime.Type) (*IntCode, error) { +	return &IntCode{typ: typ, bitSize: 32, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) int64StringCode(typ *runtime.Type) (*IntCode, error) { +	return &IntCode{typ: typ, bitSize: 64, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) uintStringCode(typ *runtime.Type) (*UintCode, error) { +	return &UintCode{typ: typ, bitSize: intSize, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) uint8StringCode(typ *runtime.Type) (*UintCode, error) { +	return &UintCode{typ: typ, bitSize: 8, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) uint16StringCode(typ *runtime.Type) (*UintCode, error) { +	return &UintCode{typ: typ, bitSize: 16, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) uint32StringCode(typ *runtime.Type) (*UintCode, error) { +	return &UintCode{typ: typ, bitSize: 32, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) uint64StringCode(typ *runtime.Type) (*UintCode, error) { +	return &UintCode{typ: typ, bitSize: 64, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) bytesCode(typ *runtime.Type, isPtr bool) (*BytesCode, error) { +	return &BytesCode{typ: typ, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) interfaceCode(typ *runtime.Type, isPtr bool) (*InterfaceCode, error) { +	return &InterfaceCode{typ: typ, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) marshalJSONCode(typ *runtime.Type) (*MarshalJSONCode, error) { +	return &MarshalJSONCode{ +		typ:                typ, +		isAddrForMarshaler: c.isPtrMarshalJSONType(typ), +		isNilableType:      c.isNilableType(typ), +		isMarshalerContext: typ.Implements(marshalJSONContextType) || runtime.PtrTo(typ).Implements(marshalJSONContextType), +	}, nil +} + +//nolint:unparam +func (c *Compiler) marshalTextCode(typ *runtime.Type) (*MarshalTextCode, error) { +	return &MarshalTextCode{ +		typ:                typ, +		isAddrForMarshaler: c.isPtrMarshalTextType(typ), +		isNilableType:      c.isNilableType(typ), +	}, nil +} + +func (c *Compiler) ptrCode(typ *runtime.Type) (*PtrCode, error) { +	code, err := c.typeToCodeWithPtr(typ.Elem(), true) +	if err != nil { +		return nil, err +	} +	ptr, ok := code.(*PtrCode) +	if ok { +		return &PtrCode{typ: typ, value: ptr.value, ptrNum: ptr.ptrNum + 1}, nil +	} +	return &PtrCode{typ: typ, value: code, ptrNum: 1}, nil +} + +func (c *Compiler) sliceCode(typ *runtime.Type) (*SliceCode, error) { +	elem := typ.Elem() +	code, err := c.listElemCode(elem) +	if err != nil { +		return nil, err +	} +	if code.Kind() == CodeKindStruct { +		structCode := code.(*StructCode) +		structCode.enableIndirect() +	} +	return &SliceCode{typ: typ, value: code}, nil +} + +func (c *Compiler) arrayCode(typ *runtime.Type) (*ArrayCode, error) { +	elem := typ.Elem() +	code, err := c.listElemCode(elem) +	if err != nil { +		return nil, err +	} +	if code.Kind() == CodeKindStruct { +		structCode := code.(*StructCode) +		structCode.enableIndirect() +	} +	return &ArrayCode{typ: typ, value: code}, nil +} + +func (c *Compiler) mapCode(typ *runtime.Type) (*MapCode, error) { +	keyCode, err := c.mapKeyCode(typ.Key()) +	if err != nil { +		return nil, err +	} +	valueCode, err := c.mapValueCode(typ.Elem()) +	if err != nil { +		return nil, err +	} +	if valueCode.Kind() == CodeKindStruct { +		structCode := valueCode.(*StructCode) +		structCode.enableIndirect() +	} +	return &MapCode{typ: typ, key: keyCode, value: valueCode}, nil +} + +func (c *Compiler) listElemCode(typ *runtime.Type) (Code, error) { +	switch { +	case c.isPtrMarshalJSONType(typ): +		return c.marshalJSONCode(typ) +	case !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType): +		return c.marshalTextCode(typ) +	case typ.Kind() == reflect.Map: +		return c.ptrCode(runtime.PtrTo(typ)) +	default: +		// isPtr was originally used to indicate whether the type of top level is pointer. +		// However, since the slice/array element is a specification that can get the pointer address, explicitly set isPtr to true. +		// See here for related issues: https://github.com/goccy/go-json/issues/370 +		code, err := c.typeToCodeWithPtr(typ, true) +		if err != nil { +			return nil, err +		} +		ptr, ok := code.(*PtrCode) +		if ok { +			if ptr.value.Kind() == CodeKindMap { +				ptr.ptrNum++ +			} +		} +		return code, nil +	} +} + +func (c *Compiler) mapKeyCode(typ *runtime.Type) (Code, error) { +	switch { +	case c.implementsMarshalJSON(typ): +		return c.marshalJSONCode(typ) +	case c.implementsMarshalText(typ): +		return c.marshalTextCode(typ) +	} +	switch typ.Kind() { +	case reflect.Ptr: +		return c.ptrCode(typ) +	case reflect.String: +		return c.stringCode(typ, false) +	case reflect.Int: +		return c.intStringCode(typ) +	case reflect.Int8: +		return c.int8StringCode(typ) +	case reflect.Int16: +		return c.int16StringCode(typ) +	case reflect.Int32: +		return c.int32StringCode(typ) +	case reflect.Int64: +		return c.int64StringCode(typ) +	case reflect.Uint: +		return c.uintStringCode(typ) +	case reflect.Uint8: +		return c.uint8StringCode(typ) +	case reflect.Uint16: +		return c.uint16StringCode(typ) +	case reflect.Uint32: +		return c.uint32StringCode(typ) +	case reflect.Uint64: +		return c.uint64StringCode(typ) +	case reflect.Uintptr: +		return c.uintStringCode(typ) +	} +	return nil, &errors.UnsupportedTypeError{Type: runtime.RType2Type(typ)} +} + +func (c *Compiler) mapValueCode(typ *runtime.Type) (Code, error) { +	switch typ.Kind() { +	case reflect.Map: +		return c.ptrCode(runtime.PtrTo(typ)) +	default: +		code, err := c.typeToCodeWithPtr(typ, false) +		if err != nil { +			return nil, err +		} +		ptr, ok := code.(*PtrCode) +		if ok { +			if ptr.value.Kind() == CodeKindMap { +				ptr.ptrNum++ +			} +		} +		return code, nil +	} +} + +func (c *Compiler) structCode(typ *runtime.Type, isPtr bool) (*StructCode, error) { +	typeptr := uintptr(unsafe.Pointer(typ)) +	if code, exists := c.structTypeToCode[typeptr]; exists { +		derefCode := *code +		derefCode.isRecursive = true +		return &derefCode, nil +	} +	indirect := runtime.IfaceIndir(typ) +	code := &StructCode{typ: typ, isPtr: isPtr, isIndirect: indirect} +	c.structTypeToCode[typeptr] = code + +	fieldNum := typ.NumField() +	tags := c.typeToStructTags(typ) +	fields := []*StructFieldCode{} +	for i, tag := range tags { +		isOnlyOneFirstField := i == 0 && fieldNum == 1 +		field, err := c.structFieldCode(code, tag, isPtr, isOnlyOneFirstField) +		if err != nil { +			return nil, err +		} +		if field.isAnonymous { +			structCode := field.getAnonymousStruct() +			if structCode != nil { +				structCode.removeFieldsByTags(tags) +				if c.isAssignableIndirect(field, isPtr) { +					if indirect { +						structCode.isIndirect = true +					} else { +						structCode.isIndirect = false +					} +				} +			} +		} else { +			structCode := field.getStruct() +			if structCode != nil { +				if indirect { +					// if parent is indirect type, set child indirect property to true +					structCode.isIndirect = true +				} else { +					// if parent is not indirect type, set child indirect property to false. +					// but if parent's indirect is false and isPtr is true, then indirect must be true. +					// Do this only if indirectConversion is enabled at the end of compileStruct. +					structCode.isIndirect = false +				} +			} +		} +		fields = append(fields, field) +	} +	fieldMap := c.getFieldMap(fields) +	duplicatedFieldMap := c.getDuplicatedFieldMap(fieldMap) +	code.fields = c.filteredDuplicatedFields(fields, duplicatedFieldMap) +	if !code.disableIndirectConversion && !indirect && isPtr { +		code.enableIndirect() +	} +	delete(c.structTypeToCode, typeptr) +	return code, nil +} + +func (c *Compiler) structFieldCode(structCode *StructCode, tag *runtime.StructTag, isPtr, isOnlyOneFirstField bool) (*StructFieldCode, error) { +	field := tag.Field +	fieldType := runtime.Type2RType(field.Type) +	isIndirectSpecialCase := isPtr && isOnlyOneFirstField +	fieldCode := &StructFieldCode{ +		typ:           fieldType, +		key:           tag.Key, +		tag:           tag, +		offset:        field.Offset, +		isAnonymous:   field.Anonymous && !tag.IsTaggedKey, +		isTaggedKey:   tag.IsTaggedKey, +		isNilableType: c.isNilableType(fieldType), +		isNilCheck:    true, +	} +	switch { +	case c.isMovePointerPositionFromHeadToFirstMarshalJSONFieldCase(fieldType, isIndirectSpecialCase): +		code, err := c.marshalJSONCode(fieldType) +		if err != nil { +			return nil, err +		} +		fieldCode.value = code +		fieldCode.isAddrForMarshaler = true +		fieldCode.isNilCheck = false +		structCode.isIndirect = false +		structCode.disableIndirectConversion = true +	case c.isMovePointerPositionFromHeadToFirstMarshalTextFieldCase(fieldType, isIndirectSpecialCase): +		code, err := c.marshalTextCode(fieldType) +		if err != nil { +			return nil, err +		} +		fieldCode.value = code +		fieldCode.isAddrForMarshaler = true +		fieldCode.isNilCheck = false +		structCode.isIndirect = false +		structCode.disableIndirectConversion = true +	case isPtr && c.isPtrMarshalJSONType(fieldType): +		// *struct{ field T } +		// func (*T) MarshalJSON() ([]byte, error) +		code, err := c.marshalJSONCode(fieldType) +		if err != nil { +			return nil, err +		} +		fieldCode.value = code +		fieldCode.isAddrForMarshaler = true +		fieldCode.isNilCheck = false +	case isPtr && c.isPtrMarshalTextType(fieldType): +		// *struct{ field T } +		// func (*T) MarshalText() ([]byte, error) +		code, err := c.marshalTextCode(fieldType) +		if err != nil { +			return nil, err +		} +		fieldCode.value = code +		fieldCode.isAddrForMarshaler = true +		fieldCode.isNilCheck = false +	default: +		code, err := c.typeToCodeWithPtr(fieldType, isPtr) +		if err != nil { +			return nil, err +		} +		switch code.Kind() { +		case CodeKindPtr, CodeKindInterface: +			fieldCode.isNextOpPtrType = true +		} +		fieldCode.value = code +	} +	return fieldCode, nil +} + +func (c *Compiler) isAssignableIndirect(fieldCode *StructFieldCode, isPtr bool) bool { +	if isPtr { +		return false +	} +	codeType := fieldCode.value.Kind() +	if codeType == CodeKindMarshalJSON { +		return false +	} +	if codeType == CodeKindMarshalText { +		return false +	} +	return true +} + +func (c *Compiler) getFieldMap(fields []*StructFieldCode) map[string][]*StructFieldCode { +	fieldMap := map[string][]*StructFieldCode{} +	for _, field := range fields { +		if field.isAnonymous { +			for k, v := range c.getAnonymousFieldMap(field) { +				fieldMap[k] = append(fieldMap[k], v...) +			} +			continue +		} +		fieldMap[field.key] = append(fieldMap[field.key], field) +	} +	return fieldMap +} + +func (c *Compiler) getAnonymousFieldMap(field *StructFieldCode) map[string][]*StructFieldCode { +	fieldMap := map[string][]*StructFieldCode{} +	structCode := field.getAnonymousStruct() +	if structCode == nil || structCode.isRecursive { +		fieldMap[field.key] = append(fieldMap[field.key], field) +		return fieldMap +	} +	for k, v := range c.getFieldMapFromAnonymousParent(structCode.fields) { +		fieldMap[k] = append(fieldMap[k], v...) +	} +	return fieldMap +} + +func (c *Compiler) getFieldMapFromAnonymousParent(fields []*StructFieldCode) map[string][]*StructFieldCode { +	fieldMap := map[string][]*StructFieldCode{} +	for _, field := range fields { +		if field.isAnonymous { +			for k, v := range c.getAnonymousFieldMap(field) { +				// Do not handle tagged key when embedding more than once +				for _, vv := range v { +					vv.isTaggedKey = false +				} +				fieldMap[k] = append(fieldMap[k], v...) +			} +			continue +		} +		fieldMap[field.key] = append(fieldMap[field.key], field) +	} +	return fieldMap +} + +func (c *Compiler) getDuplicatedFieldMap(fieldMap map[string][]*StructFieldCode) map[*StructFieldCode]struct{} { +	duplicatedFieldMap := map[*StructFieldCode]struct{}{} +	for _, fields := range fieldMap { +		if len(fields) == 1 { +			continue +		} +		if c.isTaggedKeyOnly(fields) { +			for _, field := range fields { +				if field.isTaggedKey { +					continue +				} +				duplicatedFieldMap[field] = struct{}{} +			} +		} else { +			for _, field := range fields { +				duplicatedFieldMap[field] = struct{}{} +			} +		} +	} +	return duplicatedFieldMap +} + +func (c *Compiler) filteredDuplicatedFields(fields []*StructFieldCode, duplicatedFieldMap map[*StructFieldCode]struct{}) []*StructFieldCode { +	filteredFields := make([]*StructFieldCode, 0, len(fields)) +	for _, field := range fields { +		if field.isAnonymous { +			structCode := field.getAnonymousStruct() +			if structCode != nil && !structCode.isRecursive { +				structCode.fields = c.filteredDuplicatedFields(structCode.fields, duplicatedFieldMap) +				if len(structCode.fields) > 0 { +					filteredFields = append(filteredFields, field) +				} +				continue +			} +		} +		if _, exists := duplicatedFieldMap[field]; exists { +			continue +		} +		filteredFields = append(filteredFields, field) +	} +	return filteredFields +} + +func (c *Compiler) isTaggedKeyOnly(fields []*StructFieldCode) bool { +	var taggedKeyFieldCount int +	for _, field := range fields { +		if field.isTaggedKey { +			taggedKeyFieldCount++ +		} +	} +	return taggedKeyFieldCount == 1 +} + +func (c *Compiler) typeToStructTags(typ *runtime.Type) runtime.StructTags { +	tags := runtime.StructTags{} +	fieldNum := typ.NumField() +	for i := 0; i < fieldNum; i++ { +		field := typ.Field(i) +		if runtime.IsIgnoredStructField(field) { +			continue +		} +		tags = append(tags, runtime.StructTagFromField(field)) +	} +	return tags +} + +// *struct{ field T } => struct { field *T } +// func (*T) MarshalJSON() ([]byte, error) +func (c *Compiler) isMovePointerPositionFromHeadToFirstMarshalJSONFieldCase(typ *runtime.Type, isIndirectSpecialCase bool) bool { +	return isIndirectSpecialCase && !c.isNilableType(typ) && c.isPtrMarshalJSONType(typ) +} + +// *struct{ field T } => struct { field *T } +// func (*T) MarshalText() ([]byte, error) +func (c *Compiler) isMovePointerPositionFromHeadToFirstMarshalTextFieldCase(typ *runtime.Type, isIndirectSpecialCase bool) bool { +	return isIndirectSpecialCase && !c.isNilableType(typ) && c.isPtrMarshalTextType(typ) +} + +func (c *Compiler) implementsMarshalJSON(typ *runtime.Type) bool { +	if !c.implementsMarshalJSONType(typ) { +		return false +	} +	if typ.Kind() != reflect.Ptr { +		return true +	} +	// type kind is reflect.Ptr +	if !c.implementsMarshalJSONType(typ.Elem()) { +		return true +	} +	// needs to dereference +	return false +} + +func (c *Compiler) implementsMarshalText(typ *runtime.Type) bool { +	if !typ.Implements(marshalTextType) { +		return false +	} +	if typ.Kind() != reflect.Ptr { +		return true +	} +	// type kind is reflect.Ptr +	if !typ.Elem().Implements(marshalTextType) { +		return true +	} +	// needs to dereference +	return false +} + +func (c *Compiler) isNilableType(typ *runtime.Type) bool { +	if !runtime.IfaceIndir(typ) { +		return true +	} +	switch typ.Kind() { +	case reflect.Ptr: +		return true +	case reflect.Map: +		return true +	case reflect.Func: +		return true +	default: +		return false +	} +} + +func (c *Compiler) implementsMarshalJSONType(typ *runtime.Type) bool { +	return typ.Implements(marshalJSONType) || typ.Implements(marshalJSONContextType) +} + +func (c *Compiler) isPtrMarshalJSONType(typ *runtime.Type) bool { +	return !c.implementsMarshalJSONType(typ) && c.implementsMarshalJSONType(runtime.PtrTo(typ)) +} + +func (c *Compiler) isPtrMarshalTextType(typ *runtime.Type) bool { +	return !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType) +} + +func (c *Compiler) codeToOpcode(ctx *compileContext, typ *runtime.Type, code Code) *Opcode { +	codes := code.ToOpcode(ctx) +	codes.Last().Next = newEndOp(ctx, typ) +	c.linkRecursiveCode(ctx) +	return codes.First() +} + +func (c *Compiler) linkRecursiveCode(ctx *compileContext) { +	recursiveCodes := map[uintptr]*CompiledCode{} +	for _, recursive := range *ctx.recursiveCodes { +		typeptr := uintptr(unsafe.Pointer(recursive.Type)) +		codes := ctx.structTypeToCodes[typeptr] +		if recursiveCode, ok := recursiveCodes[typeptr]; ok { +			*recursive.Jmp = *recursiveCode +			continue +		} + +		code := copyOpcode(codes.First()) +		code.Op = code.Op.PtrHeadToHead() +		lastCode := newEndOp(&compileContext{}, recursive.Type) +		lastCode.Op = OpRecursiveEnd + +		// OpRecursiveEnd must set before call TotalLength +		code.End.Next = lastCode + +		totalLength := code.TotalLength() + +		// Idx, ElemIdx, Length must set after call TotalLength +		lastCode.Idx = uint32((totalLength + 1) * uintptrSize) +		lastCode.ElemIdx = lastCode.Idx + uintptrSize +		lastCode.Length = lastCode.Idx + 2*uintptrSize + +		// extend length to alloc slot for elemIdx + length +		curTotalLength := uintptr(recursive.TotalLength()) + 3 +		nextTotalLength := uintptr(totalLength) + 3 + +		compiled := recursive.Jmp +		compiled.Code = code +		compiled.CurLen = curTotalLength +		compiled.NextLen = nextTotalLength +		compiled.Linked = true + +		recursiveCodes[typeptr] = compiled +	} +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go b/vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go new file mode 100644 index 000000000..20c93cbf7 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go @@ -0,0 +1,32 @@ +//go:build !race +// +build !race + +package encoder + +func CompileToGetCodeSet(ctx *RuntimeContext, typeptr uintptr) (*OpcodeSet, error) { +	if typeptr > typeAddr.MaxTypeAddr || typeptr < typeAddr.BaseTypeAddr { +		codeSet, err := compileToGetCodeSetSlowPath(typeptr) +		if err != nil { +			return nil, err +		} +		return getFilteredCodeSetIfNeeded(ctx, codeSet) +	} +	index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift +	if codeSet := cachedOpcodeSets[index]; codeSet != nil { +		filtered, err := getFilteredCodeSetIfNeeded(ctx, codeSet) +		if err != nil { +			return nil, err +		} +		return filtered, nil +	} +	codeSet, err := newCompiler().compile(typeptr) +	if err != nil { +		return nil, err +	} +	filtered, err := getFilteredCodeSetIfNeeded(ctx, codeSet) +	if err != nil { +		return nil, err +	} +	cachedOpcodeSets[index] = codeSet +	return filtered, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go b/vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go new file mode 100644 index 000000000..13ba23fdf --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go @@ -0,0 +1,45 @@ +//go:build race +// +build race + +package encoder + +import ( +	"sync" +) + +var setsMu sync.RWMutex + +func CompileToGetCodeSet(ctx *RuntimeContext, typeptr uintptr) (*OpcodeSet, error) { +	if typeptr > typeAddr.MaxTypeAddr || typeptr < typeAddr.BaseTypeAddr { +		codeSet, err := compileToGetCodeSetSlowPath(typeptr) +		if err != nil { +			return nil, err +		} +		return getFilteredCodeSetIfNeeded(ctx, codeSet) +	} +	index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift +	setsMu.RLock() +	if codeSet := cachedOpcodeSets[index]; codeSet != nil { +		filtered, err := getFilteredCodeSetIfNeeded(ctx, codeSet) +		if err != nil { +			setsMu.RUnlock() +			return nil, err +		} +		setsMu.RUnlock() +		return filtered, nil +	} +	setsMu.RUnlock() + +	codeSet, err := newCompiler().compile(typeptr) +	if err != nil { +		return nil, err +	} +	filtered, err := getFilteredCodeSetIfNeeded(ctx, codeSet) +	if err != nil { +		return nil, err +	} +	setsMu.Lock() +	cachedOpcodeSets[index] = codeSet +	setsMu.Unlock() +	return filtered, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/context.go b/vendor/github.com/goccy/go-json/internal/encoder/context.go new file mode 100644 index 000000000..3833d0c86 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/context.go @@ -0,0 +1,105 @@ +package encoder + +import ( +	"context" +	"sync" +	"unsafe" + +	"github.com/goccy/go-json/internal/runtime" +) + +type compileContext struct { +	opcodeIndex       uint32 +	ptrIndex          int +	indent            uint32 +	escapeKey         bool +	structTypeToCodes map[uintptr]Opcodes +	recursiveCodes    *Opcodes +} + +func (c *compileContext) incIndent() { +	c.indent++ +} + +func (c *compileContext) decIndent() { +	c.indent-- +} + +func (c *compileContext) incIndex() { +	c.incOpcodeIndex() +	c.incPtrIndex() +} + +func (c *compileContext) decIndex() { +	c.decOpcodeIndex() +	c.decPtrIndex() +} + +func (c *compileContext) incOpcodeIndex() { +	c.opcodeIndex++ +} + +func (c *compileContext) decOpcodeIndex() { +	c.opcodeIndex-- +} + +func (c *compileContext) incPtrIndex() { +	c.ptrIndex++ +} + +func (c *compileContext) decPtrIndex() { +	c.ptrIndex-- +} + +const ( +	bufSize = 1024 +) + +var ( +	runtimeContextPool = sync.Pool{ +		New: func() interface{} { +			return &RuntimeContext{ +				Buf:      make([]byte, 0, bufSize), +				Ptrs:     make([]uintptr, 128), +				KeepRefs: make([]unsafe.Pointer, 0, 8), +				Option:   &Option{}, +			} +		}, +	} +) + +type RuntimeContext struct { +	Context    context.Context +	Buf        []byte +	MarshalBuf []byte +	Ptrs       []uintptr +	KeepRefs   []unsafe.Pointer +	SeenPtr    []uintptr +	BaseIndent uint32 +	Prefix     []byte +	IndentStr  []byte +	Option     *Option +} + +func (c *RuntimeContext) Init(p uintptr, codelen int) { +	if len(c.Ptrs) < codelen { +		c.Ptrs = make([]uintptr, codelen) +	} +	c.Ptrs[0] = p +	c.KeepRefs = c.KeepRefs[:0] +	c.SeenPtr = c.SeenPtr[:0] +	c.BaseIndent = 0 +} + +func (c *RuntimeContext) Ptr() uintptr { +	header := (*runtime.SliceHeader)(unsafe.Pointer(&c.Ptrs)) +	return uintptr(header.Data) +} + +func TakeRuntimeContext() *RuntimeContext { +	return runtimeContextPool.Get().(*RuntimeContext) +} + +func ReleaseRuntimeContext(ctx *RuntimeContext) { +	runtimeContextPool.Put(ctx) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/decode_rune.go b/vendor/github.com/goccy/go-json/internal/encoder/decode_rune.go new file mode 100644 index 000000000..35c959d48 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/decode_rune.go @@ -0,0 +1,126 @@ +package encoder + +import "unicode/utf8" + +const ( +	// The default lowest and highest continuation byte. +	locb = 128 //0b10000000 +	hicb = 191 //0b10111111 + +	// These names of these constants are chosen to give nice alignment in the +	// table below. The first nibble is an index into acceptRanges or F for +	// special one-byte cases. The second nibble is the Rune length or the +	// Status for the special one-byte case. +	xx = 0xF1 // invalid: size 1 +	as = 0xF0 // ASCII: size 1 +	s1 = 0x02 // accept 0, size 2 +	s2 = 0x13 // accept 1, size 3 +	s3 = 0x03 // accept 0, size 3 +	s4 = 0x23 // accept 2, size 3 +	s5 = 0x34 // accept 3, size 4 +	s6 = 0x04 // accept 0, size 4 +	s7 = 0x44 // accept 4, size 4 +) + +// first is information about the first byte in a UTF-8 sequence. +var first = [256]uint8{ +	//   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F +	as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x00-0x0F +	as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x10-0x1F +	as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x20-0x2F +	as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x30-0x3F +	as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x40-0x4F +	as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x50-0x5F +	as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x60-0x6F +	as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x70-0x7F +	//   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F +	xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x80-0x8F +	xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x90-0x9F +	xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xA0-0xAF +	xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xB0-0xBF +	xx, xx, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xC0-0xCF +	s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xD0-0xDF +	s2, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s4, s3, s3, // 0xE0-0xEF +	s5, s6, s6, s6, s7, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xF0-0xFF +} + +const ( +	lineSep      = byte(168) //'\u2028' +	paragraphSep = byte(169) //'\u2029' +) + +type decodeRuneState int + +const ( +	validUTF8State decodeRuneState = iota +	runeErrorState +	lineSepState +	paragraphSepState +) + +func decodeRuneInString(s string) (decodeRuneState, int) { +	n := len(s) +	s0 := s[0] +	x := first[s0] +	if x >= as { +		// The following code simulates an additional check for x == xx and +		// handling the ASCII and invalid cases accordingly. This mask-and-or +		// approach prevents an additional branch. +		mask := rune(x) << 31 >> 31 // Create 0x0000 or 0xFFFF. +		if rune(s[0])&^mask|utf8.RuneError&mask == utf8.RuneError { +			return runeErrorState, 1 +		} +		return validUTF8State, 1 +	} +	sz := int(x & 7) +	if n < sz { +		return runeErrorState, 1 +	} +	s1 := s[1] +	switch x >> 4 { +	case 0: +		if s1 < locb || hicb < s1 { +			return runeErrorState, 1 +		} +	case 1: +		if s1 < 0xA0 || hicb < s1 { +			return runeErrorState, 1 +		} +	case 2: +		if s1 < locb || 0x9F < s1 { +			return runeErrorState, 1 +		} +	case 3: +		if s1 < 0x90 || hicb < s1 { +			return runeErrorState, 1 +		} +	case 4: +		if s1 < locb || 0x8F < s1 { +			return runeErrorState, 1 +		} +	} +	if sz <= 2 { +		return validUTF8State, 2 +	} +	s2 := s[2] +	if s2 < locb || hicb < s2 { +		return runeErrorState, 1 +	} +	if sz <= 3 { +		// separator character prefixes: [2]byte{226, 128} +		if s0 == 226 && s1 == 128 { +			switch s2 { +			case lineSep: +				return lineSepState, 3 +			case paragraphSep: +				return paragraphSepState, 3 +			} +		} +		return validUTF8State, 3 +	} +	s3 := s[3] +	if s3 < locb || hicb < s3 { +		return runeErrorState, 1 +	} +	return validUTF8State, 4 +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/encoder.go b/vendor/github.com/goccy/go-json/internal/encoder/encoder.go new file mode 100644 index 000000000..14eb6a0d6 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/encoder.go @@ -0,0 +1,596 @@ +package encoder + +import ( +	"bytes" +	"encoding" +	"encoding/base64" +	"encoding/json" +	"fmt" +	"math" +	"reflect" +	"strconv" +	"strings" +	"sync" +	"unsafe" + +	"github.com/goccy/go-json/internal/errors" +	"github.com/goccy/go-json/internal/runtime" +) + +func (t OpType) IsMultipleOpHead() bool { +	switch t { +	case OpStructHead: +		return true +	case OpStructHeadSlice: +		return true +	case OpStructHeadArray: +		return true +	case OpStructHeadMap: +		return true +	case OpStructHeadStruct: +		return true +	case OpStructHeadOmitEmpty: +		return true +	case OpStructHeadOmitEmptySlice: +		return true +	case OpStructHeadOmitEmptyArray: +		return true +	case OpStructHeadOmitEmptyMap: +		return true +	case OpStructHeadOmitEmptyStruct: +		return true +	case OpStructHeadSlicePtr: +		return true +	case OpStructHeadOmitEmptySlicePtr: +		return true +	case OpStructHeadArrayPtr: +		return true +	case OpStructHeadOmitEmptyArrayPtr: +		return true +	case OpStructHeadMapPtr: +		return true +	case OpStructHeadOmitEmptyMapPtr: +		return true +	} +	return false +} + +func (t OpType) IsMultipleOpField() bool { +	switch t { +	case OpStructField: +		return true +	case OpStructFieldSlice: +		return true +	case OpStructFieldArray: +		return true +	case OpStructFieldMap: +		return true +	case OpStructFieldStruct: +		return true +	case OpStructFieldOmitEmpty: +		return true +	case OpStructFieldOmitEmptySlice: +		return true +	case OpStructFieldOmitEmptyArray: +		return true +	case OpStructFieldOmitEmptyMap: +		return true +	case OpStructFieldOmitEmptyStruct: +		return true +	case OpStructFieldSlicePtr: +		return true +	case OpStructFieldOmitEmptySlicePtr: +		return true +	case OpStructFieldArrayPtr: +		return true +	case OpStructFieldOmitEmptyArrayPtr: +		return true +	case OpStructFieldMapPtr: +		return true +	case OpStructFieldOmitEmptyMapPtr: +		return true +	} +	return false +} + +type OpcodeSet struct { +	Type                     *runtime.Type +	NoescapeKeyCode          *Opcode +	EscapeKeyCode            *Opcode +	InterfaceNoescapeKeyCode *Opcode +	InterfaceEscapeKeyCode   *Opcode +	CodeLength               int +	EndCode                  *Opcode +	Code                     Code +	QueryCache               map[string]*OpcodeSet +	cacheMu                  sync.RWMutex +} + +func (s *OpcodeSet) getQueryCache(hash string) *OpcodeSet { +	s.cacheMu.RLock() +	codeSet := s.QueryCache[hash] +	s.cacheMu.RUnlock() +	return codeSet +} + +func (s *OpcodeSet) setQueryCache(hash string, codeSet *OpcodeSet) { +	s.cacheMu.Lock() +	s.QueryCache[hash] = codeSet +	s.cacheMu.Unlock() +} + +type CompiledCode struct { +	Code    *Opcode +	Linked  bool // whether recursive code already have linked +	CurLen  uintptr +	NextLen uintptr +} + +const StartDetectingCyclesAfter = 1000 + +func Load(base uintptr, idx uintptr) uintptr { +	addr := base + idx +	return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func Store(base uintptr, idx uintptr, p uintptr) { +	addr := base + idx +	**(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func LoadNPtr(base uintptr, idx uintptr, ptrNum int) uintptr { +	addr := base + idx +	p := **(**uintptr)(unsafe.Pointer(&addr)) +	if p == 0 { +		return 0 +	} +	return PtrToPtr(p) +	/* +		for i := 0; i < ptrNum; i++ { +			if p == 0 { +				return p +			} +			p = PtrToPtr(p) +		} +		return p +	*/ +} + +func PtrToUint64(p uintptr) uint64              { return **(**uint64)(unsafe.Pointer(&p)) } +func PtrToFloat32(p uintptr) float32            { return **(**float32)(unsafe.Pointer(&p)) } +func PtrToFloat64(p uintptr) float64            { return **(**float64)(unsafe.Pointer(&p)) } +func PtrToBool(p uintptr) bool                  { return **(**bool)(unsafe.Pointer(&p)) } +func PtrToBytes(p uintptr) []byte               { return **(**[]byte)(unsafe.Pointer(&p)) } +func PtrToNumber(p uintptr) json.Number         { return **(**json.Number)(unsafe.Pointer(&p)) } +func PtrToString(p uintptr) string              { return **(**string)(unsafe.Pointer(&p)) } +func PtrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func PtrToPtr(p uintptr) uintptr { +	return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func PtrToNPtr(p uintptr, ptrNum int) uintptr { +	for i := 0; i < ptrNum; i++ { +		if p == 0 { +			return 0 +		} +		p = PtrToPtr(p) +	} +	return p +} + +func PtrToUnsafePtr(p uintptr) unsafe.Pointer { +	return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func PtrToInterface(code *Opcode, p uintptr) interface{} { +	return *(*interface{})(unsafe.Pointer(&emptyInterface{ +		typ: code.Type, +		ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), +	})) +} + +func ErrUnsupportedValue(code *Opcode, ptr uintptr) *errors.UnsupportedValueError { +	v := *(*interface{})(unsafe.Pointer(&emptyInterface{ +		typ: code.Type, +		ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)), +	})) +	return &errors.UnsupportedValueError{ +		Value: reflect.ValueOf(v), +		Str:   fmt.Sprintf("encountered a cycle via %s", code.Type), +	} +} + +func ErrUnsupportedFloat(v float64) *errors.UnsupportedValueError { +	return &errors.UnsupportedValueError{ +		Value: reflect.ValueOf(v), +		Str:   strconv.FormatFloat(v, 'g', -1, 64), +	} +} + +func ErrMarshalerWithCode(code *Opcode, err error) *errors.MarshalerError { +	return &errors.MarshalerError{ +		Type: runtime.RType2Type(code.Type), +		Err:  err, +	} +} + +type emptyInterface struct { +	typ *runtime.Type +	ptr unsafe.Pointer +} + +type MapItem struct { +	Key   []byte +	Value []byte +} + +type Mapslice struct { +	Items []MapItem +} + +func (m *Mapslice) Len() int { +	return len(m.Items) +} + +func (m *Mapslice) Less(i, j int) bool { +	return bytes.Compare(m.Items[i].Key, m.Items[j].Key) < 0 +} + +func (m *Mapslice) Swap(i, j int) { +	m.Items[i], m.Items[j] = m.Items[j], m.Items[i] +} + +//nolint:structcheck,unused +type mapIter struct { +	key         unsafe.Pointer +	elem        unsafe.Pointer +	t           unsafe.Pointer +	h           unsafe.Pointer +	buckets     unsafe.Pointer +	bptr        unsafe.Pointer +	overflow    unsafe.Pointer +	oldoverflow unsafe.Pointer +	startBucket uintptr +	offset      uint8 +	wrapped     bool +	B           uint8 +	i           uint8 +	bucket      uintptr +	checkBucket uintptr +} + +type MapContext struct { +	Start int +	First int +	Idx   int +	Slice *Mapslice +	Buf   []byte +	Len   int +	Iter  mapIter +} + +var mapContextPool = sync.Pool{ +	New: func() interface{} { +		return &MapContext{ +			Slice: &Mapslice{}, +		} +	}, +} + +func NewMapContext(mapLen int, unorderedMap bool) *MapContext { +	ctx := mapContextPool.Get().(*MapContext) +	if !unorderedMap { +		if len(ctx.Slice.Items) < mapLen { +			ctx.Slice.Items = make([]MapItem, mapLen) +		} else { +			ctx.Slice.Items = ctx.Slice.Items[:mapLen] +		} +	} +	ctx.Buf = ctx.Buf[:0] +	ctx.Iter = mapIter{} +	ctx.Idx = 0 +	ctx.Len = mapLen +	return ctx +} + +func ReleaseMapContext(c *MapContext) { +	mapContextPool.Put(c) +} + +//go:linkname MapIterInit runtime.mapiterinit +//go:noescape +func MapIterInit(mapType *runtime.Type, m unsafe.Pointer, it *mapIter) + +//go:linkname MapIterKey reflect.mapiterkey +//go:noescape +func MapIterKey(it *mapIter) unsafe.Pointer + +//go:linkname MapIterNext reflect.mapiternext +//go:noescape +func MapIterNext(it *mapIter) + +//go:linkname MapLen reflect.maplen +//go:noescape +func MapLen(m unsafe.Pointer) int + +func AppendByteSlice(_ *RuntimeContext, b []byte, src []byte) []byte { +	if src == nil { +		return append(b, `null`...) +	} +	encodedLen := base64.StdEncoding.EncodedLen(len(src)) +	b = append(b, '"') +	pos := len(b) +	remainLen := cap(b[pos:]) +	var buf []byte +	if remainLen > encodedLen { +		buf = b[pos : pos+encodedLen] +	} else { +		buf = make([]byte, encodedLen) +	} +	base64.StdEncoding.Encode(buf, src) +	return append(append(b, buf...), '"') +} + +func AppendFloat32(_ *RuntimeContext, b []byte, v float32) []byte { +	f64 := float64(v) +	abs := math.Abs(f64) +	fmt := byte('f') +	// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. +	if abs != 0 { +		f32 := float32(abs) +		if f32 < 1e-6 || f32 >= 1e21 { +			fmt = 'e' +		} +	} +	return strconv.AppendFloat(b, f64, fmt, -1, 32) +} + +func AppendFloat64(_ *RuntimeContext, b []byte, v float64) []byte { +	abs := math.Abs(v) +	fmt := byte('f') +	// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. +	if abs != 0 { +		if abs < 1e-6 || abs >= 1e21 { +			fmt = 'e' +		} +	} +	return strconv.AppendFloat(b, v, fmt, -1, 64) +} + +func AppendBool(_ *RuntimeContext, b []byte, v bool) []byte { +	if v { +		return append(b, "true"...) +	} +	return append(b, "false"...) +} + +var ( +	floatTable = [256]bool{ +		'0': true, +		'1': true, +		'2': true, +		'3': true, +		'4': true, +		'5': true, +		'6': true, +		'7': true, +		'8': true, +		'9': true, +		'.': true, +		'e': true, +		'E': true, +		'+': true, +		'-': true, +	} +) + +func AppendNumber(_ *RuntimeContext, b []byte, n json.Number) ([]byte, error) { +	if len(n) == 0 { +		return append(b, '0'), nil +	} +	for i := 0; i < len(n); i++ { +		if !floatTable[n[i]] { +			return nil, fmt.Errorf("json: invalid number literal %q", n) +		} +	} +	b = append(b, n...) +	return b, nil +} + +func AppendMarshalJSON(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) { +	rv := reflect.ValueOf(v) // convert by dynamic interface type +	if (code.Flags & AddrForMarshalerFlags) != 0 { +		if rv.CanAddr() { +			rv = rv.Addr() +		} else { +			newV := reflect.New(rv.Type()) +			newV.Elem().Set(rv) +			rv = newV +		} +	} +	v = rv.Interface() +	var bb []byte +	if (code.Flags & MarshalerContextFlags) != 0 { +		marshaler, ok := v.(marshalerContext) +		if !ok { +			return AppendNull(ctx, b), nil +		} +		stdctx := ctx.Option.Context +		if ctx.Option.Flag&FieldQueryOption != 0 { +			stdctx = SetFieldQueryToContext(stdctx, code.FieldQuery) +		} +		b, err := marshaler.MarshalJSON(stdctx) +		if err != nil { +			return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} +		} +		bb = b +	} else { +		marshaler, ok := v.(json.Marshaler) +		if !ok { +			return AppendNull(ctx, b), nil +		} +		b, err := marshaler.MarshalJSON() +		if err != nil { +			return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} +		} +		bb = b +	} +	marshalBuf := ctx.MarshalBuf[:0] +	marshalBuf = append(append(marshalBuf, bb...), nul) +	compactedBuf, err := compact(b, marshalBuf, (ctx.Option.Flag&HTMLEscapeOption) != 0) +	if err != nil { +		return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} +	} +	ctx.MarshalBuf = marshalBuf +	return compactedBuf, nil +} + +func AppendMarshalJSONIndent(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) { +	rv := reflect.ValueOf(v) // convert by dynamic interface type +	if (code.Flags & AddrForMarshalerFlags) != 0 { +		if rv.CanAddr() { +			rv = rv.Addr() +		} else { +			newV := reflect.New(rv.Type()) +			newV.Elem().Set(rv) +			rv = newV +		} +	} +	v = rv.Interface() +	var bb []byte +	if (code.Flags & MarshalerContextFlags) != 0 { +		marshaler, ok := v.(marshalerContext) +		if !ok { +			return AppendNull(ctx, b), nil +		} +		b, err := marshaler.MarshalJSON(ctx.Option.Context) +		if err != nil { +			return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} +		} +		bb = b +	} else { +		marshaler, ok := v.(json.Marshaler) +		if !ok { +			return AppendNull(ctx, b), nil +		} +		b, err := marshaler.MarshalJSON() +		if err != nil { +			return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} +		} +		bb = b +	} +	marshalBuf := ctx.MarshalBuf[:0] +	marshalBuf = append(append(marshalBuf, bb...), nul) +	indentedBuf, err := doIndent( +		b, +		marshalBuf, +		string(ctx.Prefix)+strings.Repeat(string(ctx.IndentStr), int(ctx.BaseIndent+code.Indent)), +		string(ctx.IndentStr), +		(ctx.Option.Flag&HTMLEscapeOption) != 0, +	) +	if err != nil { +		return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} +	} +	ctx.MarshalBuf = marshalBuf +	return indentedBuf, nil +} + +func AppendMarshalText(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) { +	rv := reflect.ValueOf(v) // convert by dynamic interface type +	if (code.Flags & AddrForMarshalerFlags) != 0 { +		if rv.CanAddr() { +			rv = rv.Addr() +		} else { +			newV := reflect.New(rv.Type()) +			newV.Elem().Set(rv) +			rv = newV +		} +	} +	v = rv.Interface() +	marshaler, ok := v.(encoding.TextMarshaler) +	if !ok { +		return AppendNull(ctx, b), nil +	} +	bytes, err := marshaler.MarshalText() +	if err != nil { +		return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} +	} +	return AppendString(ctx, b, *(*string)(unsafe.Pointer(&bytes))), nil +} + +func AppendMarshalTextIndent(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) { +	rv := reflect.ValueOf(v) // convert by dynamic interface type +	if (code.Flags & AddrForMarshalerFlags) != 0 { +		if rv.CanAddr() { +			rv = rv.Addr() +		} else { +			newV := reflect.New(rv.Type()) +			newV.Elem().Set(rv) +			rv = newV +		} +	} +	v = rv.Interface() +	marshaler, ok := v.(encoding.TextMarshaler) +	if !ok { +		return AppendNull(ctx, b), nil +	} +	bytes, err := marshaler.MarshalText() +	if err != nil { +		return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} +	} +	return AppendString(ctx, b, *(*string)(unsafe.Pointer(&bytes))), nil +} + +func AppendNull(_ *RuntimeContext, b []byte) []byte { +	return append(b, "null"...) +} + +func AppendComma(_ *RuntimeContext, b []byte) []byte { +	return append(b, ',') +} + +func AppendCommaIndent(_ *RuntimeContext, b []byte) []byte { +	return append(b, ',', '\n') +} + +func AppendStructEnd(_ *RuntimeContext, b []byte) []byte { +	return append(b, '}', ',') +} + +func AppendStructEndIndent(ctx *RuntimeContext, code *Opcode, b []byte) []byte { +	b = append(b, '\n') +	b = append(b, ctx.Prefix...) +	indentNum := ctx.BaseIndent + code.Indent - 1 +	for i := uint32(0); i < indentNum; i++ { +		b = append(b, ctx.IndentStr...) +	} +	return append(b, '}', ',', '\n') +} + +func AppendIndent(ctx *RuntimeContext, b []byte, indent uint32) []byte { +	b = append(b, ctx.Prefix...) +	indentNum := ctx.BaseIndent + indent +	for i := uint32(0); i < indentNum; i++ { +		b = append(b, ctx.IndentStr...) +	} +	return b +} + +func IsNilForMarshaler(v interface{}) bool { +	rv := reflect.ValueOf(v) +	switch rv.Kind() { +	case reflect.Bool: +		return !rv.Bool() +	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: +		return rv.Int() == 0 +	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: +		return rv.Uint() == 0 +	case reflect.Float32, reflect.Float64: +		return math.Float64bits(rv.Float()) == 0 +	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Func: +		return rv.IsNil() +	case reflect.Slice: +		return rv.IsNil() || rv.Len() == 0 +	case reflect.String: +		return rv.Len() == 0 +	} +	return false +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/indent.go b/vendor/github.com/goccy/go-json/internal/encoder/indent.go new file mode 100644 index 000000000..dfe04b5e3 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/indent.go @@ -0,0 +1,211 @@ +package encoder + +import ( +	"bytes" +	"fmt" + +	"github.com/goccy/go-json/internal/errors" +) + +func takeIndentSrcRuntimeContext(src []byte) (*RuntimeContext, []byte) { +	ctx := TakeRuntimeContext() +	buf := ctx.Buf[:0] +	buf = append(append(buf, src...), nul) +	ctx.Buf = buf +	return ctx, buf +} + +func Indent(buf *bytes.Buffer, src []byte, prefix, indentStr string) error { +	if len(src) == 0 { +		return errors.ErrUnexpectedEndOfJSON("", 0) +	} + +	srcCtx, srcBuf := takeIndentSrcRuntimeContext(src) +	dstCtx := TakeRuntimeContext() +	dst := dstCtx.Buf[:0] + +	dst, err := indentAndWrite(buf, dst, srcBuf, prefix, indentStr) +	if err != nil { +		ReleaseRuntimeContext(srcCtx) +		ReleaseRuntimeContext(dstCtx) +		return err +	} +	dstCtx.Buf = dst +	ReleaseRuntimeContext(srcCtx) +	ReleaseRuntimeContext(dstCtx) +	return nil +} + +func indentAndWrite(buf *bytes.Buffer, dst []byte, src []byte, prefix, indentStr string) ([]byte, error) { +	dst, err := doIndent(dst, src, prefix, indentStr, false) +	if err != nil { +		return nil, err +	} +	if _, err := buf.Write(dst); err != nil { +		return nil, err +	} +	return dst, nil +} + +func doIndent(dst, src []byte, prefix, indentStr string, escape bool) ([]byte, error) { +	buf, cursor, err := indentValue(dst, src, 0, 0, []byte(prefix), []byte(indentStr), escape) +	if err != nil { +		return nil, err +	} +	if err := validateEndBuf(src, cursor); err != nil { +		return nil, err +	} +	return buf, nil +} + +func indentValue( +	dst []byte, +	src []byte, +	indentNum int, +	cursor int64, +	prefix []byte, +	indentBytes []byte, +	escape bool) ([]byte, int64, error) { +	for { +		switch src[cursor] { +		case ' ', '\t', '\n', '\r': +			cursor++ +			continue +		case '{': +			return indentObject(dst, src, indentNum, cursor, prefix, indentBytes, escape) +		case '}': +			return nil, 0, errors.ErrSyntax("unexpected character '}'", cursor) +		case '[': +			return indentArray(dst, src, indentNum, cursor, prefix, indentBytes, escape) +		case ']': +			return nil, 0, errors.ErrSyntax("unexpected character ']'", cursor) +		case '"': +			return compactString(dst, src, cursor, escape) +		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': +			return compactNumber(dst, src, cursor) +		case 't': +			return compactTrue(dst, src, cursor) +		case 'f': +			return compactFalse(dst, src, cursor) +		case 'n': +			return compactNull(dst, src, cursor) +		default: +			return nil, 0, errors.ErrSyntax(fmt.Sprintf("unexpected character '%c'", src[cursor]), cursor) +		} +	} +} + +func indentObject( +	dst []byte, +	src []byte, +	indentNum int, +	cursor int64, +	prefix []byte, +	indentBytes []byte, +	escape bool) ([]byte, int64, error) { +	if src[cursor] == '{' { +		dst = append(dst, '{') +	} else { +		return nil, 0, errors.ErrExpected("expected { character for object value", cursor) +	} +	cursor = skipWhiteSpace(src, cursor+1) +	if src[cursor] == '}' { +		dst = append(dst, '}') +		return dst, cursor + 1, nil +	} +	indentNum++ +	var err error +	for { +		dst = append(append(dst, '\n'), prefix...) +		for i := 0; i < indentNum; i++ { +			dst = append(dst, indentBytes...) +		} +		cursor = skipWhiteSpace(src, cursor) +		dst, cursor, err = compactString(dst, src, cursor, escape) +		if err != nil { +			return nil, 0, err +		} +		cursor = skipWhiteSpace(src, cursor) +		if src[cursor] != ':' { +			return nil, 0, errors.ErrSyntax( +				fmt.Sprintf("invalid character '%c' after object key", src[cursor]), +				cursor+1, +			) +		} +		dst = append(dst, ':', ' ') +		dst, cursor, err = indentValue(dst, src, indentNum, cursor+1, prefix, indentBytes, escape) +		if err != nil { +			return nil, 0, err +		} +		cursor = skipWhiteSpace(src, cursor) +		switch src[cursor] { +		case '}': +			dst = append(append(dst, '\n'), prefix...) +			for i := 0; i < indentNum-1; i++ { +				dst = append(dst, indentBytes...) +			} +			dst = append(dst, '}') +			cursor++ +			return dst, cursor, nil +		case ',': +			dst = append(dst, ',') +		default: +			return nil, 0, errors.ErrSyntax( +				fmt.Sprintf("invalid character '%c' after object key:value pair", src[cursor]), +				cursor+1, +			) +		} +		cursor++ +	} +} + +func indentArray( +	dst []byte, +	src []byte, +	indentNum int, +	cursor int64, +	prefix []byte, +	indentBytes []byte, +	escape bool) ([]byte, int64, error) { +	if src[cursor] == '[' { +		dst = append(dst, '[') +	} else { +		return nil, 0, errors.ErrExpected("expected [ character for array value", cursor) +	} +	cursor = skipWhiteSpace(src, cursor+1) +	if src[cursor] == ']' { +		dst = append(dst, ']') +		return dst, cursor + 1, nil +	} +	indentNum++ +	var err error +	for { +		dst = append(append(dst, '\n'), prefix...) +		for i := 0; i < indentNum; i++ { +			dst = append(dst, indentBytes...) +		} +		dst, cursor, err = indentValue(dst, src, indentNum, cursor, prefix, indentBytes, escape) +		if err != nil { +			return nil, 0, err +		} +		cursor = skipWhiteSpace(src, cursor) +		switch src[cursor] { +		case ']': +			dst = append(append(dst, '\n'), prefix...) +			for i := 0; i < indentNum-1; i++ { +				dst = append(dst, indentBytes...) +			} +			dst = append(dst, ']') +			cursor++ +			return dst, cursor, nil +		case ',': +			dst = append(dst, ',') +		default: +			return nil, 0, errors.ErrSyntax( +				fmt.Sprintf("invalid character '%c' after array value", src[cursor]), +				cursor+1, +			) +		} +		cursor++ +	} +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/int.go b/vendor/github.com/goccy/go-json/internal/encoder/int.go new file mode 100644 index 000000000..85f079609 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/int.go @@ -0,0 +1,152 @@ +package encoder + +import ( +	"unsafe" +) + +var endianness int + +func init() { +	var b [2]byte +	*(*uint16)(unsafe.Pointer(&b)) = uint16(0xABCD) + +	switch b[0] { +	case 0xCD: +		endianness = 0 // LE +	case 0xAB: +		endianness = 1 // BE +	default: +		panic("could not determine endianness") +	} +} + +// "00010203...96979899" cast to []uint16 +var intLELookup = [100]uint16{ +	0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730, 0x3830, 0x3930, +	0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731, 0x3831, 0x3931, +	0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732, 0x3832, 0x3932, +	0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733, 0x3833, 0x3933, +	0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734, 0x3834, 0x3934, +	0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735, 0x3835, 0x3935, +	0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736, 0x3836, 0x3936, +	0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737, 0x3837, 0x3937, +	0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738, 0x3838, 0x3938, +	0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739, 0x3839, 0x3939, +} + +var intBELookup = [100]uint16{ +	0x3030, 0x3031, 0x3032, 0x3033, 0x3034, 0x3035, 0x3036, 0x3037, 0x3038, 0x3039, +	0x3130, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138, 0x3139, +	0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, 0x3236, 0x3237, 0x3238, 0x3239, +	0x3330, 0x3331, 0x3332, 0x3333, 0x3334, 0x3335, 0x3336, 0x3337, 0x3338, 0x3339, +	0x3430, 0x3431, 0x3432, 0x3433, 0x3434, 0x3435, 0x3436, 0x3437, 0x3438, 0x3439, +	0x3530, 0x3531, 0x3532, 0x3533, 0x3534, 0x3535, 0x3536, 0x3537, 0x3538, 0x3539, +	0x3630, 0x3631, 0x3632, 0x3633, 0x3634, 0x3635, 0x3636, 0x3637, 0x3638, 0x3639, +	0x3730, 0x3731, 0x3732, 0x3733, 0x3734, 0x3735, 0x3736, 0x3737, 0x3738, 0x3739, +	0x3830, 0x3831, 0x3832, 0x3833, 0x3834, 0x3835, 0x3836, 0x3837, 0x3838, 0x3839, +	0x3930, 0x3931, 0x3932, 0x3933, 0x3934, 0x3935, 0x3936, 0x3937, 0x3938, 0x3939, +} + +var intLookup = [2]*[100]uint16{&intLELookup, &intBELookup} + +func numMask(numBitSize uint8) uint64 { +	return 1<<numBitSize - 1 +} + +func AppendInt(_ *RuntimeContext, out []byte, p uintptr, code *Opcode) []byte { +	var u64 uint64 +	switch code.NumBitSize { +	case 8: +		u64 = (uint64)(**(**uint8)(unsafe.Pointer(&p))) +	case 16: +		u64 = (uint64)(**(**uint16)(unsafe.Pointer(&p))) +	case 32: +		u64 = (uint64)(**(**uint32)(unsafe.Pointer(&p))) +	case 64: +		u64 = **(**uint64)(unsafe.Pointer(&p)) +	} +	mask := numMask(code.NumBitSize) +	n := u64 & mask +	negative := (u64>>(code.NumBitSize-1))&1 == 1 +	if !negative { +		if n < 10 { +			return append(out, byte(n+'0')) +		} else if n < 100 { +			u := intLELookup[n] +			return append(out, byte(u), byte(u>>8)) +		} +	} else { +		n = -n & mask +	} + +	lookup := intLookup[endianness] + +	var b [22]byte +	u := (*[11]uint16)(unsafe.Pointer(&b)) +	i := 11 + +	for n >= 100 { +		j := n % 100 +		n /= 100 +		i-- +		u[i] = lookup[j] +	} + +	i-- +	u[i] = lookup[n] + +	i *= 2 // convert to byte index +	if n < 10 { +		i++ // remove leading zero +	} +	if negative { +		i-- +		b[i] = '-' +	} + +	return append(out, b[i:]...) +} + +func AppendUint(_ *RuntimeContext, out []byte, p uintptr, code *Opcode) []byte { +	var u64 uint64 +	switch code.NumBitSize { +	case 8: +		u64 = (uint64)(**(**uint8)(unsafe.Pointer(&p))) +	case 16: +		u64 = (uint64)(**(**uint16)(unsafe.Pointer(&p))) +	case 32: +		u64 = (uint64)(**(**uint32)(unsafe.Pointer(&p))) +	case 64: +		u64 = **(**uint64)(unsafe.Pointer(&p)) +	} +	mask := numMask(code.NumBitSize) +	n := u64 & mask +	if n < 10 { +		return append(out, byte(n+'0')) +	} else if n < 100 { +		u := intLELookup[n] +		return append(out, byte(u), byte(u>>8)) +	} + +	lookup := intLookup[endianness] + +	var b [22]byte +	u := (*[11]uint16)(unsafe.Pointer(&b)) +	i := 11 + +	for n >= 100 { +		j := n % 100 +		n /= 100 +		i-- +		u[i] = lookup[j] +	} + +	i-- +	u[i] = lookup[n] + +	i *= 2 // convert to byte index +	if n < 10 { +		i++ // remove leading zero +	} +	return append(out, b[i:]...) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/map112.go b/vendor/github.com/goccy/go-json/internal/encoder/map112.go new file mode 100644 index 000000000..e96ffadf7 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/map112.go @@ -0,0 +1,9 @@ +//go:build !go1.13 +// +build !go1.13 + +package encoder + +import "unsafe" + +//go:linkname MapIterValue reflect.mapitervalue +func MapIterValue(it *mapIter) unsafe.Pointer diff --git a/vendor/github.com/goccy/go-json/internal/encoder/map113.go b/vendor/github.com/goccy/go-json/internal/encoder/map113.go new file mode 100644 index 000000000..9b69dcc36 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/map113.go @@ -0,0 +1,9 @@ +//go:build go1.13 +// +build go1.13 + +package encoder + +import "unsafe" + +//go:linkname MapIterValue reflect.mapiterelem +func MapIterValue(it *mapIter) unsafe.Pointer diff --git a/vendor/github.com/goccy/go-json/internal/encoder/opcode.go b/vendor/github.com/goccy/go-json/internal/encoder/opcode.go new file mode 100644 index 000000000..05fc3ce04 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/opcode.go @@ -0,0 +1,669 @@ +package encoder + +import ( +	"fmt" +	"strings" +	"unsafe" + +	"github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +type OpFlags uint16 + +const ( +	AnonymousHeadFlags     OpFlags = 1 << 0 +	AnonymousKeyFlags      OpFlags = 1 << 1 +	IndirectFlags          OpFlags = 1 << 2 +	IsTaggedKeyFlags       OpFlags = 1 << 3 +	NilCheckFlags          OpFlags = 1 << 4 +	AddrForMarshalerFlags  OpFlags = 1 << 5 +	IsNextOpPtrTypeFlags   OpFlags = 1 << 6 +	IsNilableTypeFlags     OpFlags = 1 << 7 +	MarshalerContextFlags  OpFlags = 1 << 8 +	NonEmptyInterfaceFlags OpFlags = 1 << 9 +) + +type Opcode struct { +	Op         OpType  // operation type +	Idx        uint32  // offset to access ptr +	Next       *Opcode // next opcode +	End        *Opcode // array/slice/struct/map end +	NextField  *Opcode // next struct field +	Key        string  // struct field key +	Offset     uint32  // offset size from struct header +	PtrNum     uint8   // pointer number: e.g. double pointer is 2. +	NumBitSize uint8 +	Flags      OpFlags + +	Type       *runtime.Type // go type +	Jmp        *CompiledCode // for recursive call +	FieldQuery *FieldQuery   // field query for Interface / MarshalJSON / MarshalText +	ElemIdx    uint32        // offset to access array/slice elem +	Length     uint32        // offset to access slice length or array length +	Indent     uint32        // indent number +	Size       uint32        // array/slice elem size +	DisplayIdx uint32        // opcode index +	DisplayKey string        // key text to display +} + +func (c *Opcode) Validate() error { +	var prevIdx uint32 +	for code := c; !code.IsEnd(); { +		if prevIdx != 0 { +			if code.DisplayIdx != prevIdx+1 { +				return fmt.Errorf( +					"invalid index. previous display index is %d but next is %d. dump = %s", +					prevIdx, code.DisplayIdx, c.Dump(), +				) +			} +		} +		prevIdx = code.DisplayIdx +		code = code.IterNext() +	} +	return nil +} + +func (c *Opcode) IterNext() *Opcode { +	if c == nil { +		return nil +	} +	switch c.Op.CodeType() { +	case CodeArrayElem, CodeSliceElem, CodeMapKey: +		return c.End +	default: +		return c.Next +	} +} + +func (c *Opcode) IsEnd() bool { +	if c == nil { +		return true +	} +	return c.Op == OpEnd || c.Op == OpInterfaceEnd || c.Op == OpRecursiveEnd +} + +func (c *Opcode) MaxIdx() uint32 { +	max := uint32(0) +	for _, value := range []uint32{ +		c.Idx, +		c.ElemIdx, +		c.Length, +		c.Size, +	} { +		if max < value { +			max = value +		} +	} +	return max +} + +func (c *Opcode) ToHeaderType(isString bool) OpType { +	switch c.Op { +	case OpInt: +		if isString { +			return OpStructHeadIntString +		} +		return OpStructHeadInt +	case OpIntPtr: +		if isString { +			return OpStructHeadIntPtrString +		} +		return OpStructHeadIntPtr +	case OpUint: +		if isString { +			return OpStructHeadUintString +		} +		return OpStructHeadUint +	case OpUintPtr: +		if isString { +			return OpStructHeadUintPtrString +		} +		return OpStructHeadUintPtr +	case OpFloat32: +		if isString { +			return OpStructHeadFloat32String +		} +		return OpStructHeadFloat32 +	case OpFloat32Ptr: +		if isString { +			return OpStructHeadFloat32PtrString +		} +		return OpStructHeadFloat32Ptr +	case OpFloat64: +		if isString { +			return OpStructHeadFloat64String +		} +		return OpStructHeadFloat64 +	case OpFloat64Ptr: +		if isString { +			return OpStructHeadFloat64PtrString +		} +		return OpStructHeadFloat64Ptr +	case OpString: +		if isString { +			return OpStructHeadStringString +		} +		return OpStructHeadString +	case OpStringPtr: +		if isString { +			return OpStructHeadStringPtrString +		} +		return OpStructHeadStringPtr +	case OpNumber: +		if isString { +			return OpStructHeadNumberString +		} +		return OpStructHeadNumber +	case OpNumberPtr: +		if isString { +			return OpStructHeadNumberPtrString +		} +		return OpStructHeadNumberPtr +	case OpBool: +		if isString { +			return OpStructHeadBoolString +		} +		return OpStructHeadBool +	case OpBoolPtr: +		if isString { +			return OpStructHeadBoolPtrString +		} +		return OpStructHeadBoolPtr +	case OpBytes: +		return OpStructHeadBytes +	case OpBytesPtr: +		return OpStructHeadBytesPtr +	case OpMap: +		return OpStructHeadMap +	case OpMapPtr: +		c.Op = OpMap +		return OpStructHeadMapPtr +	case OpArray: +		return OpStructHeadArray +	case OpArrayPtr: +		c.Op = OpArray +		return OpStructHeadArrayPtr +	case OpSlice: +		return OpStructHeadSlice +	case OpSlicePtr: +		c.Op = OpSlice +		return OpStructHeadSlicePtr +	case OpMarshalJSON: +		return OpStructHeadMarshalJSON +	case OpMarshalJSONPtr: +		return OpStructHeadMarshalJSONPtr +	case OpMarshalText: +		return OpStructHeadMarshalText +	case OpMarshalTextPtr: +		return OpStructHeadMarshalTextPtr +	} +	return OpStructHead +} + +func (c *Opcode) ToFieldType(isString bool) OpType { +	switch c.Op { +	case OpInt: +		if isString { +			return OpStructFieldIntString +		} +		return OpStructFieldInt +	case OpIntPtr: +		if isString { +			return OpStructFieldIntPtrString +		} +		return OpStructFieldIntPtr +	case OpUint: +		if isString { +			return OpStructFieldUintString +		} +		return OpStructFieldUint +	case OpUintPtr: +		if isString { +			return OpStructFieldUintPtrString +		} +		return OpStructFieldUintPtr +	case OpFloat32: +		if isString { +			return OpStructFieldFloat32String +		} +		return OpStructFieldFloat32 +	case OpFloat32Ptr: +		if isString { +			return OpStructFieldFloat32PtrString +		} +		return OpStructFieldFloat32Ptr +	case OpFloat64: +		if isString { +			return OpStructFieldFloat64String +		} +		return OpStructFieldFloat64 +	case OpFloat64Ptr: +		if isString { +			return OpStructFieldFloat64PtrString +		} +		return OpStructFieldFloat64Ptr +	case OpString: +		if isString { +			return OpStructFieldStringString +		} +		return OpStructFieldString +	case OpStringPtr: +		if isString { +			return OpStructFieldStringPtrString +		} +		return OpStructFieldStringPtr +	case OpNumber: +		if isString { +			return OpStructFieldNumberString +		} +		return OpStructFieldNumber +	case OpNumberPtr: +		if isString { +			return OpStructFieldNumberPtrString +		} +		return OpStructFieldNumberPtr +	case OpBool: +		if isString { +			return OpStructFieldBoolString +		} +		return OpStructFieldBool +	case OpBoolPtr: +		if isString { +			return OpStructFieldBoolPtrString +		} +		return OpStructFieldBoolPtr +	case OpBytes: +		return OpStructFieldBytes +	case OpBytesPtr: +		return OpStructFieldBytesPtr +	case OpMap: +		return OpStructFieldMap +	case OpMapPtr: +		c.Op = OpMap +		return OpStructFieldMapPtr +	case OpArray: +		return OpStructFieldArray +	case OpArrayPtr: +		c.Op = OpArray +		return OpStructFieldArrayPtr +	case OpSlice: +		return OpStructFieldSlice +	case OpSlicePtr: +		c.Op = OpSlice +		return OpStructFieldSlicePtr +	case OpMarshalJSON: +		return OpStructFieldMarshalJSON +	case OpMarshalJSONPtr: +		return OpStructFieldMarshalJSONPtr +	case OpMarshalText: +		return OpStructFieldMarshalText +	case OpMarshalTextPtr: +		return OpStructFieldMarshalTextPtr +	} +	return OpStructField +} + +func newOpCode(ctx *compileContext, typ *runtime.Type, op OpType) *Opcode { +	return newOpCodeWithNext(ctx, typ, op, newEndOp(ctx, typ)) +} + +func opcodeOffset(idx int) uint32 { +	return uint32(idx) * uintptrSize +} + +func getCodeAddrByIdx(head *Opcode, idx uint32) *Opcode { +	addr := uintptr(unsafe.Pointer(head)) + uintptr(idx)*unsafe.Sizeof(Opcode{}) +	return *(**Opcode)(unsafe.Pointer(&addr)) +} + +func copyOpcode(code *Opcode) *Opcode { +	codeNum := ToEndCode(code).DisplayIdx + 1 +	codeSlice := make([]Opcode, codeNum) +	head := (*Opcode)((*runtime.SliceHeader)(unsafe.Pointer(&codeSlice)).Data) +	ptr := head +	c := code +	for { +		*ptr = Opcode{ +			Op:         c.Op, +			Key:        c.Key, +			PtrNum:     c.PtrNum, +			NumBitSize: c.NumBitSize, +			Flags:      c.Flags, +			Idx:        c.Idx, +			Offset:     c.Offset, +			Type:       c.Type, +			FieldQuery: c.FieldQuery, +			DisplayIdx: c.DisplayIdx, +			DisplayKey: c.DisplayKey, +			ElemIdx:    c.ElemIdx, +			Length:     c.Length, +			Size:       c.Size, +			Indent:     c.Indent, +			Jmp:        c.Jmp, +		} +		if c.End != nil { +			ptr.End = getCodeAddrByIdx(head, c.End.DisplayIdx) +		} +		if c.NextField != nil { +			ptr.NextField = getCodeAddrByIdx(head, c.NextField.DisplayIdx) +		} +		if c.Next != nil { +			ptr.Next = getCodeAddrByIdx(head, c.Next.DisplayIdx) +		} +		if c.IsEnd() { +			break +		} +		ptr = getCodeAddrByIdx(head, c.DisplayIdx+1) +		c = c.IterNext() +	} +	return head +} + +func setTotalLengthToInterfaceOp(code *Opcode) { +	for c := code; !c.IsEnd(); { +		if c.Op == OpInterface || c.Op == OpInterfacePtr { +			c.Length = uint32(code.TotalLength()) +		} +		c = c.IterNext() +	} +} + +func ToEndCode(code *Opcode) *Opcode { +	c := code +	for !c.IsEnd() { +		c = c.IterNext() +	} +	return c +} + +func copyToInterfaceOpcode(code *Opcode) *Opcode { +	copied := copyOpcode(code) +	c := copied +	c = ToEndCode(c) +	c.Idx += uintptrSize +	c.ElemIdx = c.Idx + uintptrSize +	c.Length = c.Idx + 2*uintptrSize +	c.Op = OpInterfaceEnd +	return copied +} + +func newOpCodeWithNext(ctx *compileContext, typ *runtime.Type, op OpType, next *Opcode) *Opcode { +	return &Opcode{ +		Op:         op, +		Idx:        opcodeOffset(ctx.ptrIndex), +		Next:       next, +		Type:       typ, +		DisplayIdx: ctx.opcodeIndex, +		Indent:     ctx.indent, +	} +} + +func newEndOp(ctx *compileContext, typ *runtime.Type) *Opcode { +	return newOpCodeWithNext(ctx, typ, OpEnd, nil) +} + +func (c *Opcode) TotalLength() int { +	var idx int +	code := c +	for !code.IsEnd() { +		maxIdx := int(code.MaxIdx() / uintptrSize) +		if idx < maxIdx { +			idx = maxIdx +		} +		if code.Op == OpRecursiveEnd { +			break +		} +		code = code.IterNext() +	} +	maxIdx := int(code.MaxIdx() / uintptrSize) +	if idx < maxIdx { +		idx = maxIdx +	} +	return idx + 1 +} + +func (c *Opcode) dumpHead(code *Opcode) string { +	var length uint32 +	if code.Op.CodeType() == CodeArrayHead { +		length = code.Length +	} else { +		length = code.Length / uintptrSize +	} +	return fmt.Sprintf( +		`[%03d]%s%s ([idx:%d][elemIdx:%d][length:%d])`, +		code.DisplayIdx, +		strings.Repeat("-", int(code.Indent)), +		code.Op, +		code.Idx/uintptrSize, +		code.ElemIdx/uintptrSize, +		length, +	) +} + +func (c *Opcode) dumpMapHead(code *Opcode) string { +	return fmt.Sprintf( +		`[%03d]%s%s ([idx:%d])`, +		code.DisplayIdx, +		strings.Repeat("-", int(code.Indent)), +		code.Op, +		code.Idx/uintptrSize, +	) +} + +func (c *Opcode) dumpMapEnd(code *Opcode) string { +	return fmt.Sprintf( +		`[%03d]%s%s ([idx:%d])`, +		code.DisplayIdx, +		strings.Repeat("-", int(code.Indent)), +		code.Op, +		code.Idx/uintptrSize, +	) +} + +func (c *Opcode) dumpElem(code *Opcode) string { +	var length uint32 +	if code.Op.CodeType() == CodeArrayElem { +		length = code.Length +	} else { +		length = code.Length / uintptrSize +	} +	return fmt.Sprintf( +		`[%03d]%s%s ([idx:%d][elemIdx:%d][length:%d][size:%d])`, +		code.DisplayIdx, +		strings.Repeat("-", int(code.Indent)), +		code.Op, +		code.Idx/uintptrSize, +		code.ElemIdx/uintptrSize, +		length, +		code.Size, +	) +} + +func (c *Opcode) dumpField(code *Opcode) string { +	return fmt.Sprintf( +		`[%03d]%s%s ([idx:%d][key:%s][offset:%d])`, +		code.DisplayIdx, +		strings.Repeat("-", int(code.Indent)), +		code.Op, +		code.Idx/uintptrSize, +		code.DisplayKey, +		code.Offset, +	) +} + +func (c *Opcode) dumpKey(code *Opcode) string { +	return fmt.Sprintf( +		`[%03d]%s%s ([idx:%d])`, +		code.DisplayIdx, +		strings.Repeat("-", int(code.Indent)), +		code.Op, +		code.Idx/uintptrSize, +	) +} + +func (c *Opcode) dumpValue(code *Opcode) string { +	return fmt.Sprintf( +		`[%03d]%s%s ([idx:%d])`, +		code.DisplayIdx, +		strings.Repeat("-", int(code.Indent)), +		code.Op, +		code.Idx/uintptrSize, +	) +} + +func (c *Opcode) Dump() string { +	codes := []string{} +	for code := c; !code.IsEnd(); { +		switch code.Op.CodeType() { +		case CodeSliceHead: +			codes = append(codes, c.dumpHead(code)) +			code = code.Next +		case CodeMapHead: +			codes = append(codes, c.dumpMapHead(code)) +			code = code.Next +		case CodeArrayElem, CodeSliceElem: +			codes = append(codes, c.dumpElem(code)) +			code = code.End +		case CodeMapKey: +			codes = append(codes, c.dumpKey(code)) +			code = code.End +		case CodeMapValue: +			codes = append(codes, c.dumpValue(code)) +			code = code.Next +		case CodeMapEnd: +			codes = append(codes, c.dumpMapEnd(code)) +			code = code.Next +		case CodeStructField: +			codes = append(codes, c.dumpField(code)) +			code = code.Next +		case CodeStructEnd: +			codes = append(codes, c.dumpField(code)) +			code = code.Next +		default: +			codes = append(codes, fmt.Sprintf( +				"[%03d]%s%s ([idx:%d])", +				code.DisplayIdx, +				strings.Repeat("-", int(code.Indent)), +				code.Op, +				code.Idx/uintptrSize, +			)) +			code = code.Next +		} +	} +	return strings.Join(codes, "\n") +} + +func newSliceHeaderCode(ctx *compileContext, typ *runtime.Type) *Opcode { +	idx := opcodeOffset(ctx.ptrIndex) +	ctx.incPtrIndex() +	elemIdx := opcodeOffset(ctx.ptrIndex) +	ctx.incPtrIndex() +	length := opcodeOffset(ctx.ptrIndex) +	return &Opcode{ +		Op:         OpSlice, +		Type:       typ, +		Idx:        idx, +		DisplayIdx: ctx.opcodeIndex, +		ElemIdx:    elemIdx, +		Length:     length, +		Indent:     ctx.indent, +	} +} + +func newSliceElemCode(ctx *compileContext, typ *runtime.Type, head *Opcode, size uintptr) *Opcode { +	return &Opcode{ +		Op:         OpSliceElem, +		Type:       typ, +		Idx:        head.Idx, +		DisplayIdx: ctx.opcodeIndex, +		ElemIdx:    head.ElemIdx, +		Length:     head.Length, +		Indent:     ctx.indent, +		Size:       uint32(size), +	} +} + +func newArrayHeaderCode(ctx *compileContext, typ *runtime.Type, alen int) *Opcode { +	idx := opcodeOffset(ctx.ptrIndex) +	ctx.incPtrIndex() +	elemIdx := opcodeOffset(ctx.ptrIndex) +	return &Opcode{ +		Op:         OpArray, +		Type:       typ, +		Idx:        idx, +		DisplayIdx: ctx.opcodeIndex, +		ElemIdx:    elemIdx, +		Indent:     ctx.indent, +		Length:     uint32(alen), +	} +} + +func newArrayElemCode(ctx *compileContext, typ *runtime.Type, head *Opcode, length int, size uintptr) *Opcode { +	return &Opcode{ +		Op:         OpArrayElem, +		Type:       typ, +		Idx:        head.Idx, +		DisplayIdx: ctx.opcodeIndex, +		ElemIdx:    head.ElemIdx, +		Length:     uint32(length), +		Indent:     ctx.indent, +		Size:       uint32(size), +	} +} + +func newMapHeaderCode(ctx *compileContext, typ *runtime.Type) *Opcode { +	idx := opcodeOffset(ctx.ptrIndex) +	ctx.incPtrIndex() +	return &Opcode{ +		Op:         OpMap, +		Type:       typ, +		Idx:        idx, +		DisplayIdx: ctx.opcodeIndex, +		Indent:     ctx.indent, +	} +} + +func newMapKeyCode(ctx *compileContext, typ *runtime.Type, head *Opcode) *Opcode { +	return &Opcode{ +		Op:         OpMapKey, +		Type:       typ, +		Idx:        head.Idx, +		DisplayIdx: ctx.opcodeIndex, +		Indent:     ctx.indent, +	} +} + +func newMapValueCode(ctx *compileContext, typ *runtime.Type, head *Opcode) *Opcode { +	return &Opcode{ +		Op:         OpMapValue, +		Type:       typ, +		Idx:        head.Idx, +		DisplayIdx: ctx.opcodeIndex, +		Indent:     ctx.indent, +	} +} + +func newMapEndCode(ctx *compileContext, typ *runtime.Type, head *Opcode) *Opcode { +	return &Opcode{ +		Op:         OpMapEnd, +		Type:       typ, +		Idx:        head.Idx, +		DisplayIdx: ctx.opcodeIndex, +		Indent:     ctx.indent, +		Next:       newEndOp(ctx, typ), +	} +} + +func newRecursiveCode(ctx *compileContext, typ *runtime.Type, jmp *CompiledCode) *Opcode { +	return &Opcode{ +		Op:         OpRecursive, +		Type:       typ, +		Idx:        opcodeOffset(ctx.ptrIndex), +		Next:       newEndOp(ctx, typ), +		DisplayIdx: ctx.opcodeIndex, +		Indent:     ctx.indent, +		Jmp:        jmp, +	} +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/option.go b/vendor/github.com/goccy/go-json/internal/encoder/option.go new file mode 100644 index 000000000..82d5ce3e7 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/option.go @@ -0,0 +1,47 @@ +package encoder + +import ( +	"context" +	"io" +) + +type OptionFlag uint8 + +const ( +	HTMLEscapeOption OptionFlag = 1 << iota +	IndentOption +	UnorderedMapOption +	DebugOption +	ColorizeOption +	ContextOption +	NormalizeUTF8Option +	FieldQueryOption +) + +type Option struct { +	Flag        OptionFlag +	ColorScheme *ColorScheme +	Context     context.Context +	DebugOut    io.Writer +} + +type EncodeFormat struct { +	Header string +	Footer string +} + +type EncodeFormatScheme struct { +	Int       EncodeFormat +	Uint      EncodeFormat +	Float     EncodeFormat +	Bool      EncodeFormat +	String    EncodeFormat +	Binary    EncodeFormat +	ObjectKey EncodeFormat +	Null      EncodeFormat +} + +type ( +	ColorScheme = EncodeFormatScheme +	ColorFormat = EncodeFormat +) diff --git a/vendor/github.com/goccy/go-json/internal/encoder/optype.go b/vendor/github.com/goccy/go-json/internal/encoder/optype.go new file mode 100644 index 000000000..5c1241b47 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/optype.go @@ -0,0 +1,932 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package encoder + +import ( +	"strings" +) + +type CodeType int + +const ( +	CodeOp          CodeType = 0 +	CodeArrayHead   CodeType = 1 +	CodeArrayElem   CodeType = 2 +	CodeSliceHead   CodeType = 3 +	CodeSliceElem   CodeType = 4 +	CodeMapHead     CodeType = 5 +	CodeMapKey      CodeType = 6 +	CodeMapValue    CodeType = 7 +	CodeMapEnd      CodeType = 8 +	CodeRecursive   CodeType = 9 +	CodeStructField CodeType = 10 +	CodeStructEnd   CodeType = 11 +) + +var opTypeStrings = [400]string{ +	"End", +	"Interface", +	"Ptr", +	"SliceElem", +	"SliceEnd", +	"ArrayElem", +	"ArrayEnd", +	"MapKey", +	"MapValue", +	"MapEnd", +	"Recursive", +	"RecursivePtr", +	"RecursiveEnd", +	"InterfaceEnd", +	"Int", +	"Uint", +	"Float32", +	"Float64", +	"Bool", +	"String", +	"Bytes", +	"Number", +	"Array", +	"Map", +	"Slice", +	"Struct", +	"MarshalJSON", +	"MarshalText", +	"IntString", +	"UintString", +	"Float32String", +	"Float64String", +	"BoolString", +	"StringString", +	"NumberString", +	"IntPtr", +	"UintPtr", +	"Float32Ptr", +	"Float64Ptr", +	"BoolPtr", +	"StringPtr", +	"BytesPtr", +	"NumberPtr", +	"ArrayPtr", +	"MapPtr", +	"SlicePtr", +	"MarshalJSONPtr", +	"MarshalTextPtr", +	"InterfacePtr", +	"IntPtrString", +	"UintPtrString", +	"Float32PtrString", +	"Float64PtrString", +	"BoolPtrString", +	"StringPtrString", +	"NumberPtrString", +	"StructHeadInt", +	"StructHeadOmitEmptyInt", +	"StructPtrHeadInt", +	"StructPtrHeadOmitEmptyInt", +	"StructHeadUint", +	"StructHeadOmitEmptyUint", +	"StructPtrHeadUint", +	"StructPtrHeadOmitEmptyUint", +	"StructHeadFloat32", +	"StructHeadOmitEmptyFloat32", +	"StructPtrHeadFloat32", +	"StructPtrHeadOmitEmptyFloat32", +	"StructHeadFloat64", +	"StructHeadOmitEmptyFloat64", +	"StructPtrHeadFloat64", +	"StructPtrHeadOmitEmptyFloat64", +	"StructHeadBool", +	"StructHeadOmitEmptyBool", +	"StructPtrHeadBool", +	"StructPtrHeadOmitEmptyBool", +	"StructHeadString", +	"StructHeadOmitEmptyString", +	"StructPtrHeadString", +	"StructPtrHeadOmitEmptyString", +	"StructHeadBytes", +	"StructHeadOmitEmptyBytes", +	"StructPtrHeadBytes", +	"StructPtrHeadOmitEmptyBytes", +	"StructHeadNumber", +	"StructHeadOmitEmptyNumber", +	"StructPtrHeadNumber", +	"StructPtrHeadOmitEmptyNumber", +	"StructHeadArray", +	"StructHeadOmitEmptyArray", +	"StructPtrHeadArray", +	"StructPtrHeadOmitEmptyArray", +	"StructHeadMap", +	"StructHeadOmitEmptyMap", +	"StructPtrHeadMap", +	"StructPtrHeadOmitEmptyMap", +	"StructHeadSlice", +	"StructHeadOmitEmptySlice", +	"StructPtrHeadSlice", +	"StructPtrHeadOmitEmptySlice", +	"StructHeadStruct", +	"StructHeadOmitEmptyStruct", +	"StructPtrHeadStruct", +	"StructPtrHeadOmitEmptyStruct", +	"StructHeadMarshalJSON", +	"StructHeadOmitEmptyMarshalJSON", +	"StructPtrHeadMarshalJSON", +	"StructPtrHeadOmitEmptyMarshalJSON", +	"StructHeadMarshalText", +	"StructHeadOmitEmptyMarshalText", +	"StructPtrHeadMarshalText", +	"StructPtrHeadOmitEmptyMarshalText", +	"StructHeadIntString", +	"StructHeadOmitEmptyIntString", +	"StructPtrHeadIntString", +	"StructPtrHeadOmitEmptyIntString", +	"StructHeadUintString", +	"StructHeadOmitEmptyUintString", +	"StructPtrHeadUintString", +	"StructPtrHeadOmitEmptyUintString", +	"StructHeadFloat32String", +	"StructHeadOmitEmptyFloat32String", +	"StructPtrHeadFloat32String", +	"StructPtrHeadOmitEmptyFloat32String", +	"StructHeadFloat64String", +	"StructHeadOmitEmptyFloat64String", +	"StructPtrHeadFloat64String", +	"StructPtrHeadOmitEmptyFloat64String", +	"StructHeadBoolString", +	"StructHeadOmitEmptyBoolString", +	"StructPtrHeadBoolString", +	"StructPtrHeadOmitEmptyBoolString", +	"StructHeadStringString", +	"StructHeadOmitEmptyStringString", +	"StructPtrHeadStringString", +	"StructPtrHeadOmitEmptyStringString", +	"StructHeadNumberString", +	"StructHeadOmitEmptyNumberString", +	"StructPtrHeadNumberString", +	"StructPtrHeadOmitEmptyNumberString", +	"StructHeadIntPtr", +	"StructHeadOmitEmptyIntPtr", +	"StructPtrHeadIntPtr", +	"StructPtrHeadOmitEmptyIntPtr", +	"StructHeadUintPtr", +	"StructHeadOmitEmptyUintPtr", +	"StructPtrHeadUintPtr", +	"StructPtrHeadOmitEmptyUintPtr", +	"StructHeadFloat32Ptr", +	"StructHeadOmitEmptyFloat32Ptr", +	"StructPtrHeadFloat32Ptr", +	"StructPtrHeadOmitEmptyFloat32Ptr", +	"StructHeadFloat64Ptr", +	"StructHeadOmitEmptyFloat64Ptr", +	"StructPtrHeadFloat64Ptr", +	"StructPtrHeadOmitEmptyFloat64Ptr", +	"StructHeadBoolPtr", +	"StructHeadOmitEmptyBoolPtr", +	"StructPtrHeadBoolPtr", +	"StructPtrHeadOmitEmptyBoolPtr", +	"StructHeadStringPtr", +	"StructHeadOmitEmptyStringPtr", +	"StructPtrHeadStringPtr", +	"StructPtrHeadOmitEmptyStringPtr", +	"StructHeadBytesPtr", +	"StructHeadOmitEmptyBytesPtr", +	"StructPtrHeadBytesPtr", +	"StructPtrHeadOmitEmptyBytesPtr", +	"StructHeadNumberPtr", +	"StructHeadOmitEmptyNumberPtr", +	"StructPtrHeadNumberPtr", +	"StructPtrHeadOmitEmptyNumberPtr", +	"StructHeadArrayPtr", +	"StructHeadOmitEmptyArrayPtr", +	"StructPtrHeadArrayPtr", +	"StructPtrHeadOmitEmptyArrayPtr", +	"StructHeadMapPtr", +	"StructHeadOmitEmptyMapPtr", +	"StructPtrHeadMapPtr", +	"StructPtrHeadOmitEmptyMapPtr", +	"StructHeadSlicePtr", +	"StructHeadOmitEmptySlicePtr", +	"StructPtrHeadSlicePtr", +	"StructPtrHeadOmitEmptySlicePtr", +	"StructHeadMarshalJSONPtr", +	"StructHeadOmitEmptyMarshalJSONPtr", +	"StructPtrHeadMarshalJSONPtr", +	"StructPtrHeadOmitEmptyMarshalJSONPtr", +	"StructHeadMarshalTextPtr", +	"StructHeadOmitEmptyMarshalTextPtr", +	"StructPtrHeadMarshalTextPtr", +	"StructPtrHeadOmitEmptyMarshalTextPtr", +	"StructHeadInterfacePtr", +	"StructHeadOmitEmptyInterfacePtr", +	"StructPtrHeadInterfacePtr", +	"StructPtrHeadOmitEmptyInterfacePtr", +	"StructHeadIntPtrString", +	"StructHeadOmitEmptyIntPtrString", +	"StructPtrHeadIntPtrString", +	"StructPtrHeadOmitEmptyIntPtrString", +	"StructHeadUintPtrString", +	"StructHeadOmitEmptyUintPtrString", +	"StructPtrHeadUintPtrString", +	"StructPtrHeadOmitEmptyUintPtrString", +	"StructHeadFloat32PtrString", +	"StructHeadOmitEmptyFloat32PtrString", +	"StructPtrHeadFloat32PtrString", +	"StructPtrHeadOmitEmptyFloat32PtrString", +	"StructHeadFloat64PtrString", +	"StructHeadOmitEmptyFloat64PtrString", +	"StructPtrHeadFloat64PtrString", +	"StructPtrHeadOmitEmptyFloat64PtrString", +	"StructHeadBoolPtrString", +	"StructHeadOmitEmptyBoolPtrString", +	"StructPtrHeadBoolPtrString", +	"StructPtrHeadOmitEmptyBoolPtrString", +	"StructHeadStringPtrString", +	"StructHeadOmitEmptyStringPtrString", +	"StructPtrHeadStringPtrString", +	"StructPtrHeadOmitEmptyStringPtrString", +	"StructHeadNumberPtrString", +	"StructHeadOmitEmptyNumberPtrString", +	"StructPtrHeadNumberPtrString", +	"StructPtrHeadOmitEmptyNumberPtrString", +	"StructHead", +	"StructHeadOmitEmpty", +	"StructPtrHead", +	"StructPtrHeadOmitEmpty", +	"StructFieldInt", +	"StructFieldOmitEmptyInt", +	"StructEndInt", +	"StructEndOmitEmptyInt", +	"StructFieldUint", +	"StructFieldOmitEmptyUint", +	"StructEndUint", +	"StructEndOmitEmptyUint", +	"StructFieldFloat32", +	"StructFieldOmitEmptyFloat32", +	"StructEndFloat32", +	"StructEndOmitEmptyFloat32", +	"StructFieldFloat64", +	"StructFieldOmitEmptyFloat64", +	"StructEndFloat64", +	"StructEndOmitEmptyFloat64", +	"StructFieldBool", +	"StructFieldOmitEmptyBool", +	"StructEndBool", +	"StructEndOmitEmptyBool", +	"StructFieldString", +	"StructFieldOmitEmptyString", +	"StructEndString", +	"StructEndOmitEmptyString", +	"StructFieldBytes", +	"StructFieldOmitEmptyBytes", +	"StructEndBytes", +	"StructEndOmitEmptyBytes", +	"StructFieldNumber", +	"StructFieldOmitEmptyNumber", +	"StructEndNumber", +	"StructEndOmitEmptyNumber", +	"StructFieldArray", +	"StructFieldOmitEmptyArray", +	"StructEndArray", +	"StructEndOmitEmptyArray", +	"StructFieldMap", +	"StructFieldOmitEmptyMap", +	"StructEndMap", +	"StructEndOmitEmptyMap", +	"StructFieldSlice", +	"StructFieldOmitEmptySlice", +	"StructEndSlice", +	"StructEndOmitEmptySlice", +	"StructFieldStruct", +	"StructFieldOmitEmptyStruct", +	"StructEndStruct", +	"StructEndOmitEmptyStruct", +	"StructFieldMarshalJSON", +	"StructFieldOmitEmptyMarshalJSON", +	"StructEndMarshalJSON", +	"StructEndOmitEmptyMarshalJSON", +	"StructFieldMarshalText", +	"StructFieldOmitEmptyMarshalText", +	"StructEndMarshalText", +	"StructEndOmitEmptyMarshalText", +	"StructFieldIntString", +	"StructFieldOmitEmptyIntString", +	"StructEndIntString", +	"StructEndOmitEmptyIntString", +	"StructFieldUintString", +	"StructFieldOmitEmptyUintString", +	"StructEndUintString", +	"StructEndOmitEmptyUintString", +	"StructFieldFloat32String", +	"StructFieldOmitEmptyFloat32String", +	"StructEndFloat32String", +	"StructEndOmitEmptyFloat32String", +	"StructFieldFloat64String", +	"StructFieldOmitEmptyFloat64String", +	"StructEndFloat64String", +	"StructEndOmitEmptyFloat64String", +	"StructFieldBoolString", +	"StructFieldOmitEmptyBoolString", +	"StructEndBoolString", +	"StructEndOmitEmptyBoolString", +	"StructFieldStringString", +	"StructFieldOmitEmptyStringString", +	"StructEndStringString", +	"StructEndOmitEmptyStringString", +	"StructFieldNumberString", +	"StructFieldOmitEmptyNumberString", +	"StructEndNumberString", +	"StructEndOmitEmptyNumberString", +	"StructFieldIntPtr", +	"StructFieldOmitEmptyIntPtr", +	"StructEndIntPtr", +	"StructEndOmitEmptyIntPtr", +	"StructFieldUintPtr", +	"StructFieldOmitEmptyUintPtr", +	"StructEndUintPtr", +	"StructEndOmitEmptyUintPtr", +	"StructFieldFloat32Ptr", +	"StructFieldOmitEmptyFloat32Ptr", +	"StructEndFloat32Ptr", +	"StructEndOmitEmptyFloat32Ptr", +	"StructFieldFloat64Ptr", +	"StructFieldOmitEmptyFloat64Ptr", +	"StructEndFloat64Ptr", +	"StructEndOmitEmptyFloat64Ptr", +	"StructFieldBoolPtr", +	"StructFieldOmitEmptyBoolPtr", +	"StructEndBoolPtr", +	"StructEndOmitEmptyBoolPtr", +	"StructFieldStringPtr", +	"StructFieldOmitEmptyStringPtr", +	"StructEndStringPtr", +	"StructEndOmitEmptyStringPtr", +	"StructFieldBytesPtr", +	"StructFieldOmitEmptyBytesPtr", +	"StructEndBytesPtr", +	"StructEndOmitEmptyBytesPtr", +	"StructFieldNumberPtr", +	"StructFieldOmitEmptyNumberPtr", +	"StructEndNumberPtr", +	"StructEndOmitEmptyNumberPtr", +	"StructFieldArrayPtr", +	"StructFieldOmitEmptyArrayPtr", +	"StructEndArrayPtr", +	"StructEndOmitEmptyArrayPtr", +	"StructFieldMapPtr", +	"StructFieldOmitEmptyMapPtr", +	"StructEndMapPtr", +	"StructEndOmitEmptyMapPtr", +	"StructFieldSlicePtr", +	"StructFieldOmitEmptySlicePtr", +	"StructEndSlicePtr", +	"StructEndOmitEmptySlicePtr", +	"StructFieldMarshalJSONPtr", +	"StructFieldOmitEmptyMarshalJSONPtr", +	"StructEndMarshalJSONPtr", +	"StructEndOmitEmptyMarshalJSONPtr", +	"StructFieldMarshalTextPtr", +	"StructFieldOmitEmptyMarshalTextPtr", +	"StructEndMarshalTextPtr", +	"StructEndOmitEmptyMarshalTextPtr", +	"StructFieldInterfacePtr", +	"StructFieldOmitEmptyInterfacePtr", +	"StructEndInterfacePtr", +	"StructEndOmitEmptyInterfacePtr", +	"StructFieldIntPtrString", +	"StructFieldOmitEmptyIntPtrString", +	"StructEndIntPtrString", +	"StructEndOmitEmptyIntPtrString", +	"StructFieldUintPtrString", +	"StructFieldOmitEmptyUintPtrString", +	"StructEndUintPtrString", +	"StructEndOmitEmptyUintPtrString", +	"StructFieldFloat32PtrString", +	"StructFieldOmitEmptyFloat32PtrString", +	"StructEndFloat32PtrString", +	"StructEndOmitEmptyFloat32PtrString", +	"StructFieldFloat64PtrString", +	"StructFieldOmitEmptyFloat64PtrString", +	"StructEndFloat64PtrString", +	"StructEndOmitEmptyFloat64PtrString", +	"StructFieldBoolPtrString", +	"StructFieldOmitEmptyBoolPtrString", +	"StructEndBoolPtrString", +	"StructEndOmitEmptyBoolPtrString", +	"StructFieldStringPtrString", +	"StructFieldOmitEmptyStringPtrString", +	"StructEndStringPtrString", +	"StructEndOmitEmptyStringPtrString", +	"StructFieldNumberPtrString", +	"StructFieldOmitEmptyNumberPtrString", +	"StructEndNumberPtrString", +	"StructEndOmitEmptyNumberPtrString", +	"StructField", +	"StructFieldOmitEmpty", +	"StructEnd", +	"StructEndOmitEmpty", +} + +type OpType uint16 + +const ( +	OpEnd                                    OpType = 0 +	OpInterface                              OpType = 1 +	OpPtr                                    OpType = 2 +	OpSliceElem                              OpType = 3 +	OpSliceEnd                               OpType = 4 +	OpArrayElem                              OpType = 5 +	OpArrayEnd                               OpType = 6 +	OpMapKey                                 OpType = 7 +	OpMapValue                               OpType = 8 +	OpMapEnd                                 OpType = 9 +	OpRecursive                              OpType = 10 +	OpRecursivePtr                           OpType = 11 +	OpRecursiveEnd                           OpType = 12 +	OpInterfaceEnd                           OpType = 13 +	OpInt                                    OpType = 14 +	OpUint                                   OpType = 15 +	OpFloat32                                OpType = 16 +	OpFloat64                                OpType = 17 +	OpBool                                   OpType = 18 +	OpString                                 OpType = 19 +	OpBytes                                  OpType = 20 +	OpNumber                                 OpType = 21 +	OpArray                                  OpType = 22 +	OpMap                                    OpType = 23 +	OpSlice                                  OpType = 24 +	OpStruct                                 OpType = 25 +	OpMarshalJSON                            OpType = 26 +	OpMarshalText                            OpType = 27 +	OpIntString                              OpType = 28 +	OpUintString                             OpType = 29 +	OpFloat32String                          OpType = 30 +	OpFloat64String                          OpType = 31 +	OpBoolString                             OpType = 32 +	OpStringString                           OpType = 33 +	OpNumberString                           OpType = 34 +	OpIntPtr                                 OpType = 35 +	OpUintPtr                                OpType = 36 +	OpFloat32Ptr                             OpType = 37 +	OpFloat64Ptr                             OpType = 38 +	OpBoolPtr                                OpType = 39 +	OpStringPtr                              OpType = 40 +	OpBytesPtr                               OpType = 41 +	OpNumberPtr                              OpType = 42 +	OpArrayPtr                               OpType = 43 +	OpMapPtr                                 OpType = 44 +	OpSlicePtr                               OpType = 45 +	OpMarshalJSONPtr                         OpType = 46 +	OpMarshalTextPtr                         OpType = 47 +	OpInterfacePtr                           OpType = 48 +	OpIntPtrString                           OpType = 49 +	OpUintPtrString                          OpType = 50 +	OpFloat32PtrString                       OpType = 51 +	OpFloat64PtrString                       OpType = 52 +	OpBoolPtrString                          OpType = 53 +	OpStringPtrString                        OpType = 54 +	OpNumberPtrString                        OpType = 55 +	OpStructHeadInt                          OpType = 56 +	OpStructHeadOmitEmptyInt                 OpType = 57 +	OpStructPtrHeadInt                       OpType = 58 +	OpStructPtrHeadOmitEmptyInt              OpType = 59 +	OpStructHeadUint                         OpType = 60 +	OpStructHeadOmitEmptyUint                OpType = 61 +	OpStructPtrHeadUint                      OpType = 62 +	OpStructPtrHeadOmitEmptyUint             OpType = 63 +	OpStructHeadFloat32                      OpType = 64 +	OpStructHeadOmitEmptyFloat32             OpType = 65 +	OpStructPtrHeadFloat32                   OpType = 66 +	OpStructPtrHeadOmitEmptyFloat32          OpType = 67 +	OpStructHeadFloat64                      OpType = 68 +	OpStructHeadOmitEmptyFloat64             OpType = 69 +	OpStructPtrHeadFloat64                   OpType = 70 +	OpStructPtrHeadOmitEmptyFloat64          OpType = 71 +	OpStructHeadBool                         OpType = 72 +	OpStructHeadOmitEmptyBool                OpType = 73 +	OpStructPtrHeadBool                      OpType = 74 +	OpStructPtrHeadOmitEmptyBool             OpType = 75 +	OpStructHeadString                       OpType = 76 +	OpStructHeadOmitEmptyString              OpType = 77 +	OpStructPtrHeadString                    OpType = 78 +	OpStructPtrHeadOmitEmptyString           OpType = 79 +	OpStructHeadBytes                        OpType = 80 +	OpStructHeadOmitEmptyBytes               OpType = 81 +	OpStructPtrHeadBytes                     OpType = 82 +	OpStructPtrHeadOmitEmptyBytes            OpType = 83 +	OpStructHeadNumber                       OpType = 84 +	OpStructHeadOmitEmptyNumber              OpType = 85 +	OpStructPtrHeadNumber                    OpType = 86 +	OpStructPtrHeadOmitEmptyNumber           OpType = 87 +	OpStructHeadArray                        OpType = 88 +	OpStructHeadOmitEmptyArray               OpType = 89 +	OpStructPtrHeadArray                     OpType = 90 +	OpStructPtrHeadOmitEmptyArray            OpType = 91 +	OpStructHeadMap                          OpType = 92 +	OpStructHeadOmitEmptyMap                 OpType = 93 +	OpStructPtrHeadMap                       OpType = 94 +	OpStructPtrHeadOmitEmptyMap              OpType = 95 +	OpStructHeadSlice                        OpType = 96 +	OpStructHeadOmitEmptySlice               OpType = 97 +	OpStructPtrHeadSlice                     OpType = 98 +	OpStructPtrHeadOmitEmptySlice            OpType = 99 +	OpStructHeadStruct                       OpType = 100 +	OpStructHeadOmitEmptyStruct              OpType = 101 +	OpStructPtrHeadStruct                    OpType = 102 +	OpStructPtrHeadOmitEmptyStruct           OpType = 103 +	OpStructHeadMarshalJSON                  OpType = 104 +	OpStructHeadOmitEmptyMarshalJSON         OpType = 105 +	OpStructPtrHeadMarshalJSON               OpType = 106 +	OpStructPtrHeadOmitEmptyMarshalJSON      OpType = 107 +	OpStructHeadMarshalText                  OpType = 108 +	OpStructHeadOmitEmptyMarshalText         OpType = 109 +	OpStructPtrHeadMarshalText               OpType = 110 +	OpStructPtrHeadOmitEmptyMarshalText      OpType = 111 +	OpStructHeadIntString                    OpType = 112 +	OpStructHeadOmitEmptyIntString           OpType = 113 +	OpStructPtrHeadIntString                 OpType = 114 +	OpStructPtrHeadOmitEmptyIntString        OpType = 115 +	OpStructHeadUintString                   OpType = 116 +	OpStructHeadOmitEmptyUintString          OpType = 117 +	OpStructPtrHeadUintString                OpType = 118 +	OpStructPtrHeadOmitEmptyUintString       OpType = 119 +	OpStructHeadFloat32String                OpType = 120 +	OpStructHeadOmitEmptyFloat32String       OpType = 121 +	OpStructPtrHeadFloat32String             OpType = 122 +	OpStructPtrHeadOmitEmptyFloat32String    OpType = 123 +	OpStructHeadFloat64String                OpType = 124 +	OpStructHeadOmitEmptyFloat64String       OpType = 125 +	OpStructPtrHeadFloat64String             OpType = 126 +	OpStructPtrHeadOmitEmptyFloat64String    OpType = 127 +	OpStructHeadBoolString                   OpType = 128 +	OpStructHeadOmitEmptyBoolString          OpType = 129 +	OpStructPtrHeadBoolString                OpType = 130 +	OpStructPtrHeadOmitEmptyBoolString       OpType = 131 +	OpStructHeadStringString                 OpType = 132 +	OpStructHeadOmitEmptyStringString        OpType = 133 +	OpStructPtrHeadStringString              OpType = 134 +	OpStructPtrHeadOmitEmptyStringString     OpType = 135 +	OpStructHeadNumberString                 OpType = 136 +	OpStructHeadOmitEmptyNumberString        OpType = 137 +	OpStructPtrHeadNumberString              OpType = 138 +	OpStructPtrHeadOmitEmptyNumberString     OpType = 139 +	OpStructHeadIntPtr                       OpType = 140 +	OpStructHeadOmitEmptyIntPtr              OpType = 141 +	OpStructPtrHeadIntPtr                    OpType = 142 +	OpStructPtrHeadOmitEmptyIntPtr           OpType = 143 +	OpStructHeadUintPtr                      OpType = 144 +	OpStructHeadOmitEmptyUintPtr             OpType = 145 +	OpStructPtrHeadUintPtr                   OpType = 146 +	OpStructPtrHeadOmitEmptyUintPtr          OpType = 147 +	OpStructHeadFloat32Ptr                   OpType = 148 +	OpStructHeadOmitEmptyFloat32Ptr          OpType = 149 +	OpStructPtrHeadFloat32Ptr                OpType = 150 +	OpStructPtrHeadOmitEmptyFloat32Ptr       OpType = 151 +	OpStructHeadFloat64Ptr                   OpType = 152 +	OpStructHeadOmitEmptyFloat64Ptr          OpType = 153 +	OpStructPtrHeadFloat64Ptr                OpType = 154 +	OpStructPtrHeadOmitEmptyFloat64Ptr       OpType = 155 +	OpStructHeadBoolPtr                      OpType = 156 +	OpStructHeadOmitEmptyBoolPtr             OpType = 157 +	OpStructPtrHeadBoolPtr                   OpType = 158 +	OpStructPtrHeadOmitEmptyBoolPtr          OpType = 159 +	OpStructHeadStringPtr                    OpType = 160 +	OpStructHeadOmitEmptyStringPtr           OpType = 161 +	OpStructPtrHeadStringPtr                 OpType = 162 +	OpStructPtrHeadOmitEmptyStringPtr        OpType = 163 +	OpStructHeadBytesPtr                     OpType = 164 +	OpStructHeadOmitEmptyBytesPtr            OpType = 165 +	OpStructPtrHeadBytesPtr                  OpType = 166 +	OpStructPtrHeadOmitEmptyBytesPtr         OpType = 167 +	OpStructHeadNumberPtr                    OpType = 168 +	OpStructHeadOmitEmptyNumberPtr           OpType = 169 +	OpStructPtrHeadNumberPtr                 OpType = 170 +	OpStructPtrHeadOmitEmptyNumberPtr        OpType = 171 +	OpStructHeadArrayPtr                     OpType = 172 +	OpStructHeadOmitEmptyArrayPtr            OpType = 173 +	OpStructPtrHeadArrayPtr                  OpType = 174 +	OpStructPtrHeadOmitEmptyArrayPtr         OpType = 175 +	OpStructHeadMapPtr                       OpType = 176 +	OpStructHeadOmitEmptyMapPtr              OpType = 177 +	OpStructPtrHeadMapPtr                    OpType = 178 +	OpStructPtrHeadOmitEmptyMapPtr           OpType = 179 +	OpStructHeadSlicePtr                     OpType = 180 +	OpStructHeadOmitEmptySlicePtr            OpType = 181 +	OpStructPtrHeadSlicePtr                  OpType = 182 +	OpStructPtrHeadOmitEmptySlicePtr         OpType = 183 +	OpStructHeadMarshalJSONPtr               OpType = 184 +	OpStructHeadOmitEmptyMarshalJSONPtr      OpType = 185 +	OpStructPtrHeadMarshalJSONPtr            OpType = 186 +	OpStructPtrHeadOmitEmptyMarshalJSONPtr   OpType = 187 +	OpStructHeadMarshalTextPtr               OpType = 188 +	OpStructHeadOmitEmptyMarshalTextPtr      OpType = 189 +	OpStructPtrHeadMarshalTextPtr            OpType = 190 +	OpStructPtrHeadOmitEmptyMarshalTextPtr   OpType = 191 +	OpStructHeadInterfacePtr                 OpType = 192 +	OpStructHeadOmitEmptyInterfacePtr        OpType = 193 +	OpStructPtrHeadInterfacePtr              OpType = 194 +	OpStructPtrHeadOmitEmptyInterfacePtr     OpType = 195 +	OpStructHeadIntPtrString                 OpType = 196 +	OpStructHeadOmitEmptyIntPtrString        OpType = 197 +	OpStructPtrHeadIntPtrString              OpType = 198 +	OpStructPtrHeadOmitEmptyIntPtrString     OpType = 199 +	OpStructHeadUintPtrString                OpType = 200 +	OpStructHeadOmitEmptyUintPtrString       OpType = 201 +	OpStructPtrHeadUintPtrString             OpType = 202 +	OpStructPtrHeadOmitEmptyUintPtrString    OpType = 203 +	OpStructHeadFloat32PtrString             OpType = 204 +	OpStructHeadOmitEmptyFloat32PtrString    OpType = 205 +	OpStructPtrHeadFloat32PtrString          OpType = 206 +	OpStructPtrHeadOmitEmptyFloat32PtrString OpType = 207 +	OpStructHeadFloat64PtrString             OpType = 208 +	OpStructHeadOmitEmptyFloat64PtrString    OpType = 209 +	OpStructPtrHeadFloat64PtrString          OpType = 210 +	OpStructPtrHeadOmitEmptyFloat64PtrString OpType = 211 +	OpStructHeadBoolPtrString                OpType = 212 +	OpStructHeadOmitEmptyBoolPtrString       OpType = 213 +	OpStructPtrHeadBoolPtrString             OpType = 214 +	OpStructPtrHeadOmitEmptyBoolPtrString    OpType = 215 +	OpStructHeadStringPtrString              OpType = 216 +	OpStructHeadOmitEmptyStringPtrString     OpType = 217 +	OpStructPtrHeadStringPtrString           OpType = 218 +	OpStructPtrHeadOmitEmptyStringPtrString  OpType = 219 +	OpStructHeadNumberPtrString              OpType = 220 +	OpStructHeadOmitEmptyNumberPtrString     OpType = 221 +	OpStructPtrHeadNumberPtrString           OpType = 222 +	OpStructPtrHeadOmitEmptyNumberPtrString  OpType = 223 +	OpStructHead                             OpType = 224 +	OpStructHeadOmitEmpty                    OpType = 225 +	OpStructPtrHead                          OpType = 226 +	OpStructPtrHeadOmitEmpty                 OpType = 227 +	OpStructFieldInt                         OpType = 228 +	OpStructFieldOmitEmptyInt                OpType = 229 +	OpStructEndInt                           OpType = 230 +	OpStructEndOmitEmptyInt                  OpType = 231 +	OpStructFieldUint                        OpType = 232 +	OpStructFieldOmitEmptyUint               OpType = 233 +	OpStructEndUint                          OpType = 234 +	OpStructEndOmitEmptyUint                 OpType = 235 +	OpStructFieldFloat32                     OpType = 236 +	OpStructFieldOmitEmptyFloat32            OpType = 237 +	OpStructEndFloat32                       OpType = 238 +	OpStructEndOmitEmptyFloat32              OpType = 239 +	OpStructFieldFloat64                     OpType = 240 +	OpStructFieldOmitEmptyFloat64            OpType = 241 +	OpStructEndFloat64                       OpType = 242 +	OpStructEndOmitEmptyFloat64              OpType = 243 +	OpStructFieldBool                        OpType = 244 +	OpStructFieldOmitEmptyBool               OpType = 245 +	OpStructEndBool                          OpType = 246 +	OpStructEndOmitEmptyBool                 OpType = 247 +	OpStructFieldString                      OpType = 248 +	OpStructFieldOmitEmptyString             OpType = 249 +	OpStructEndString                        OpType = 250 +	OpStructEndOmitEmptyString               OpType = 251 +	OpStructFieldBytes                       OpType = 252 +	OpStructFieldOmitEmptyBytes              OpType = 253 +	OpStructEndBytes                         OpType = 254 +	OpStructEndOmitEmptyBytes                OpType = 255 +	OpStructFieldNumber                      OpType = 256 +	OpStructFieldOmitEmptyNumber             OpType = 257 +	OpStructEndNumber                        OpType = 258 +	OpStructEndOmitEmptyNumber               OpType = 259 +	OpStructFieldArray                       OpType = 260 +	OpStructFieldOmitEmptyArray              OpType = 261 +	OpStructEndArray                         OpType = 262 +	OpStructEndOmitEmptyArray                OpType = 263 +	OpStructFieldMap                         OpType = 264 +	OpStructFieldOmitEmptyMap                OpType = 265 +	OpStructEndMap                           OpType = 266 +	OpStructEndOmitEmptyMap                  OpType = 267 +	OpStructFieldSlice                       OpType = 268 +	OpStructFieldOmitEmptySlice              OpType = 269 +	OpStructEndSlice                         OpType = 270 +	OpStructEndOmitEmptySlice                OpType = 271 +	OpStructFieldStruct                      OpType = 272 +	OpStructFieldOmitEmptyStruct             OpType = 273 +	OpStructEndStruct                        OpType = 274 +	OpStructEndOmitEmptyStruct               OpType = 275 +	OpStructFieldMarshalJSON                 OpType = 276 +	OpStructFieldOmitEmptyMarshalJSON        OpType = 277 +	OpStructEndMarshalJSON                   OpType = 278 +	OpStructEndOmitEmptyMarshalJSON          OpType = 279 +	OpStructFieldMarshalText                 OpType = 280 +	OpStructFieldOmitEmptyMarshalText        OpType = 281 +	OpStructEndMarshalText                   OpType = 282 +	OpStructEndOmitEmptyMarshalText          OpType = 283 +	OpStructFieldIntString                   OpType = 284 +	OpStructFieldOmitEmptyIntString          OpType = 285 +	OpStructEndIntString                     OpType = 286 +	OpStructEndOmitEmptyIntString            OpType = 287 +	OpStructFieldUintString                  OpType = 288 +	OpStructFieldOmitEmptyUintString         OpType = 289 +	OpStructEndUintString                    OpType = 290 +	OpStructEndOmitEmptyUintString           OpType = 291 +	OpStructFieldFloat32String               OpType = 292 +	OpStructFieldOmitEmptyFloat32String      OpType = 293 +	OpStructEndFloat32String                 OpType = 294 +	OpStructEndOmitEmptyFloat32String        OpType = 295 +	OpStructFieldFloat64String               OpType = 296 +	OpStructFieldOmitEmptyFloat64String      OpType = 297 +	OpStructEndFloat64String                 OpType = 298 +	OpStructEndOmitEmptyFloat64String        OpType = 299 +	OpStructFieldBoolString                  OpType = 300 +	OpStructFieldOmitEmptyBoolString         OpType = 301 +	OpStructEndBoolString                    OpType = 302 +	OpStructEndOmitEmptyBoolString           OpType = 303 +	OpStructFieldStringString                OpType = 304 +	OpStructFieldOmitEmptyStringString       OpType = 305 +	OpStructEndStringString                  OpType = 306 +	OpStructEndOmitEmptyStringString         OpType = 307 +	OpStructFieldNumberString                OpType = 308 +	OpStructFieldOmitEmptyNumberString       OpType = 309 +	OpStructEndNumberString                  OpType = 310 +	OpStructEndOmitEmptyNumberString         OpType = 311 +	OpStructFieldIntPtr                      OpType = 312 +	OpStructFieldOmitEmptyIntPtr             OpType = 313 +	OpStructEndIntPtr                        OpType = 314 +	OpStructEndOmitEmptyIntPtr               OpType = 315 +	OpStructFieldUintPtr                     OpType = 316 +	OpStructFieldOmitEmptyUintPtr            OpType = 317 +	OpStructEndUintPtr                       OpType = 318 +	OpStructEndOmitEmptyUintPtr              OpType = 319 +	OpStructFieldFloat32Ptr                  OpType = 320 +	OpStructFieldOmitEmptyFloat32Ptr         OpType = 321 +	OpStructEndFloat32Ptr                    OpType = 322 +	OpStructEndOmitEmptyFloat32Ptr           OpType = 323 +	OpStructFieldFloat64Ptr                  OpType = 324 +	OpStructFieldOmitEmptyFloat64Ptr         OpType = 325 +	OpStructEndFloat64Ptr                    OpType = 326 +	OpStructEndOmitEmptyFloat64Ptr           OpType = 327 +	OpStructFieldBoolPtr                     OpType = 328 +	OpStructFieldOmitEmptyBoolPtr            OpType = 329 +	OpStructEndBoolPtr                       OpType = 330 +	OpStructEndOmitEmptyBoolPtr              OpType = 331 +	OpStructFieldStringPtr                   OpType = 332 +	OpStructFieldOmitEmptyStringPtr          OpType = 333 +	OpStructEndStringPtr                     OpType = 334 +	OpStructEndOmitEmptyStringPtr            OpType = 335 +	OpStructFieldBytesPtr                    OpType = 336 +	OpStructFieldOmitEmptyBytesPtr           OpType = 337 +	OpStructEndBytesPtr                      OpType = 338 +	OpStructEndOmitEmptyBytesPtr             OpType = 339 +	OpStructFieldNumberPtr                   OpType = 340 +	OpStructFieldOmitEmptyNumberPtr          OpType = 341 +	OpStructEndNumberPtr                     OpType = 342 +	OpStructEndOmitEmptyNumberPtr            OpType = 343 +	OpStructFieldArrayPtr                    OpType = 344 +	OpStructFieldOmitEmptyArrayPtr           OpType = 345 +	OpStructEndArrayPtr                      OpType = 346 +	OpStructEndOmitEmptyArrayPtr             OpType = 347 +	OpStructFieldMapPtr                      OpType = 348 +	OpStructFieldOmitEmptyMapPtr             OpType = 349 +	OpStructEndMapPtr                        OpType = 350 +	OpStructEndOmitEmptyMapPtr               OpType = 351 +	OpStructFieldSlicePtr                    OpType = 352 +	OpStructFieldOmitEmptySlicePtr           OpType = 353 +	OpStructEndSlicePtr                      OpType = 354 +	OpStructEndOmitEmptySlicePtr             OpType = 355 +	OpStructFieldMarshalJSONPtr              OpType = 356 +	OpStructFieldOmitEmptyMarshalJSONPtr     OpType = 357 +	OpStructEndMarshalJSONPtr                OpType = 358 +	OpStructEndOmitEmptyMarshalJSONPtr       OpType = 359 +	OpStructFieldMarshalTextPtr              OpType = 360 +	OpStructFieldOmitEmptyMarshalTextPtr     OpType = 361 +	OpStructEndMarshalTextPtr                OpType = 362 +	OpStructEndOmitEmptyMarshalTextPtr       OpType = 363 +	OpStructFieldInterfacePtr                OpType = 364 +	OpStructFieldOmitEmptyInterfacePtr       OpType = 365 +	OpStructEndInterfacePtr                  OpType = 366 +	OpStructEndOmitEmptyInterfacePtr         OpType = 367 +	OpStructFieldIntPtrString                OpType = 368 +	OpStructFieldOmitEmptyIntPtrString       OpType = 369 +	OpStructEndIntPtrString                  OpType = 370 +	OpStructEndOmitEmptyIntPtrString         OpType = 371 +	OpStructFieldUintPtrString               OpType = 372 +	OpStructFieldOmitEmptyUintPtrString      OpType = 373 +	OpStructEndUintPtrString                 OpType = 374 +	OpStructEndOmitEmptyUintPtrString        OpType = 375 +	OpStructFieldFloat32PtrString            OpType = 376 +	OpStructFieldOmitEmptyFloat32PtrString   OpType = 377 +	OpStructEndFloat32PtrString              OpType = 378 +	OpStructEndOmitEmptyFloat32PtrString     OpType = 379 +	OpStructFieldFloat64PtrString            OpType = 380 +	OpStructFieldOmitEmptyFloat64PtrString   OpType = 381 +	OpStructEndFloat64PtrString              OpType = 382 +	OpStructEndOmitEmptyFloat64PtrString     OpType = 383 +	OpStructFieldBoolPtrString               OpType = 384 +	OpStructFieldOmitEmptyBoolPtrString      OpType = 385 +	OpStructEndBoolPtrString                 OpType = 386 +	OpStructEndOmitEmptyBoolPtrString        OpType = 387 +	OpStructFieldStringPtrString             OpType = 388 +	OpStructFieldOmitEmptyStringPtrString    OpType = 389 +	OpStructEndStringPtrString               OpType = 390 +	OpStructEndOmitEmptyStringPtrString      OpType = 391 +	OpStructFieldNumberPtrString             OpType = 392 +	OpStructFieldOmitEmptyNumberPtrString    OpType = 393 +	OpStructEndNumberPtrString               OpType = 394 +	OpStructEndOmitEmptyNumberPtrString      OpType = 395 +	OpStructField                            OpType = 396 +	OpStructFieldOmitEmpty                   OpType = 397 +	OpStructEnd                              OpType = 398 +	OpStructEndOmitEmpty                     OpType = 399 +) + +func (t OpType) String() string { +	if int(t) >= 400 { +		return "" +	} +	return opTypeStrings[int(t)] +} + +func (t OpType) CodeType() CodeType { +	if strings.Contains(t.String(), "Struct") { +		if strings.Contains(t.String(), "End") { +			return CodeStructEnd +		} +		return CodeStructField +	} +	switch t { +	case OpArray, OpArrayPtr: +		return CodeArrayHead +	case OpArrayElem: +		return CodeArrayElem +	case OpSlice, OpSlicePtr: +		return CodeSliceHead +	case OpSliceElem: +		return CodeSliceElem +	case OpMap, OpMapPtr: +		return CodeMapHead +	case OpMapKey: +		return CodeMapKey +	case OpMapValue: +		return CodeMapValue +	case OpMapEnd: +		return CodeMapEnd +	} + +	return CodeOp +} + +func (t OpType) HeadToPtrHead() OpType { +	if strings.Index(t.String(), "PtrHead") > 0 { +		return t +	} + +	idx := strings.Index(t.String(), "Head") +	if idx == -1 { +		return t +	} +	suffix := "PtrHead" + t.String()[idx+len("Head"):] + +	const toPtrOffset = 2 +	if strings.Contains(OpType(int(t)+toPtrOffset).String(), suffix) { +		return OpType(int(t) + toPtrOffset) +	} +	return t +} + +func (t OpType) HeadToOmitEmptyHead() OpType { +	const toOmitEmptyOffset = 1 +	if strings.Contains(OpType(int(t)+toOmitEmptyOffset).String(), "OmitEmpty") { +		return OpType(int(t) + toOmitEmptyOffset) +	} + +	return t +} + +func (t OpType) PtrHeadToHead() OpType { +	idx := strings.Index(t.String(), "PtrHead") +	if idx == -1 { +		return t +	} +	suffix := t.String()[idx+len("Ptr"):] + +	const toPtrOffset = 2 +	if strings.Contains(OpType(int(t)-toPtrOffset).String(), suffix) { +		return OpType(int(t) - toPtrOffset) +	} +	return t +} + +func (t OpType) FieldToEnd() OpType { +	idx := strings.Index(t.String(), "Field") +	if idx == -1 { +		return t +	} +	suffix := t.String()[idx+len("Field"):] +	if suffix == "" || suffix == "OmitEmpty" { +		return t +	} +	const toEndOffset = 2 +	if strings.Contains(OpType(int(t)+toEndOffset).String(), "End"+suffix) { +		return OpType(int(t) + toEndOffset) +	} +	return t +} + +func (t OpType) FieldToOmitEmptyField() OpType { +	const toOmitEmptyOffset = 1 +	if strings.Contains(OpType(int(t)+toOmitEmptyOffset).String(), "OmitEmpty") { +		return OpType(int(t) + toOmitEmptyOffset) +	} +	return t +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/query.go b/vendor/github.com/goccy/go-json/internal/encoder/query.go new file mode 100644 index 000000000..1e1850cc1 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/query.go @@ -0,0 +1,135 @@ +package encoder + +import ( +	"context" +	"fmt" +	"reflect" +) + +var ( +	Marshal   func(interface{}) ([]byte, error) +	Unmarshal func([]byte, interface{}) error +) + +type FieldQuery struct { +	Name   string +	Fields []*FieldQuery +	hash   string +} + +func (q *FieldQuery) Hash() string { +	if q.hash != "" { +		return q.hash +	} +	b, _ := Marshal(q) +	q.hash = string(b) +	return q.hash +} + +func (q *FieldQuery) MarshalJSON() ([]byte, error) { +	if q.Name != "" { +		if len(q.Fields) > 0 { +			return Marshal(map[string][]*FieldQuery{q.Name: q.Fields}) +		} +		return Marshal(q.Name) +	} +	return Marshal(q.Fields) +} + +func (q *FieldQuery) QueryString() (FieldQueryString, error) { +	b, err := Marshal(q) +	if err != nil { +		return "", err +	} +	return FieldQueryString(b), nil +} + +type FieldQueryString string + +func (s FieldQueryString) Build() (*FieldQuery, error) { +	var query interface{} +	if err := Unmarshal([]byte(s), &query); err != nil { +		return nil, err +	} +	return s.build(reflect.ValueOf(query)) +} + +func (s FieldQueryString) build(v reflect.Value) (*FieldQuery, error) { +	switch v.Type().Kind() { +	case reflect.String: +		return s.buildString(v) +	case reflect.Map: +		return s.buildMap(v) +	case reflect.Slice: +		return s.buildSlice(v) +	case reflect.Interface: +		return s.build(reflect.ValueOf(v.Interface())) +	} +	return nil, fmt.Errorf("failed to build field query") +} + +func (s FieldQueryString) buildString(v reflect.Value) (*FieldQuery, error) { +	b := []byte(v.String()) +	switch b[0] { +	case '[', '{': +		var query interface{} +		if err := Unmarshal(b, &query); err != nil { +			return nil, err +		} +		if str, ok := query.(string); ok { +			return &FieldQuery{Name: str}, nil +		} +		return s.build(reflect.ValueOf(query)) +	} +	return &FieldQuery{Name: string(b)}, nil +} + +func (s FieldQueryString) buildSlice(v reflect.Value) (*FieldQuery, error) { +	fields := make([]*FieldQuery, 0, v.Len()) +	for i := 0; i < v.Len(); i++ { +		def, err := s.build(v.Index(i)) +		if err != nil { +			return nil, err +		} +		fields = append(fields, def) +	} +	return &FieldQuery{Fields: fields}, nil +} + +func (s FieldQueryString) buildMap(v reflect.Value) (*FieldQuery, error) { +	keys := v.MapKeys() +	if len(keys) != 1 { +		return nil, fmt.Errorf("failed to build field query object") +	} +	key := keys[0] +	if key.Type().Kind() != reflect.String { +		return nil, fmt.Errorf("failed to build field query. invalid object key type") +	} +	name := key.String() +	def, err := s.build(v.MapIndex(key)) +	if err != nil { +		return nil, err +	} +	return &FieldQuery{ +		Name:   name, +		Fields: def.Fields, +	}, nil +} + +type queryKey struct{} + +func FieldQueryFromContext(ctx context.Context) *FieldQuery { +	query := ctx.Value(queryKey{}) +	if query == nil { +		return nil +	} +	q, ok := query.(*FieldQuery) +	if !ok { +		return nil +	} +	return q +} + +func SetFieldQueryToContext(ctx context.Context, query *FieldQuery) context.Context { +	return context.WithValue(ctx, queryKey{}, query) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/string.go b/vendor/github.com/goccy/go-json/internal/encoder/string.go new file mode 100644 index 000000000..e4152b27c --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/string.go @@ -0,0 +1,459 @@ +package encoder + +import ( +	"math/bits" +	"reflect" +	"unsafe" +) + +const ( +	lsb = 0x0101010101010101 +	msb = 0x8080808080808080 +) + +var hex = "0123456789abcdef" + +//nolint:govet +func stringToUint64Slice(s string) []uint64 { +	return *(*[]uint64)(unsafe.Pointer(&reflect.SliceHeader{ +		Data: ((*reflect.StringHeader)(unsafe.Pointer(&s))).Data, +		Len:  len(s) / 8, +		Cap:  len(s) / 8, +	})) +} + +func AppendString(ctx *RuntimeContext, buf []byte, s string) []byte { +	if ctx.Option.Flag&HTMLEscapeOption != 0 { +		if ctx.Option.Flag&NormalizeUTF8Option != 0 { +			return appendNormalizedHTMLString(buf, s) +		} +		return appendHTMLString(buf, s) +	} +	if ctx.Option.Flag&NormalizeUTF8Option != 0 { +		return appendNormalizedString(buf, s) +	} +	return appendString(buf, s) +} + +func appendNormalizedHTMLString(buf []byte, s string) []byte { +	valLen := len(s) +	if valLen == 0 { +		return append(buf, `""`...) +	} +	buf = append(buf, '"') +	var ( +		i, j int +	) +	if valLen >= 8 { +		chunks := stringToUint64Slice(s) +		for _, n := range chunks { +			// combine masks before checking for the MSB of each byte. We include +			// `n` in the mask to check whether any of the *input* byte MSBs were +			// set (i.e. the byte was outside the ASCII range). +			mask := n | (n - (lsb * 0x20)) | +				((n ^ (lsb * '"')) - lsb) | +				((n ^ (lsb * '\\')) - lsb) | +				((n ^ (lsb * '<')) - lsb) | +				((n ^ (lsb * '>')) - lsb) | +				((n ^ (lsb * '&')) - lsb) +			if (mask & msb) != 0 { +				j = bits.TrailingZeros64(mask&msb) / 8 +				goto ESCAPE_END +			} +		} +		for i := len(chunks) * 8; i < valLen; i++ { +			if needEscapeHTMLNormalizeUTF8[s[i]] { +				j = i +				goto ESCAPE_END +			} +		} +		// no found any escape characters. +		return append(append(buf, s...), '"') +	} +ESCAPE_END: +	for j < valLen { +		c := s[j] + +		if !needEscapeHTMLNormalizeUTF8[c] { +			// fast path: most of the time, printable ascii characters are used +			j++ +			continue +		} + +		switch c { +		case '\\', '"': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', c) +			i = j + 1 +			j = j + 1 +			continue + +		case '\n': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', 'n') +			i = j + 1 +			j = j + 1 +			continue + +		case '\r': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', 'r') +			i = j + 1 +			j = j + 1 +			continue + +		case '\t': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', 't') +			i = j + 1 +			j = j + 1 +			continue + +		case '<', '>', '&': +			buf = append(buf, s[i:j]...) +			buf = append(buf, `\u00`...) +			buf = append(buf, hex[c>>4], hex[c&0xF]) +			i = j + 1 +			j = j + 1 +			continue + +		case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, // 0x00-0x0F +			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F: // 0x10-0x1F +			buf = append(buf, s[i:j]...) +			buf = append(buf, `\u00`...) +			buf = append(buf, hex[c>>4], hex[c&0xF]) +			i = j + 1 +			j = j + 1 +			continue +		} +		state, size := decodeRuneInString(s[j:]) +		switch state { +		case runeErrorState: +			buf = append(buf, s[i:j]...) +			buf = append(buf, `\ufffd`...) +			i = j + 1 +			j = j + 1 +			continue +			// U+2028 is LINE SEPARATOR. +			// U+2029 is PARAGRAPH SEPARATOR. +			// They are both technically valid characters in JSON strings, +			// but don't work in JSONP, which has to be evaluated as JavaScript, +			// and can lead to security holes there. It is valid JSON to +			// escape them, so we do so unconditionally. +			// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. +		case lineSepState: +			buf = append(buf, s[i:j]...) +			buf = append(buf, `\u2028`...) +			i = j + 3 +			j = j + 3 +			continue +		case paragraphSepState: +			buf = append(buf, s[i:j]...) +			buf = append(buf, `\u2029`...) +			i = j + 3 +			j = j + 3 +			continue +		} +		j += size +	} + +	return append(append(buf, s[i:]...), '"') +} + +func appendHTMLString(buf []byte, s string) []byte { +	valLen := len(s) +	if valLen == 0 { +		return append(buf, `""`...) +	} +	buf = append(buf, '"') +	var ( +		i, j int +	) +	if valLen >= 8 { +		chunks := stringToUint64Slice(s) +		for _, n := range chunks { +			// combine masks before checking for the MSB of each byte. We include +			// `n` in the mask to check whether any of the *input* byte MSBs were +			// set (i.e. the byte was outside the ASCII range). +			mask := n | (n - (lsb * 0x20)) | +				((n ^ (lsb * '"')) - lsb) | +				((n ^ (lsb * '\\')) - lsb) | +				((n ^ (lsb * '<')) - lsb) | +				((n ^ (lsb * '>')) - lsb) | +				((n ^ (lsb * '&')) - lsb) +			if (mask & msb) != 0 { +				j = bits.TrailingZeros64(mask&msb) / 8 +				goto ESCAPE_END +			} +		} +		for i := len(chunks) * 8; i < valLen; i++ { +			if needEscapeHTML[s[i]] { +				j = i +				goto ESCAPE_END +			} +		} +		// no found any escape characters. +		return append(append(buf, s...), '"') +	} +ESCAPE_END: +	for j < valLen { +		c := s[j] + +		if !needEscapeHTML[c] { +			// fast path: most of the time, printable ascii characters are used +			j++ +			continue +		} + +		switch c { +		case '\\', '"': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', c) +			i = j + 1 +			j = j + 1 +			continue + +		case '\n': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', 'n') +			i = j + 1 +			j = j + 1 +			continue + +		case '\r': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', 'r') +			i = j + 1 +			j = j + 1 +			continue + +		case '\t': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', 't') +			i = j + 1 +			j = j + 1 +			continue + +		case '<', '>', '&': +			buf = append(buf, s[i:j]...) +			buf = append(buf, `\u00`...) +			buf = append(buf, hex[c>>4], hex[c&0xF]) +			i = j + 1 +			j = j + 1 +			continue + +		case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, // 0x00-0x0F +			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F: // 0x10-0x1F +			buf = append(buf, s[i:j]...) +			buf = append(buf, `\u00`...) +			buf = append(buf, hex[c>>4], hex[c&0xF]) +			i = j + 1 +			j = j + 1 +			continue +		} +		j++ +	} + +	return append(append(buf, s[i:]...), '"') +} + +func appendNormalizedString(buf []byte, s string) []byte { +	valLen := len(s) +	if valLen == 0 { +		return append(buf, `""`...) +	} +	buf = append(buf, '"') +	var ( +		i, j int +	) +	if valLen >= 8 { +		chunks := stringToUint64Slice(s) +		for _, n := range chunks { +			// combine masks before checking for the MSB of each byte. We include +			// `n` in the mask to check whether any of the *input* byte MSBs were +			// set (i.e. the byte was outside the ASCII range). +			mask := n | (n - (lsb * 0x20)) | +				((n ^ (lsb * '"')) - lsb) | +				((n ^ (lsb * '\\')) - lsb) +			if (mask & msb) != 0 { +				j = bits.TrailingZeros64(mask&msb) / 8 +				goto ESCAPE_END +			} +		} +		valLen := len(s) +		for i := len(chunks) * 8; i < valLen; i++ { +			if needEscapeNormalizeUTF8[s[i]] { +				j = i +				goto ESCAPE_END +			} +		} +		return append(append(buf, s...), '"') +	} +ESCAPE_END: +	for j < valLen { +		c := s[j] + +		if !needEscapeNormalizeUTF8[c] { +			// fast path: most of the time, printable ascii characters are used +			j++ +			continue +		} + +		switch c { +		case '\\', '"': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', c) +			i = j + 1 +			j = j + 1 +			continue + +		case '\n': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', 'n') +			i = j + 1 +			j = j + 1 +			continue + +		case '\r': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', 'r') +			i = j + 1 +			j = j + 1 +			continue + +		case '\t': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', 't') +			i = j + 1 +			j = j + 1 +			continue + +		case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, // 0x00-0x0F +			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F: // 0x10-0x1F +			buf = append(buf, s[i:j]...) +			buf = append(buf, `\u00`...) +			buf = append(buf, hex[c>>4], hex[c&0xF]) +			i = j + 1 +			j = j + 1 +			continue +		} + +		state, size := decodeRuneInString(s[j:]) +		switch state { +		case runeErrorState: +			buf = append(buf, s[i:j]...) +			buf = append(buf, `\ufffd`...) +			i = j + 1 +			j = j + 1 +			continue +			// U+2028 is LINE SEPARATOR. +			// U+2029 is PARAGRAPH SEPARATOR. +			// They are both technically valid characters in JSON strings, +			// but don't work in JSONP, which has to be evaluated as JavaScript, +			// and can lead to security holes there. It is valid JSON to +			// escape them, so we do so unconditionally. +			// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. +		case lineSepState: +			buf = append(buf, s[i:j]...) +			buf = append(buf, `\u2028`...) +			i = j + 3 +			j = j + 3 +			continue +		case paragraphSepState: +			buf = append(buf, s[i:j]...) +			buf = append(buf, `\u2029`...) +			i = j + 3 +			j = j + 3 +			continue +		} +		j += size +	} + +	return append(append(buf, s[i:]...), '"') +} + +func appendString(buf []byte, s string) []byte { +	valLen := len(s) +	if valLen == 0 { +		return append(buf, `""`...) +	} +	buf = append(buf, '"') +	var ( +		i, j int +	) +	if valLen >= 8 { +		chunks := stringToUint64Slice(s) +		for _, n := range chunks { +			// combine masks before checking for the MSB of each byte. We include +			// `n` in the mask to check whether any of the *input* byte MSBs were +			// set (i.e. the byte was outside the ASCII range). +			mask := n | (n - (lsb * 0x20)) | +				((n ^ (lsb * '"')) - lsb) | +				((n ^ (lsb * '\\')) - lsb) +			if (mask & msb) != 0 { +				j = bits.TrailingZeros64(mask&msb) / 8 +				goto ESCAPE_END +			} +		} +		valLen := len(s) +		for i := len(chunks) * 8; i < valLen; i++ { +			if needEscape[s[i]] { +				j = i +				goto ESCAPE_END +			} +		} +		return append(append(buf, s...), '"') +	} +ESCAPE_END: +	for j < valLen { +		c := s[j] + +		if !needEscape[c] { +			// fast path: most of the time, printable ascii characters are used +			j++ +			continue +		} + +		switch c { +		case '\\', '"': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', c) +			i = j + 1 +			j = j + 1 +			continue + +		case '\n': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', 'n') +			i = j + 1 +			j = j + 1 +			continue + +		case '\r': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', 'r') +			i = j + 1 +			j = j + 1 +			continue + +		case '\t': +			buf = append(buf, s[i:j]...) +			buf = append(buf, '\\', 't') +			i = j + 1 +			j = j + 1 +			continue + +		case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, // 0x00-0x0F +			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F: // 0x10-0x1F +			buf = append(buf, s[i:j]...) +			buf = append(buf, `\u00`...) +			buf = append(buf, hex[c>>4], hex[c&0xF]) +			i = j + 1 +			j = j + 1 +			continue +		} +		j++ +	} + +	return append(append(buf, s[i:]...), '"') +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/string_table.go b/vendor/github.com/goccy/go-json/internal/encoder/string_table.go new file mode 100644 index 000000000..ebe42c92d --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/string_table.go @@ -0,0 +1,415 @@ +package encoder + +var needEscapeHTMLNormalizeUTF8 = [256]bool{ +	'"':  true, +	'&':  true, +	'<':  true, +	'>':  true, +	'\\': true, +	0x00: true, +	0x01: true, +	0x02: true, +	0x03: true, +	0x04: true, +	0x05: true, +	0x06: true, +	0x07: true, +	0x08: true, +	0x09: true, +	0x0a: true, +	0x0b: true, +	0x0c: true, +	0x0d: true, +	0x0e: true, +	0x0f: true, +	0x10: true, +	0x11: true, +	0x12: true, +	0x13: true, +	0x14: true, +	0x15: true, +	0x16: true, +	0x17: true, +	0x18: true, +	0x19: true, +	0x1a: true, +	0x1b: true, +	0x1c: true, +	0x1d: true, +	0x1e: true, +	0x1f: true, +	/* 0x20 - 0x7f */ +	0x80: true, +	0x81: true, +	0x82: true, +	0x83: true, +	0x84: true, +	0x85: true, +	0x86: true, +	0x87: true, +	0x88: true, +	0x89: true, +	0x8a: true, +	0x8b: true, +	0x8c: true, +	0x8d: true, +	0x8e: true, +	0x8f: true, +	0x90: true, +	0x91: true, +	0x92: true, +	0x93: true, +	0x94: true, +	0x95: true, +	0x96: true, +	0x97: true, +	0x98: true, +	0x99: true, +	0x9a: true, +	0x9b: true, +	0x9c: true, +	0x9d: true, +	0x9e: true, +	0x9f: true, +	0xa0: true, +	0xa1: true, +	0xa2: true, +	0xa3: true, +	0xa4: true, +	0xa5: true, +	0xa6: true, +	0xa7: true, +	0xa8: true, +	0xa9: true, +	0xaa: true, +	0xab: true, +	0xac: true, +	0xad: true, +	0xae: true, +	0xaf: true, +	0xb0: true, +	0xb1: true, +	0xb2: true, +	0xb3: true, +	0xb4: true, +	0xb5: true, +	0xb6: true, +	0xb7: true, +	0xb8: true, +	0xb9: true, +	0xba: true, +	0xbb: true, +	0xbc: true, +	0xbd: true, +	0xbe: true, +	0xbf: true, +	0xc0: true, +	0xc1: true, +	0xc2: true, +	0xc3: true, +	0xc4: true, +	0xc5: true, +	0xc6: true, +	0xc7: true, +	0xc8: true, +	0xc9: true, +	0xca: true, +	0xcb: true, +	0xcc: true, +	0xcd: true, +	0xce: true, +	0xcf: true, +	0xd0: true, +	0xd1: true, +	0xd2: true, +	0xd3: true, +	0xd4: true, +	0xd5: true, +	0xd6: true, +	0xd7: true, +	0xd8: true, +	0xd9: true, +	0xda: true, +	0xdb: true, +	0xdc: true, +	0xdd: true, +	0xde: true, +	0xdf: true, +	0xe0: true, +	0xe1: true, +	0xe2: true, +	0xe3: true, +	0xe4: true, +	0xe5: true, +	0xe6: true, +	0xe7: true, +	0xe8: true, +	0xe9: true, +	0xea: true, +	0xeb: true, +	0xec: true, +	0xed: true, +	0xee: true, +	0xef: true, +	0xf0: true, +	0xf1: true, +	0xf2: true, +	0xf3: true, +	0xf4: true, +	0xf5: true, +	0xf6: true, +	0xf7: true, +	0xf8: true, +	0xf9: true, +	0xfa: true, +	0xfb: true, +	0xfc: true, +	0xfd: true, +	0xfe: true, +	0xff: true, +} + +var needEscapeNormalizeUTF8 = [256]bool{ +	'"':  true, +	'\\': true, +	0x00: true, +	0x01: true, +	0x02: true, +	0x03: true, +	0x04: true, +	0x05: true, +	0x06: true, +	0x07: true, +	0x08: true, +	0x09: true, +	0x0a: true, +	0x0b: true, +	0x0c: true, +	0x0d: true, +	0x0e: true, +	0x0f: true, +	0x10: true, +	0x11: true, +	0x12: true, +	0x13: true, +	0x14: true, +	0x15: true, +	0x16: true, +	0x17: true, +	0x18: true, +	0x19: true, +	0x1a: true, +	0x1b: true, +	0x1c: true, +	0x1d: true, +	0x1e: true, +	0x1f: true, +	/* 0x20 - 0x7f */ +	0x80: true, +	0x81: true, +	0x82: true, +	0x83: true, +	0x84: true, +	0x85: true, +	0x86: true, +	0x87: true, +	0x88: true, +	0x89: true, +	0x8a: true, +	0x8b: true, +	0x8c: true, +	0x8d: true, +	0x8e: true, +	0x8f: true, +	0x90: true, +	0x91: true, +	0x92: true, +	0x93: true, +	0x94: true, +	0x95: true, +	0x96: true, +	0x97: true, +	0x98: true, +	0x99: true, +	0x9a: true, +	0x9b: true, +	0x9c: true, +	0x9d: true, +	0x9e: true, +	0x9f: true, +	0xa0: true, +	0xa1: true, +	0xa2: true, +	0xa3: true, +	0xa4: true, +	0xa5: true, +	0xa6: true, +	0xa7: true, +	0xa8: true, +	0xa9: true, +	0xaa: true, +	0xab: true, +	0xac: true, +	0xad: true, +	0xae: true, +	0xaf: true, +	0xb0: true, +	0xb1: true, +	0xb2: true, +	0xb3: true, +	0xb4: true, +	0xb5: true, +	0xb6: true, +	0xb7: true, +	0xb8: true, +	0xb9: true, +	0xba: true, +	0xbb: true, +	0xbc: true, +	0xbd: true, +	0xbe: true, +	0xbf: true, +	0xc0: true, +	0xc1: true, +	0xc2: true, +	0xc3: true, +	0xc4: true, +	0xc5: true, +	0xc6: true, +	0xc7: true, +	0xc8: true, +	0xc9: true, +	0xca: true, +	0xcb: true, +	0xcc: true, +	0xcd: true, +	0xce: true, +	0xcf: true, +	0xd0: true, +	0xd1: true, +	0xd2: true, +	0xd3: true, +	0xd4: true, +	0xd5: true, +	0xd6: true, +	0xd7: true, +	0xd8: true, +	0xd9: true, +	0xda: true, +	0xdb: true, +	0xdc: true, +	0xdd: true, +	0xde: true, +	0xdf: true, +	0xe0: true, +	0xe1: true, +	0xe2: true, +	0xe3: true, +	0xe4: true, +	0xe5: true, +	0xe6: true, +	0xe7: true, +	0xe8: true, +	0xe9: true, +	0xea: true, +	0xeb: true, +	0xec: true, +	0xed: true, +	0xee: true, +	0xef: true, +	0xf0: true, +	0xf1: true, +	0xf2: true, +	0xf3: true, +	0xf4: true, +	0xf5: true, +	0xf6: true, +	0xf7: true, +	0xf8: true, +	0xf9: true, +	0xfa: true, +	0xfb: true, +	0xfc: true, +	0xfd: true, +	0xfe: true, +	0xff: true, +} + +var needEscapeHTML = [256]bool{ +	'"':  true, +	'&':  true, +	'<':  true, +	'>':  true, +	'\\': true, +	0x00: true, +	0x01: true, +	0x02: true, +	0x03: true, +	0x04: true, +	0x05: true, +	0x06: true, +	0x07: true, +	0x08: true, +	0x09: true, +	0x0a: true, +	0x0b: true, +	0x0c: true, +	0x0d: true, +	0x0e: true, +	0x0f: true, +	0x10: true, +	0x11: true, +	0x12: true, +	0x13: true, +	0x14: true, +	0x15: true, +	0x16: true, +	0x17: true, +	0x18: true, +	0x19: true, +	0x1a: true, +	0x1b: true, +	0x1c: true, +	0x1d: true, +	0x1e: true, +	0x1f: true, +	/* 0x20 - 0xff */ +} + +var needEscape = [256]bool{ +	'"':  true, +	'\\': true, +	0x00: true, +	0x01: true, +	0x02: true, +	0x03: true, +	0x04: true, +	0x05: true, +	0x06: true, +	0x07: true, +	0x08: true, +	0x09: true, +	0x0a: true, +	0x0b: true, +	0x0c: true, +	0x0d: true, +	0x0e: true, +	0x0f: true, +	0x10: true, +	0x11: true, +	0x12: true, +	0x13: true, +	0x14: true, +	0x15: true, +	0x16: true, +	0x17: true, +	0x18: true, +	0x19: true, +	0x1a: true, +	0x1b: true, +	0x1c: true, +	0x1d: true, +	0x1e: true, +	0x1f: true, +	/* 0x20 - 0xff */ +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go new file mode 100644 index 000000000..fbbc0de44 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go @@ -0,0 +1,35 @@ +package vm + +import ( +	"fmt" + +	"github.com/goccy/go-json/internal/encoder" +) + +func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { +	defer func() { +		var code *encoder.Opcode +		if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { +			code = codeSet.EscapeKeyCode +		} else { +			code = codeSet.NoescapeKeyCode +		} + +		if err := recover(); err != nil { +			w := ctx.Option.DebugOut +			fmt.Fprintln(w, "=============[DEBUG]===============") +			fmt.Fprintln(w, "* [TYPE]") +			fmt.Fprintln(w, codeSet.Type) +			fmt.Fprintf(w, "\n") +			fmt.Fprintln(w, "* [ALL OPCODE]") +			fmt.Fprintln(w, code.Dump()) +			fmt.Fprintf(w, "\n") +			fmt.Fprintln(w, "* [CONTEXT]") +			fmt.Fprintf(w, "%+v\n", ctx) +			fmt.Fprintln(w, "===================================") +			panic(err) +		} +	}() + +	return Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go new file mode 100644 index 000000000..65252b4a5 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go @@ -0,0 +1,9 @@ +package vm + +import ( +	// HACK: compile order +	// `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile, +	// so forcibly make dependencies and avoid compiling in concurrent. +	// dependency order: vm => vm_indent => vm_color => vm_color_indent +	_ "github.com/goccy/go-json/internal/encoder/vm_indent" +) diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/util.go new file mode 100644 index 000000000..86291d7bb --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/util.go @@ -0,0 +1,207 @@ +package vm + +import ( +	"encoding/json" +	"fmt" +	"unsafe" + +	"github.com/goccy/go-json/internal/encoder" +	"github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +var ( +	appendInt           = encoder.AppendInt +	appendUint          = encoder.AppendUint +	appendFloat32       = encoder.AppendFloat32 +	appendFloat64       = encoder.AppendFloat64 +	appendString        = encoder.AppendString +	appendByteSlice     = encoder.AppendByteSlice +	appendNumber        = encoder.AppendNumber +	errUnsupportedValue = encoder.ErrUnsupportedValue +	errUnsupportedFloat = encoder.ErrUnsupportedFloat +	mapiterinit         = encoder.MapIterInit +	mapiterkey          = encoder.MapIterKey +	mapitervalue        = encoder.MapIterValue +	mapiternext         = encoder.MapIterNext +	maplen              = encoder.MapLen +) + +type emptyInterface struct { +	typ *runtime.Type +	ptr unsafe.Pointer +} + +type nonEmptyInterface struct { +	itab *struct { +		ityp *runtime.Type // static interface type +		typ  *runtime.Type // dynamic concrete type +		// unused fields... +	} +	ptr unsafe.Pointer +} + +func errUnimplementedOp(op encoder.OpType) error { +	return fmt.Errorf("encoder: opcode %s has not been implemented", op) +} + +func load(base uintptr, idx uint32) uintptr { +	addr := base + uintptr(idx) +	return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uint32, p uintptr) { +	addr := base + uintptr(idx) +	**(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr { +	addr := base + uintptr(idx) +	p := **(**uintptr)(unsafe.Pointer(&addr)) +	for i := uint8(0); i < ptrNum; i++ { +		if p == 0 { +			return 0 +		} +		p = ptrToPtr(p) +	} +	return p +} + +func ptrToUint64(p uintptr, bitSize uint8) uint64 { +	switch bitSize { +	case 8: +		return (uint64)(**(**uint8)(unsafe.Pointer(&p))) +	case 16: +		return (uint64)(**(**uint16)(unsafe.Pointer(&p))) +	case 32: +		return (uint64)(**(**uint32)(unsafe.Pointer(&p))) +	case 64: +		return **(**uint64)(unsafe.Pointer(&p)) +	} +	return 0 +} +func ptrToFloat32(p uintptr) float32            { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64            { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool                  { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte               { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number         { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string              { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { +	return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum uint8) uintptr { +	for i := uint8(0); i < ptrNum; i++ { +		if p == 0 { +			return 0 +		} +		p = ptrToPtr(p) +	} +	return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { +	return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { +	return *(*interface{})(unsafe.Pointer(&emptyInterface{ +		typ: code.Type, +		ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), +	})) +} + +func appendBool(_ *encoder.RuntimeContext, b []byte, v bool) []byte { +	if v { +		return append(b, "true"...) +	} +	return append(b, "false"...) +} + +func appendNull(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, "null"...) +} + +func appendComma(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, ',') +} + +func appendNullComma(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, "null,"...) +} + +func appendColon(_ *encoder.RuntimeContext, b []byte) []byte { +	last := len(b) - 1 +	b[last] = ':' +	return b +} + +func appendMapKeyValue(_ *encoder.RuntimeContext, _ *encoder.Opcode, b, key, value []byte) []byte { +	b = append(b, key...) +	b[len(b)-1] = ':' +	return append(b, value...) +} + +func appendMapEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { +	b[len(b)-1] = '}' +	b = append(b, ',') +	return b +} + +func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { +	return encoder.AppendMarshalJSON(ctx, code, b, v) +} + +func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { +	return encoder.AppendMarshalText(ctx, code, b, v) +} + +func appendArrayHead(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { +	return append(b, '[') +} + +func appendArrayEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { +	last := len(b) - 1 +	b[last] = ']' +	return append(b, ',') +} + +func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, '[', ']', ',') +} + +func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, '{', '}', ',') +} + +func appendObjectEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { +	last := len(b) - 1 +	b[last] = '}' +	return append(b, ',') +} + +func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, '{') +} + +func appendStructKey(_ *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	return append(b, code.Key...) +} + +func appendStructEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { +	return append(b, '}', ',') +} + +func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	last := len(b) - 1 +	if b[last] == ',' { +		b[last] = '}' +		return appendComma(ctx, b) +	} +	return appendStructEnd(ctx, code, b) +} + +func restoreIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, _ uintptr)               {} +func storeIndent(_ uintptr, _ *encoder.Opcode, _ uintptr)                                 {} +func appendMapKeyIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte    { return b } +func appendArrayElemIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b } diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go new file mode 100644 index 000000000..645d20f9f --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go @@ -0,0 +1,4859 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package vm + +import ( +	"math" +	"reflect" +	"sort" +	"unsafe" + +	"github.com/goccy/go-json/internal/encoder" +	"github.com/goccy/go-json/internal/runtime" +) + +func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { +	recursiveLevel := 0 +	ptrOffset := uintptr(0) +	ctxptr := ctx.Ptr() +	var code *encoder.Opcode +	if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { +		code = codeSet.EscapeKeyCode +	} else { +		code = codeSet.NoescapeKeyCode +	} + +	for { +		switch code.Op { +		default: +			return nil, errUnimplementedOp(code.Op) +		case encoder.OpPtr: +			p := load(ctxptr, code.Idx) +			code = code.Next +			store(ctxptr, code.Idx, ptrToPtr(p)) +		case encoder.OpIntPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpInt: +			b = appendInt(ctx, b, load(ctxptr, code.Idx), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpUintPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpUint: +			b = appendUint(ctx, b, load(ctxptr, code.Idx), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpIntString: +			b = append(b, '"') +			b = appendInt(ctx, b, load(ctxptr, code.Idx), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpUintString: +			b = append(b, '"') +			b = appendUint(ctx, b, load(ctxptr, code.Idx), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpFloat32Ptr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +				b = appendComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpFloat32: +			b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpFloat64Ptr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpFloat64: +			v := ptrToFloat64(load(ctxptr, code.Idx)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStringPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpString: +			b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpBoolPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpBool: +			b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpBytesPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpBytes: +			b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpNumberPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpNumber: +			bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx))) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpInterfacePtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpInterface: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			if recursiveLevel > encoder.StartDetectingCyclesAfter { +				for _, seen := range ctx.SeenPtr { +					if p == seen { +						return nil, errUnsupportedValue(code, p) +					} +				} +			} +			ctx.SeenPtr = append(ctx.SeenPtr, p) +			var ( +				typ      *runtime.Type +				ifacePtr unsafe.Pointer +			) +			up := ptrToUnsafePtr(p) +			if code.Flags&encoder.NonEmptyInterfaceFlags != 0 { +				iface := (*nonEmptyInterface)(up) +				ifacePtr = iface.ptr +				if iface.itab != nil { +					typ = iface.itab.typ +				} +			} else { +				iface := (*emptyInterface)(up) +				ifacePtr = iface.ptr +				typ = iface.typ +			} +			if ifacePtr == nil { +				isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ) +				if !isDirectedNil { +					b = appendNullComma(ctx, b) +					code = code.Next +					break +				} +			} +			ctx.KeepRefs = append(ctx.KeepRefs, up) +			ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ))) +			if err != nil { +				return nil, err +			} + +			totalLength := uintptr(code.Length) + 3 +			nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3 + +			var c *encoder.Opcode +			if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { +				c = ifaceCodeSet.InterfaceEscapeKeyCode +			} else { +				c = ifaceCodeSet.InterfaceNoescapeKeyCode +			} +			curlen := uintptr(len(ctx.Ptrs)) +			offsetNum := ptrOffset / uintptrSize +			oldOffset := ptrOffset +			ptrOffset += totalLength * uintptrSize +			oldBaseIndent := ctx.BaseIndent +			ctx.BaseIndent += code.Indent + +			newLen := offsetNum + totalLength + nextTotalLength +			if curlen < newLen { +				ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) +			} +			ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + +			end := ifaceCodeSet.EndCode +			store(ctxptr, c.Idx, uintptr(ifacePtr)) +			store(ctxptr, end.Idx, oldOffset) +			store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next))) +			storeIndent(ctxptr, end, uintptr(oldBaseIndent)) +			code = c +			recursiveLevel++ +		case encoder.OpInterfaceEnd: +			recursiveLevel-- + +			// restore ctxptr +			offset := load(ctxptr, code.Idx) +			restoreIndent(ctx, code, ctxptr) +			ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + +			codePtr := load(ctxptr, code.ElemIdx) +			code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) +			ctxptr = ctx.Ptr() + offset +			ptrOffset = offset +		case encoder.OpMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, ptrToPtr(p)) +			fallthrough +		case encoder.OpMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p) +			} +			bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, ptrToPtr(p)) +			fallthrough +		case encoder.OpMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = append(b, `""`...) +				b = appendComma(ctx, b) +				code = code.Next +				break +			} +			if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p) +			} +			bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpSlicePtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpSlice: +			p := load(ctxptr, code.Idx) +			slice := ptrToSlice(p) +			if p == 0 || slice.Data == nil { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.ElemIdx, 0) +			store(ctxptr, code.Length, uintptr(slice.Len)) +			store(ctxptr, code.Idx, uintptr(slice.Data)) +			if slice.Len > 0 { +				b = appendArrayHead(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, uintptr(slice.Data)) +			} else { +				b = appendEmptyArray(ctx, b) +				code = code.End.Next +			} +		case encoder.OpSliceElem: +			idx := load(ctxptr, code.ElemIdx) +			length := load(ctxptr, code.Length) +			idx++ +			if idx < length { +				b = appendArrayElemIndent(ctx, code, b) +				store(ctxptr, code.ElemIdx, idx) +				data := load(ctxptr, code.Idx) +				size := uintptr(code.Size) +				code = code.Next +				store(ctxptr, code.Idx, data+idx*size) +			} else { +				b = appendArrayEnd(ctx, code, b) +				code = code.End.Next +			} +		case encoder.OpArrayPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpArray: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			if code.Length > 0 { +				b = appendArrayHead(ctx, code, b) +				store(ctxptr, code.ElemIdx, 0) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				b = appendEmptyArray(ctx, b) +				code = code.End.Next +			} +		case encoder.OpArrayElem: +			idx := load(ctxptr, code.ElemIdx) +			idx++ +			if idx < uintptr(code.Length) { +				b = appendArrayElemIndent(ctx, code, b) +				store(ctxptr, code.ElemIdx, idx) +				p := load(ctxptr, code.Idx) +				size := uintptr(code.Size) +				code = code.Next +				store(ctxptr, code.Idx, p+idx*size) +			} else { +				b = appendArrayEnd(ctx, code, b) +				code = code.End.Next +			} +		case encoder.OpMapPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpMap: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			uptr := ptrToUnsafePtr(p) +			mlen := maplen(uptr) +			if mlen <= 0 { +				b = appendEmptyObject(ctx, b) +				code = code.End.Next +				break +			} +			b = appendStructHead(ctx, b) +			unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 +			mapCtx := encoder.NewMapContext(mlen, unorderedMap) +			mapiterinit(code.Type, uptr, &mapCtx.Iter) +			store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx))) +			ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) +			if unorderedMap { +				b = appendMapKeyIndent(ctx, code.Next, b) +			} else { +				mapCtx.Start = len(b) +				mapCtx.First = len(b) +			} +			key := mapiterkey(&mapCtx.Iter) +			store(ctxptr, code.Next.Idx, uintptr(key)) +			code = code.Next +		case encoder.OpMapKey: +			mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) +			idx := mapCtx.Idx +			idx++ +			if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { +				if idx < mapCtx.Len { +					b = appendMapKeyIndent(ctx, code, b) +					mapCtx.Idx = int(idx) +					key := mapiterkey(&mapCtx.Iter) +					store(ctxptr, code.Next.Idx, uintptr(key)) +					code = code.Next +				} else { +					b = appendObjectEnd(ctx, code, b) +					encoder.ReleaseMapContext(mapCtx) +					code = code.End.Next +				} +			} else { +				mapCtx.Slice.Items[mapCtx.Idx].Value = b[mapCtx.Start:len(b)] +				if idx < mapCtx.Len { +					mapCtx.Idx = int(idx) +					mapCtx.Start = len(b) +					key := mapiterkey(&mapCtx.Iter) +					store(ctxptr, code.Next.Idx, uintptr(key)) +					code = code.Next +				} else { +					code = code.End +				} +			} +		case encoder.OpMapValue: +			mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) +			if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { +				b = appendColon(ctx, b) +			} else { +				mapCtx.Slice.Items[mapCtx.Idx].Key = b[mapCtx.Start:len(b)] +				mapCtx.Start = len(b) +			} +			value := mapitervalue(&mapCtx.Iter) +			store(ctxptr, code.Next.Idx, uintptr(value)) +			mapiternext(&mapCtx.Iter) +			code = code.Next +		case encoder.OpMapEnd: +			// this operation only used by sorted map. +			mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) +			sort.Sort(mapCtx.Slice) +			buf := mapCtx.Buf +			for _, item := range mapCtx.Slice.Items { +				buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value) +			} +			buf = appendMapEnd(ctx, code, buf) +			b = b[:mapCtx.First] +			b = append(b, buf...) +			mapCtx.Buf = buf +			encoder.ReleaseMapContext(mapCtx) +			code = code.Next +		case encoder.OpRecursivePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpRecursive: +			ptr := load(ctxptr, code.Idx) +			if ptr != 0 { +				if recursiveLevel > encoder.StartDetectingCyclesAfter { +					for _, seen := range ctx.SeenPtr { +						if ptr == seen { +							return nil, errUnsupportedValue(code, ptr) +						} +					} +				} +			} +			ctx.SeenPtr = append(ctx.SeenPtr, ptr) +			c := code.Jmp.Code +			curlen := uintptr(len(ctx.Ptrs)) +			offsetNum := ptrOffset / uintptrSize +			oldOffset := ptrOffset +			ptrOffset += code.Jmp.CurLen * uintptrSize +			oldBaseIndent := ctx.BaseIndent +			indentDiffFromTop := c.Indent - 1 +			ctx.BaseIndent += code.Indent - indentDiffFromTop + +			newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen +			if curlen < newLen { +				ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) +			} +			ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + +			store(ctxptr, c.Idx, ptr) +			store(ctxptr, c.End.Next.Idx, oldOffset) +			store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) +			storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent)) +			code = c +			recursiveLevel++ +		case encoder.OpRecursiveEnd: +			recursiveLevel-- + +			// restore ctxptr +			restoreIndent(ctx, code, ctxptr) +			offset := load(ctxptr, code.Idx) +			ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + +			codePtr := load(ctxptr, code.ElemIdx) +			code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) +			ctxptr = ctx.Ptr() + offset +			ptrOffset = offset +		case encoder.OpStructPtrHead: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHead: +			p := load(ctxptr, code.Idx) +			if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if len(code.Key) > 0 { +				if (code.Flags&encoder.IsTaggedKeyFlags) != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { +					b = appendStructKey(ctx, code, b) +				} +			} +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmpty: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmpty: +			p := load(ctxptr, code.Idx) +			if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadInt: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadInt: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyInt: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyInt: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadIntString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadIntString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyIntString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyIntString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			u64 := ptrToUint64(p, code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendInt(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadUint: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadUint: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUint: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyUint: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadUintString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadUintString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUintString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyUintString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendUint(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat32: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat32: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat32String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat32String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat64: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat64: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat64String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat64String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat64(ctx, b, v) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNull(ctx, b) +					b = appendComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToString(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadStringString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadStringString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset))))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyStringString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyStringString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToString(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, ptrToString(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, ptrToString(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadBool: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadBool: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBool: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyBool: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} else { +				code = code.NextField +			} +		case encoder.OpStructPtrHeadBoolString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadBoolString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBoolString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyBoolString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} else { +				code = code.NextField +			} +		case encoder.OpStructPtrHeadBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendBool(ctx, b, ptrToBool(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, ptrToBool(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadBytes: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadBytes: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBytes: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyBytes: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToBytes(p + uintptr(code.Offset)) +			if len(v) == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadNumber: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadNumber: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumber: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumber: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +				code = code.Next +			} +		case encoder.OpStructPtrHeadNumberString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadNumberString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = append(bb, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumberString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumberString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructPtrHeadNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadArray, encoder.OpStructHeadSlice: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmptyArray: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyArray: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			b = appendStructKey(ctx, code, b) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmptySlice: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptySlice: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			slice := ptrToSlice(p) +			if slice.Len == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.NextField +			} else { +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadMap: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMap: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p + uintptr(code.Offset)) +			} +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmptyMap: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMap: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p + uintptr(code.Offset)) +			} +			if maplen(ptrToUnsafePtr(p)) == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.NextField +				break +			} +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.NextField +			} else { +				if (code.Flags & encoder.IndirectFlags) != 0 { +					p = ptrToNPtr(p, code.PtrNum) +				} +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadOmitEmptyMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p == 0 { +				code = code.NextField +				break +			} +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p == 0 { +				code = code.NextField +			} else { +				if (code.Flags & encoder.IndirectFlags) != 0 { +					p = ptrToNPtr(p, code.PtrNum) +				} +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { +					p = ptrToPtr(p) +				} +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { +					p = ptrToPtr(p) +				} +			} +			iface := ptrToInterface(code, p) +			if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalJSON(ctx, code, b, iface) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { +					p = ptrToPtr(p) +				} +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { +					p = ptrToPtr(p) +				} +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructField: +			if code.Flags&encoder.IsTaggedKeyFlags != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { +				b = appendStructKey(ctx, code, b) +			} +			p := load(ctxptr, code.Idx) + uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmpty: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructFieldInt: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyInt: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldIntString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyIntString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldIntPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendInt(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldIntPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUint: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUint: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUintString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUintString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUintPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendUint(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUintPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32String: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat64(ctx, b, v) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			v := ptrToFloat64(p) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldStringString: +			p := load(ctxptr, code.Idx) +			s := ptrToString(p + uintptr(code.Offset)) +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyStringString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldStringPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, ptrToString(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, ptrToString(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldStringPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBool: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBool: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBoolString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBoolString: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBoolPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendBool(ctx, b, ptrToBool(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, ptrToBool(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBoolPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBytes: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBytes: +			p := load(ctxptr, code.Idx) +			v := ptrToBytes(p + uintptr(code.Offset)) +			if len(v) > 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBytesPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldNumber: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumber: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldNumberString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = append(bb, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumberString: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldNumberPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldNumberPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldMarshalJSON: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalJSON: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				code = code.NextField +				break +			} +			iface := ptrToInterface(code, p) +			if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { +				code = code.NextField +				break +			} +			b = appendStructKey(ctx, code, b) +			bb, err := appendMarshalJSON(ctx, code, b, iface) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructFieldMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldMarshalText: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalText: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				code = code.NextField +				break +			} +			b = appendStructKey(ctx, code, b) +			bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructFieldMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldArray: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyArray: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldArrayPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyArrayPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				code = code.NextField +			} +		case encoder.OpStructFieldSlice: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptySlice: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			slice := ptrToSlice(p) +			if slice.Len == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructFieldSlicePtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptySlicePtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				code = code.NextField +			} +		case encoder.OpStructFieldMap: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyMap: +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructFieldMapPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p != 0 { +				p = ptrToNPtr(p, code.PtrNum) +			} +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyMapPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p != 0 { +				p = ptrToNPtr(p, code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				code = code.NextField +			} +		case encoder.OpStructFieldStruct: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyStruct: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructEnd: +			b = appendStructEndSkipLast(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndInt: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyInt: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndIntString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyIntString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndIntPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendInt(ctx, b, p, code) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p, code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndIntPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUint: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUint: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUintString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUintString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUintPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendUint(ctx, b, p, code) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p, code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUintPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32String: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32Ptr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32PtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = appendFloat64(ctx, b, v) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = appendFloat64(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat64(ctx, b, v) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64Ptr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +				b = appendStructEnd(ctx, code, b) +				code = code.Next +				break +			} +			v := ptrToFloat64(p) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64PtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndStringString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			s := ptrToString(p + uintptr(code.Offset)) +			b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyStringString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndStringPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, ptrToString(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, ptrToString(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndStringPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBool: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBool: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBoolString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBoolString: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBoolPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendBool(ctx, b, ptrToBool(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, ptrToBool(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBoolPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBytes: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBytes: +			p := load(ctxptr, code.Idx) +			v := ptrToBytes(p + uintptr(code.Offset)) +			if len(v) > 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBytesPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumber: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = appendStructEnd(ctx, code, bb) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumber: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = appendStructEnd(ctx, code, bb) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumberString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = append(bb, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumberString: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumberPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = appendStructEnd(ctx, code, bb) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumberPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpEnd: +			goto END +		} +	} +END: +	return b, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go new file mode 100644 index 000000000..925f61ed8 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go @@ -0,0 +1,35 @@ +package vm_color + +import ( +	"fmt" + +	"github.com/goccy/go-json/internal/encoder" +) + +func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { +	var code *encoder.Opcode +	if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { +		code = codeSet.EscapeKeyCode +	} else { +		code = codeSet.NoescapeKeyCode +	} + +	defer func() { +		if err := recover(); err != nil { +			w := ctx.Option.DebugOut +			fmt.Fprintln(w, "=============[DEBUG]===============") +			fmt.Fprintln(w, "* [TYPE]") +			fmt.Fprintln(w, codeSet.Type) +			fmt.Fprintf(w, "\n") +			fmt.Fprintln(w, "* [ALL OPCODE]") +			fmt.Fprintln(w, code.Dump()) +			fmt.Fprintf(w, "\n") +			fmt.Fprintln(w, "* [CONTEXT]") +			fmt.Fprintf(w, "%+v\n", ctx) +			fmt.Fprintln(w, "===================================") +			panic(err) +		} +	}() + +	return Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go new file mode 100644 index 000000000..12ec56c5b --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go @@ -0,0 +1,9 @@ +package vm_color + +import ( +	// HACK: compile order +	// `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile, +	// so forcibly make dependencies and avoid compiling in concurrent. +	// dependency order: vm => vm_indent => vm_color => vm_color_indent +	_ "github.com/goccy/go-json/internal/encoder/vm_color_indent" +) diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go new file mode 100644 index 000000000..33f29aee4 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go @@ -0,0 +1,274 @@ +package vm_color + +import ( +	"encoding/json" +	"fmt" +	"unsafe" + +	"github.com/goccy/go-json/internal/encoder" +	"github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +var ( +	errUnsupportedValue = encoder.ErrUnsupportedValue +	errUnsupportedFloat = encoder.ErrUnsupportedFloat +	mapiterinit         = encoder.MapIterInit +	mapiterkey          = encoder.MapIterKey +	mapitervalue        = encoder.MapIterValue +	mapiternext         = encoder.MapIterNext +	maplen              = encoder.MapLen +) + +type emptyInterface struct { +	typ *runtime.Type +	ptr unsafe.Pointer +} + +type nonEmptyInterface struct { +	itab *struct { +		ityp *runtime.Type // static interface type +		typ  *runtime.Type // dynamic concrete type +		// unused fields... +	} +	ptr unsafe.Pointer +} + +func errUnimplementedOp(op encoder.OpType) error { +	return fmt.Errorf("encoder: opcode %s has not been implemented", op) +} + +func load(base uintptr, idx uint32) uintptr { +	addr := base + uintptr(idx) +	return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uint32, p uintptr) { +	addr := base + uintptr(idx) +	**(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr { +	addr := base + uintptr(idx) +	p := **(**uintptr)(unsafe.Pointer(&addr)) +	for i := uint8(0); i < ptrNum; i++ { +		if p == 0 { +			return 0 +		} +		p = ptrToPtr(p) +	} +	return p +} + +func ptrToUint64(p uintptr, bitSize uint8) uint64 { +	switch bitSize { +	case 8: +		return (uint64)(**(**uint8)(unsafe.Pointer(&p))) +	case 16: +		return (uint64)(**(**uint16)(unsafe.Pointer(&p))) +	case 32: +		return (uint64)(**(**uint32)(unsafe.Pointer(&p))) +	case 64: +		return **(**uint64)(unsafe.Pointer(&p)) +	} +	return 0 +} +func ptrToFloat32(p uintptr) float32            { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64            { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool                  { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte               { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number         { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string              { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { +	return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum uint8) uintptr { +	for i := uint8(0); i < ptrNum; i++ { +		if p == 0 { +			return 0 +		} +		p = ptrToPtr(p) +	} +	return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { +	return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { +	return *(*interface{})(unsafe.Pointer(&emptyInterface{ +		typ: code.Type, +		ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), +	})) +} + +func appendInt(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte { +	format := ctx.Option.ColorScheme.Int +	b = append(b, format.Header...) +	b = encoder.AppendInt(ctx, b, p, code) +	return append(b, format.Footer...) +} + +func appendUint(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte { +	format := ctx.Option.ColorScheme.Uint +	b = append(b, format.Header...) +	b = encoder.AppendUint(ctx, b, p, code) +	return append(b, format.Footer...) +} + +func appendFloat32(ctx *encoder.RuntimeContext, b []byte, v float32) []byte { +	format := ctx.Option.ColorScheme.Float +	b = append(b, format.Header...) +	b = encoder.AppendFloat32(ctx, b, v) +	return append(b, format.Footer...) +} + +func appendFloat64(ctx *encoder.RuntimeContext, b []byte, v float64) []byte { +	format := ctx.Option.ColorScheme.Float +	b = append(b, format.Header...) +	b = encoder.AppendFloat64(ctx, b, v) +	return append(b, format.Footer...) +} + +func appendString(ctx *encoder.RuntimeContext, b []byte, v string) []byte { +	format := ctx.Option.ColorScheme.String +	b = append(b, format.Header...) +	b = encoder.AppendString(ctx, b, v) +	return append(b, format.Footer...) +} + +func appendByteSlice(ctx *encoder.RuntimeContext, b []byte, src []byte) []byte { +	format := ctx.Option.ColorScheme.Binary +	b = append(b, format.Header...) +	b = encoder.AppendByteSlice(ctx, b, src) +	return append(b, format.Footer...) +} + +func appendNumber(ctx *encoder.RuntimeContext, b []byte, n json.Number) ([]byte, error) { +	format := ctx.Option.ColorScheme.Int +	b = append(b, format.Header...) +	bb, err := encoder.AppendNumber(ctx, b, n) +	if err != nil { +		return nil, err +	} +	return append(bb, format.Footer...), nil +} + +func appendBool(ctx *encoder.RuntimeContext, b []byte, v bool) []byte { +	format := ctx.Option.ColorScheme.Bool +	b = append(b, format.Header...) +	if v { +		b = append(b, "true"...) +	} else { +		b = append(b, "false"...) +	} +	return append(b, format.Footer...) +} + +func appendNull(ctx *encoder.RuntimeContext, b []byte) []byte { +	format := ctx.Option.ColorScheme.Null +	b = append(b, format.Header...) +	b = append(b, "null"...) +	return append(b, format.Footer...) +} + +func appendComma(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, ',') +} + +func appendNullComma(ctx *encoder.RuntimeContext, b []byte) []byte { +	format := ctx.Option.ColorScheme.Null +	b = append(b, format.Header...) +	b = append(b, "null"...) +	return append(append(b, format.Footer...), ',') +} + +func appendColon(_ *encoder.RuntimeContext, b []byte) []byte { +	last := len(b) - 1 +	b[last] = ':' +	return b +} + +func appendMapKeyValue(_ *encoder.RuntimeContext, _ *encoder.Opcode, b, key, value []byte) []byte { +	b = append(b, key[:len(key)-1]...) +	b = append(b, ':') +	return append(b, value...) +} + +func appendMapEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { +	last := len(b) - 1 +	b[last] = '}' +	b = append(b, ',') +	return b +} + +func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { +	return encoder.AppendMarshalJSON(ctx, code, b, v) +} + +func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { +	format := ctx.Option.ColorScheme.String +	b = append(b, format.Header...) +	bb, err := encoder.AppendMarshalText(ctx, code, b, v) +	if err != nil { +		return nil, err +	} +	return append(bb, format.Footer...), nil +} + +func appendArrayHead(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { +	return append(b, '[') +} + +func appendArrayEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { +	last := len(b) - 1 +	b[last] = ']' +	return append(b, ',') +} + +func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, '[', ']', ',') +} + +func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, '{', '}', ',') +} + +func appendObjectEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { +	last := len(b) - 1 +	b[last] = '}' +	return append(b, ',') +} + +func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, '{') +} + +func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	format := ctx.Option.ColorScheme.ObjectKey +	b = append(b, format.Header...) +	b = append(b, code.Key[:len(code.Key)-1]...) +	b = append(b, format.Footer...) + +	return append(b, ':') +} + +func appendStructEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { +	return append(b, '}', ',') +} + +func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	last := len(b) - 1 +	if b[last] == ',' { +		b[last] = '}' +		return appendComma(ctx, b) +	} +	return appendStructEnd(ctx, code, b) +} + +func restoreIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, _ uintptr)               {} +func storeIndent(_ uintptr, _ *encoder.Opcode, _ uintptr)                                 {} +func appendMapKeyIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte    { return b } +func appendArrayElemIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b } diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go new file mode 100644 index 000000000..a63e83e55 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go @@ -0,0 +1,4859 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package vm_color + +import ( +	"math" +	"reflect" +	"sort" +	"unsafe" + +	"github.com/goccy/go-json/internal/encoder" +	"github.com/goccy/go-json/internal/runtime" +) + +func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { +	recursiveLevel := 0 +	ptrOffset := uintptr(0) +	ctxptr := ctx.Ptr() +	var code *encoder.Opcode +	if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { +		code = codeSet.EscapeKeyCode +	} else { +		code = codeSet.NoescapeKeyCode +	} + +	for { +		switch code.Op { +		default: +			return nil, errUnimplementedOp(code.Op) +		case encoder.OpPtr: +			p := load(ctxptr, code.Idx) +			code = code.Next +			store(ctxptr, code.Idx, ptrToPtr(p)) +		case encoder.OpIntPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpInt: +			b = appendInt(ctx, b, load(ctxptr, code.Idx), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpUintPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpUint: +			b = appendUint(ctx, b, load(ctxptr, code.Idx), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpIntString: +			b = append(b, '"') +			b = appendInt(ctx, b, load(ctxptr, code.Idx), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpUintString: +			b = append(b, '"') +			b = appendUint(ctx, b, load(ctxptr, code.Idx), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpFloat32Ptr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +				b = appendComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpFloat32: +			b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpFloat64Ptr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpFloat64: +			v := ptrToFloat64(load(ctxptr, code.Idx)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStringPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpString: +			b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpBoolPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpBool: +			b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpBytesPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpBytes: +			b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpNumberPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpNumber: +			bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx))) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpInterfacePtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpInterface: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			if recursiveLevel > encoder.StartDetectingCyclesAfter { +				for _, seen := range ctx.SeenPtr { +					if p == seen { +						return nil, errUnsupportedValue(code, p) +					} +				} +			} +			ctx.SeenPtr = append(ctx.SeenPtr, p) +			var ( +				typ      *runtime.Type +				ifacePtr unsafe.Pointer +			) +			up := ptrToUnsafePtr(p) +			if code.Flags&encoder.NonEmptyInterfaceFlags != 0 { +				iface := (*nonEmptyInterface)(up) +				ifacePtr = iface.ptr +				if iface.itab != nil { +					typ = iface.itab.typ +				} +			} else { +				iface := (*emptyInterface)(up) +				ifacePtr = iface.ptr +				typ = iface.typ +			} +			if ifacePtr == nil { +				isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ) +				if !isDirectedNil { +					b = appendNullComma(ctx, b) +					code = code.Next +					break +				} +			} +			ctx.KeepRefs = append(ctx.KeepRefs, up) +			ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ))) +			if err != nil { +				return nil, err +			} + +			totalLength := uintptr(code.Length) + 3 +			nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3 + +			var c *encoder.Opcode +			if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { +				c = ifaceCodeSet.InterfaceEscapeKeyCode +			} else { +				c = ifaceCodeSet.InterfaceNoescapeKeyCode +			} +			curlen := uintptr(len(ctx.Ptrs)) +			offsetNum := ptrOffset / uintptrSize +			oldOffset := ptrOffset +			ptrOffset += totalLength * uintptrSize +			oldBaseIndent := ctx.BaseIndent +			ctx.BaseIndent += code.Indent + +			newLen := offsetNum + totalLength + nextTotalLength +			if curlen < newLen { +				ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) +			} +			ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + +			end := ifaceCodeSet.EndCode +			store(ctxptr, c.Idx, uintptr(ifacePtr)) +			store(ctxptr, end.Idx, oldOffset) +			store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next))) +			storeIndent(ctxptr, end, uintptr(oldBaseIndent)) +			code = c +			recursiveLevel++ +		case encoder.OpInterfaceEnd: +			recursiveLevel-- + +			// restore ctxptr +			offset := load(ctxptr, code.Idx) +			restoreIndent(ctx, code, ctxptr) +			ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + +			codePtr := load(ctxptr, code.ElemIdx) +			code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) +			ctxptr = ctx.Ptr() + offset +			ptrOffset = offset +		case encoder.OpMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, ptrToPtr(p)) +			fallthrough +		case encoder.OpMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p) +			} +			bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, ptrToPtr(p)) +			fallthrough +		case encoder.OpMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = append(b, `""`...) +				b = appendComma(ctx, b) +				code = code.Next +				break +			} +			if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p) +			} +			bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpSlicePtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpSlice: +			p := load(ctxptr, code.Idx) +			slice := ptrToSlice(p) +			if p == 0 || slice.Data == nil { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.ElemIdx, 0) +			store(ctxptr, code.Length, uintptr(slice.Len)) +			store(ctxptr, code.Idx, uintptr(slice.Data)) +			if slice.Len > 0 { +				b = appendArrayHead(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, uintptr(slice.Data)) +			} else { +				b = appendEmptyArray(ctx, b) +				code = code.End.Next +			} +		case encoder.OpSliceElem: +			idx := load(ctxptr, code.ElemIdx) +			length := load(ctxptr, code.Length) +			idx++ +			if idx < length { +				b = appendArrayElemIndent(ctx, code, b) +				store(ctxptr, code.ElemIdx, idx) +				data := load(ctxptr, code.Idx) +				size := uintptr(code.Size) +				code = code.Next +				store(ctxptr, code.Idx, data+idx*size) +			} else { +				b = appendArrayEnd(ctx, code, b) +				code = code.End.Next +			} +		case encoder.OpArrayPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpArray: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			if code.Length > 0 { +				b = appendArrayHead(ctx, code, b) +				store(ctxptr, code.ElemIdx, 0) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				b = appendEmptyArray(ctx, b) +				code = code.End.Next +			} +		case encoder.OpArrayElem: +			idx := load(ctxptr, code.ElemIdx) +			idx++ +			if idx < uintptr(code.Length) { +				b = appendArrayElemIndent(ctx, code, b) +				store(ctxptr, code.ElemIdx, idx) +				p := load(ctxptr, code.Idx) +				size := uintptr(code.Size) +				code = code.Next +				store(ctxptr, code.Idx, p+idx*size) +			} else { +				b = appendArrayEnd(ctx, code, b) +				code = code.End.Next +			} +		case encoder.OpMapPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpMap: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			uptr := ptrToUnsafePtr(p) +			mlen := maplen(uptr) +			if mlen <= 0 { +				b = appendEmptyObject(ctx, b) +				code = code.End.Next +				break +			} +			b = appendStructHead(ctx, b) +			unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 +			mapCtx := encoder.NewMapContext(mlen, unorderedMap) +			mapiterinit(code.Type, uptr, &mapCtx.Iter) +			store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx))) +			ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) +			if unorderedMap { +				b = appendMapKeyIndent(ctx, code.Next, b) +			} else { +				mapCtx.Start = len(b) +				mapCtx.First = len(b) +			} +			key := mapiterkey(&mapCtx.Iter) +			store(ctxptr, code.Next.Idx, uintptr(key)) +			code = code.Next +		case encoder.OpMapKey: +			mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) +			idx := mapCtx.Idx +			idx++ +			if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { +				if idx < mapCtx.Len { +					b = appendMapKeyIndent(ctx, code, b) +					mapCtx.Idx = int(idx) +					key := mapiterkey(&mapCtx.Iter) +					store(ctxptr, code.Next.Idx, uintptr(key)) +					code = code.Next +				} else { +					b = appendObjectEnd(ctx, code, b) +					encoder.ReleaseMapContext(mapCtx) +					code = code.End.Next +				} +			} else { +				mapCtx.Slice.Items[mapCtx.Idx].Value = b[mapCtx.Start:len(b)] +				if idx < mapCtx.Len { +					mapCtx.Idx = int(idx) +					mapCtx.Start = len(b) +					key := mapiterkey(&mapCtx.Iter) +					store(ctxptr, code.Next.Idx, uintptr(key)) +					code = code.Next +				} else { +					code = code.End +				} +			} +		case encoder.OpMapValue: +			mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) +			if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { +				b = appendColon(ctx, b) +			} else { +				mapCtx.Slice.Items[mapCtx.Idx].Key = b[mapCtx.Start:len(b)] +				mapCtx.Start = len(b) +			} +			value := mapitervalue(&mapCtx.Iter) +			store(ctxptr, code.Next.Idx, uintptr(value)) +			mapiternext(&mapCtx.Iter) +			code = code.Next +		case encoder.OpMapEnd: +			// this operation only used by sorted map. +			mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) +			sort.Sort(mapCtx.Slice) +			buf := mapCtx.Buf +			for _, item := range mapCtx.Slice.Items { +				buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value) +			} +			buf = appendMapEnd(ctx, code, buf) +			b = b[:mapCtx.First] +			b = append(b, buf...) +			mapCtx.Buf = buf +			encoder.ReleaseMapContext(mapCtx) +			code = code.Next +		case encoder.OpRecursivePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpRecursive: +			ptr := load(ctxptr, code.Idx) +			if ptr != 0 { +				if recursiveLevel > encoder.StartDetectingCyclesAfter { +					for _, seen := range ctx.SeenPtr { +						if ptr == seen { +							return nil, errUnsupportedValue(code, ptr) +						} +					} +				} +			} +			ctx.SeenPtr = append(ctx.SeenPtr, ptr) +			c := code.Jmp.Code +			curlen := uintptr(len(ctx.Ptrs)) +			offsetNum := ptrOffset / uintptrSize +			oldOffset := ptrOffset +			ptrOffset += code.Jmp.CurLen * uintptrSize +			oldBaseIndent := ctx.BaseIndent +			indentDiffFromTop := c.Indent - 1 +			ctx.BaseIndent += code.Indent - indentDiffFromTop + +			newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen +			if curlen < newLen { +				ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) +			} +			ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + +			store(ctxptr, c.Idx, ptr) +			store(ctxptr, c.End.Next.Idx, oldOffset) +			store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) +			storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent)) +			code = c +			recursiveLevel++ +		case encoder.OpRecursiveEnd: +			recursiveLevel-- + +			// restore ctxptr +			restoreIndent(ctx, code, ctxptr) +			offset := load(ctxptr, code.Idx) +			ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + +			codePtr := load(ctxptr, code.ElemIdx) +			code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) +			ctxptr = ctx.Ptr() + offset +			ptrOffset = offset +		case encoder.OpStructPtrHead: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHead: +			p := load(ctxptr, code.Idx) +			if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if len(code.Key) > 0 { +				if (code.Flags&encoder.IsTaggedKeyFlags) != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { +					b = appendStructKey(ctx, code, b) +				} +			} +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmpty: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmpty: +			p := load(ctxptr, code.Idx) +			if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadInt: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadInt: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyInt: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyInt: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadIntString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadIntString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyIntString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyIntString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			u64 := ptrToUint64(p, code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendInt(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadUint: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadUint: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUint: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyUint: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadUintString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadUintString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUintString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyUintString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendUint(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat32: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat32: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat32String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat32String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat64: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat64: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat64String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat64String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat64(ctx, b, v) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNull(ctx, b) +					b = appendComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToString(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadStringString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadStringString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset))))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyStringString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyStringString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToString(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, ptrToString(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, ptrToString(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadBool: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadBool: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBool: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyBool: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} else { +				code = code.NextField +			} +		case encoder.OpStructPtrHeadBoolString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadBoolString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBoolString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyBoolString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} else { +				code = code.NextField +			} +		case encoder.OpStructPtrHeadBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendBool(ctx, b, ptrToBool(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, ptrToBool(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadBytes: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadBytes: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBytes: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyBytes: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToBytes(p + uintptr(code.Offset)) +			if len(v) == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadNumber: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadNumber: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumber: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumber: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +				code = code.Next +			} +		case encoder.OpStructPtrHeadNumberString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadNumberString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = append(bb, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumberString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumberString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructPtrHeadNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadArray, encoder.OpStructHeadSlice: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmptyArray: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyArray: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			b = appendStructKey(ctx, code, b) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmptySlice: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptySlice: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			slice := ptrToSlice(p) +			if slice.Len == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.NextField +			} else { +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadMap: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMap: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p + uintptr(code.Offset)) +			} +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmptyMap: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMap: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p + uintptr(code.Offset)) +			} +			if maplen(ptrToUnsafePtr(p)) == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.NextField +				break +			} +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.NextField +			} else { +				if (code.Flags & encoder.IndirectFlags) != 0 { +					p = ptrToNPtr(p, code.PtrNum) +				} +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadOmitEmptyMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p == 0 { +				code = code.NextField +				break +			} +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p == 0 { +				code = code.NextField +			} else { +				if (code.Flags & encoder.IndirectFlags) != 0 { +					p = ptrToNPtr(p, code.PtrNum) +				} +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { +					p = ptrToPtr(p) +				} +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { +					p = ptrToPtr(p) +				} +			} +			iface := ptrToInterface(code, p) +			if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalJSON(ctx, code, b, iface) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { +					p = ptrToPtr(p) +				} +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { +					p = ptrToPtr(p) +				} +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructField: +			if code.Flags&encoder.IsTaggedKeyFlags != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { +				b = appendStructKey(ctx, code, b) +			} +			p := load(ctxptr, code.Idx) + uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmpty: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructFieldInt: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyInt: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldIntString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyIntString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldIntPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendInt(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldIntPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUint: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUint: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUintString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUintString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUintPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendUint(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUintPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32String: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat64(ctx, b, v) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			v := ptrToFloat64(p) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldStringString: +			p := load(ctxptr, code.Idx) +			s := ptrToString(p + uintptr(code.Offset)) +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyStringString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldStringPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, ptrToString(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, ptrToString(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldStringPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBool: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBool: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBoolString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBoolString: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBoolPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendBool(ctx, b, ptrToBool(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, ptrToBool(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBoolPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBytes: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBytes: +			p := load(ctxptr, code.Idx) +			v := ptrToBytes(p + uintptr(code.Offset)) +			if len(v) > 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBytesPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldNumber: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumber: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldNumberString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = append(bb, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumberString: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldNumberPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldNumberPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldMarshalJSON: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalJSON: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				code = code.NextField +				break +			} +			iface := ptrToInterface(code, p) +			if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { +				code = code.NextField +				break +			} +			b = appendStructKey(ctx, code, b) +			bb, err := appendMarshalJSON(ctx, code, b, iface) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructFieldMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldMarshalText: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalText: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				code = code.NextField +				break +			} +			b = appendStructKey(ctx, code, b) +			bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructFieldMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldArray: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyArray: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldArrayPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyArrayPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				code = code.NextField +			} +		case encoder.OpStructFieldSlice: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptySlice: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			slice := ptrToSlice(p) +			if slice.Len == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructFieldSlicePtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptySlicePtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				code = code.NextField +			} +		case encoder.OpStructFieldMap: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyMap: +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructFieldMapPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p != 0 { +				p = ptrToNPtr(p, code.PtrNum) +			} +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyMapPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p != 0 { +				p = ptrToNPtr(p, code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				code = code.NextField +			} +		case encoder.OpStructFieldStruct: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyStruct: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructEnd: +			b = appendStructEndSkipLast(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndInt: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyInt: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndIntString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyIntString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndIntPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendInt(ctx, b, p, code) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p, code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndIntPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUint: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUint: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUintString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUintString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUintPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendUint(ctx, b, p, code) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p, code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUintPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32String: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32Ptr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32PtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = appendFloat64(ctx, b, v) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = appendFloat64(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat64(ctx, b, v) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64Ptr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +				b = appendStructEnd(ctx, code, b) +				code = code.Next +				break +			} +			v := ptrToFloat64(p) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64PtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndStringString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			s := ptrToString(p + uintptr(code.Offset)) +			b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyStringString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndStringPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, ptrToString(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, ptrToString(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndStringPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBool: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBool: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBoolString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBoolString: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBoolPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendBool(ctx, b, ptrToBool(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, ptrToBool(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBoolPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBytes: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBytes: +			p := load(ctxptr, code.Idx) +			v := ptrToBytes(p + uintptr(code.Offset)) +			if len(v) > 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBytesPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumber: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = appendStructEnd(ctx, code, bb) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumber: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = appendStructEnd(ctx, code, bb) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumberString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = append(bb, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumberString: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumberPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = appendStructEnd(ctx, code, bb) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumberPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpEnd: +			goto END +		} +	} +END: +	return b, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go new file mode 100644 index 000000000..dd4cd489e --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go @@ -0,0 +1,35 @@ +package vm_color_indent + +import ( +	"fmt" + +	"github.com/goccy/go-json/internal/encoder" +) + +func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { +	var code *encoder.Opcode +	if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { +		code = codeSet.EscapeKeyCode +	} else { +		code = codeSet.NoescapeKeyCode +	} + +	defer func() { +		if err := recover(); err != nil { +			w := ctx.Option.DebugOut +			fmt.Fprintln(w, "=============[DEBUG]===============") +			fmt.Fprintln(w, "* [TYPE]") +			fmt.Fprintln(w, codeSet.Type) +			fmt.Fprintf(w, "\n") +			fmt.Fprintln(w, "* [ALL OPCODE]") +			fmt.Fprintln(w, code.Dump()) +			fmt.Fprintf(w, "\n") +			fmt.Fprintln(w, "* [CONTEXT]") +			fmt.Fprintf(w, "%+v\n", ctx) +			fmt.Fprintln(w, "===================================") +			panic(err) +		} +	}() + +	return Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go new file mode 100644 index 000000000..60e4a8ed5 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go @@ -0,0 +1,296 @@ +package vm_color_indent + +import ( +	"encoding/json" +	"fmt" +	"unsafe" + +	"github.com/goccy/go-json/internal/encoder" +	"github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +var ( +	appendIndent        = encoder.AppendIndent +	appendStructEnd     = encoder.AppendStructEndIndent +	errUnsupportedValue = encoder.ErrUnsupportedValue +	errUnsupportedFloat = encoder.ErrUnsupportedFloat +	mapiterinit         = encoder.MapIterInit +	mapiterkey          = encoder.MapIterKey +	mapitervalue        = encoder.MapIterValue +	mapiternext         = encoder.MapIterNext +	maplen              = encoder.MapLen +) + +type emptyInterface struct { +	typ *runtime.Type +	ptr unsafe.Pointer +} + +type nonEmptyInterface struct { +	itab *struct { +		ityp *runtime.Type // static interface type +		typ  *runtime.Type // dynamic concrete type +		// unused fields... +	} +	ptr unsafe.Pointer +} + +func errUnimplementedOp(op encoder.OpType) error { +	return fmt.Errorf("encoder (indent): opcode %s has not been implemented", op) +} + +func load(base uintptr, idx uint32) uintptr { +	addr := base + uintptr(idx) +	return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uint32, p uintptr) { +	addr := base + uintptr(idx) +	**(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr { +	addr := base + uintptr(idx) +	p := **(**uintptr)(unsafe.Pointer(&addr)) +	for i := uint8(0); i < ptrNum; i++ { +		if p == 0 { +			return 0 +		} +		p = ptrToPtr(p) +	} +	return p +} + +func ptrToUint64(p uintptr, bitSize uint8) uint64 { +	switch bitSize { +	case 8: +		return (uint64)(**(**uint8)(unsafe.Pointer(&p))) +	case 16: +		return (uint64)(**(**uint16)(unsafe.Pointer(&p))) +	case 32: +		return (uint64)(**(**uint32)(unsafe.Pointer(&p))) +	case 64: +		return **(**uint64)(unsafe.Pointer(&p)) +	} +	return 0 +} + +func ptrToFloat32(p uintptr) float32            { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64            { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool                  { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte               { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number         { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string              { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { +	return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum uint8) uintptr { +	for i := uint8(0); i < ptrNum; i++ { +		if p == 0 { +			return 0 +		} +		p = ptrToPtr(p) +	} +	return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { +	return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { +	return *(*interface{})(unsafe.Pointer(&emptyInterface{ +		typ: code.Type, +		ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), +	})) +} + +func appendInt(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte { +	format := ctx.Option.ColorScheme.Int +	b = append(b, format.Header...) +	b = encoder.AppendInt(ctx, b, p, code) +	return append(b, format.Footer...) +} + +func appendUint(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte { +	format := ctx.Option.ColorScheme.Uint +	b = append(b, format.Header...) +	b = encoder.AppendUint(ctx, b, p, code) +	return append(b, format.Footer...) +} + +func appendFloat32(ctx *encoder.RuntimeContext, b []byte, v float32) []byte { +	format := ctx.Option.ColorScheme.Float +	b = append(b, format.Header...) +	b = encoder.AppendFloat32(ctx, b, v) +	return append(b, format.Footer...) +} + +func appendFloat64(ctx *encoder.RuntimeContext, b []byte, v float64) []byte { +	format := ctx.Option.ColorScheme.Float +	b = append(b, format.Header...) +	b = encoder.AppendFloat64(ctx, b, v) +	return append(b, format.Footer...) +} + +func appendString(ctx *encoder.RuntimeContext, b []byte, v string) []byte { +	format := ctx.Option.ColorScheme.String +	b = append(b, format.Header...) +	b = encoder.AppendString(ctx, b, v) +	return append(b, format.Footer...) +} + +func appendByteSlice(ctx *encoder.RuntimeContext, b []byte, src []byte) []byte { +	format := ctx.Option.ColorScheme.Binary +	b = append(b, format.Header...) +	b = encoder.AppendByteSlice(ctx, b, src) +	return append(b, format.Footer...) +} + +func appendNumber(ctx *encoder.RuntimeContext, b []byte, n json.Number) ([]byte, error) { +	format := ctx.Option.ColorScheme.Int +	b = append(b, format.Header...) +	bb, err := encoder.AppendNumber(ctx, b, n) +	if err != nil { +		return nil, err +	} +	return append(bb, format.Footer...), nil +} + +func appendBool(ctx *encoder.RuntimeContext, b []byte, v bool) []byte { +	format := ctx.Option.ColorScheme.Bool +	b = append(b, format.Header...) +	if v { +		b = append(b, "true"...) +	} else { +		b = append(b, "false"...) +	} +	return append(b, format.Footer...) +} + +func appendNull(ctx *encoder.RuntimeContext, b []byte) []byte { +	format := ctx.Option.ColorScheme.Null +	b = append(b, format.Header...) +	b = append(b, "null"...) +	return append(b, format.Footer...) +} + +func appendComma(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, ',', '\n') +} + +func appendNullComma(ctx *encoder.RuntimeContext, b []byte) []byte { +	format := ctx.Option.ColorScheme.Null +	b = append(b, format.Header...) +	b = append(b, "null"...) +	return append(append(b, format.Footer...), ',', '\n') +} + +func appendColon(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, ':', ' ') +} + +func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte { +	b = appendIndent(ctx, b, code.Indent+1) +	b = append(b, key...) +	b[len(b)-2] = ':' +	b[len(b)-1] = ' ' +	return append(b, value...) +} + +func appendMapEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	b = b[:len(b)-2] +	b = append(b, '\n') +	b = appendIndent(ctx, b, code.Indent) +	return append(b, '}', ',', '\n') +} + +func appendArrayHead(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	b = append(b, '[', '\n') +	return appendIndent(ctx, b, code.Indent+1) +} + +func appendArrayEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	b = b[:len(b)-2] +	b = append(b, '\n') +	b = appendIndent(ctx, b, code.Indent) +	return append(b, ']', ',', '\n') +} + +func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, '[', ']', ',', '\n') +} + +func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, '{', '}', ',', '\n') +} + +func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	last := len(b) - 1 +	b[last] = '\n' +	b = appendIndent(ctx, b, code.Indent-1) +	return append(b, '}', ',', '\n') +} + +func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { +	return encoder.AppendMarshalJSONIndent(ctx, code, b, v) +} + +func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { +	format := ctx.Option.ColorScheme.String +	b = append(b, format.Header...) +	bb, err := encoder.AppendMarshalTextIndent(ctx, code, b, v) +	if err != nil { +		return nil, err +	} +	return append(bb, format.Footer...), nil +} + +func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, '{', '\n') +} + +func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	b = appendIndent(ctx, b, code.Indent) + +	format := ctx.Option.ColorScheme.ObjectKey +	b = append(b, format.Header...) +	b = append(b, code.Key[:len(code.Key)-1]...) +	b = append(b, format.Footer...) + +	return append(b, ':', ' ') +} + +func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	last := len(b) - 1 +	if b[last-1] == '{' { +		b[last] = '}' +	} else { +		if b[last] == '\n' { +			// to remove ',' and '\n' characters +			b = b[:len(b)-2] +		} +		b = append(b, '\n') +		b = appendIndent(ctx, b, code.Indent-1) +		b = append(b, '}') +	} +	return appendComma(ctx, b) +} + +func restoreIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, ctxptr uintptr) { +	ctx.BaseIndent = uint32(load(ctxptr, code.Length)) +} + +func storeIndent(ctxptr uintptr, code *encoder.Opcode, indent uintptr) { +	store(ctxptr, code.Length, indent) +} + +func appendArrayElemIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	return appendIndent(ctx, b, code.Indent+1) +} + +func appendMapKeyIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	return appendIndent(ctx, b, code.Indent) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go new file mode 100644 index 000000000..3b4e22e5d --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go @@ -0,0 +1,4859 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package vm_color_indent + +import ( +	"math" +	"reflect" +	"sort" +	"unsafe" + +	"github.com/goccy/go-json/internal/encoder" +	"github.com/goccy/go-json/internal/runtime" +) + +func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { +	recursiveLevel := 0 +	ptrOffset := uintptr(0) +	ctxptr := ctx.Ptr() +	var code *encoder.Opcode +	if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { +		code = codeSet.EscapeKeyCode +	} else { +		code = codeSet.NoescapeKeyCode +	} + +	for { +		switch code.Op { +		default: +			return nil, errUnimplementedOp(code.Op) +		case encoder.OpPtr: +			p := load(ctxptr, code.Idx) +			code = code.Next +			store(ctxptr, code.Idx, ptrToPtr(p)) +		case encoder.OpIntPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpInt: +			b = appendInt(ctx, b, load(ctxptr, code.Idx), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpUintPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpUint: +			b = appendUint(ctx, b, load(ctxptr, code.Idx), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpIntString: +			b = append(b, '"') +			b = appendInt(ctx, b, load(ctxptr, code.Idx), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpUintString: +			b = append(b, '"') +			b = appendUint(ctx, b, load(ctxptr, code.Idx), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpFloat32Ptr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +				b = appendComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpFloat32: +			b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpFloat64Ptr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpFloat64: +			v := ptrToFloat64(load(ctxptr, code.Idx)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStringPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpString: +			b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpBoolPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpBool: +			b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpBytesPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpBytes: +			b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpNumberPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpNumber: +			bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx))) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpInterfacePtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpInterface: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			if recursiveLevel > encoder.StartDetectingCyclesAfter { +				for _, seen := range ctx.SeenPtr { +					if p == seen { +						return nil, errUnsupportedValue(code, p) +					} +				} +			} +			ctx.SeenPtr = append(ctx.SeenPtr, p) +			var ( +				typ      *runtime.Type +				ifacePtr unsafe.Pointer +			) +			up := ptrToUnsafePtr(p) +			if code.Flags&encoder.NonEmptyInterfaceFlags != 0 { +				iface := (*nonEmptyInterface)(up) +				ifacePtr = iface.ptr +				if iface.itab != nil { +					typ = iface.itab.typ +				} +			} else { +				iface := (*emptyInterface)(up) +				ifacePtr = iface.ptr +				typ = iface.typ +			} +			if ifacePtr == nil { +				isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ) +				if !isDirectedNil { +					b = appendNullComma(ctx, b) +					code = code.Next +					break +				} +			} +			ctx.KeepRefs = append(ctx.KeepRefs, up) +			ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ))) +			if err != nil { +				return nil, err +			} + +			totalLength := uintptr(code.Length) + 3 +			nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3 + +			var c *encoder.Opcode +			if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { +				c = ifaceCodeSet.InterfaceEscapeKeyCode +			} else { +				c = ifaceCodeSet.InterfaceNoescapeKeyCode +			} +			curlen := uintptr(len(ctx.Ptrs)) +			offsetNum := ptrOffset / uintptrSize +			oldOffset := ptrOffset +			ptrOffset += totalLength * uintptrSize +			oldBaseIndent := ctx.BaseIndent +			ctx.BaseIndent += code.Indent + +			newLen := offsetNum + totalLength + nextTotalLength +			if curlen < newLen { +				ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) +			} +			ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + +			end := ifaceCodeSet.EndCode +			store(ctxptr, c.Idx, uintptr(ifacePtr)) +			store(ctxptr, end.Idx, oldOffset) +			store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next))) +			storeIndent(ctxptr, end, uintptr(oldBaseIndent)) +			code = c +			recursiveLevel++ +		case encoder.OpInterfaceEnd: +			recursiveLevel-- + +			// restore ctxptr +			offset := load(ctxptr, code.Idx) +			restoreIndent(ctx, code, ctxptr) +			ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + +			codePtr := load(ctxptr, code.ElemIdx) +			code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) +			ctxptr = ctx.Ptr() + offset +			ptrOffset = offset +		case encoder.OpMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, ptrToPtr(p)) +			fallthrough +		case encoder.OpMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p) +			} +			bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, ptrToPtr(p)) +			fallthrough +		case encoder.OpMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = append(b, `""`...) +				b = appendComma(ctx, b) +				code = code.Next +				break +			} +			if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p) +			} +			bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpSlicePtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpSlice: +			p := load(ctxptr, code.Idx) +			slice := ptrToSlice(p) +			if p == 0 || slice.Data == nil { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.ElemIdx, 0) +			store(ctxptr, code.Length, uintptr(slice.Len)) +			store(ctxptr, code.Idx, uintptr(slice.Data)) +			if slice.Len > 0 { +				b = appendArrayHead(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, uintptr(slice.Data)) +			} else { +				b = appendEmptyArray(ctx, b) +				code = code.End.Next +			} +		case encoder.OpSliceElem: +			idx := load(ctxptr, code.ElemIdx) +			length := load(ctxptr, code.Length) +			idx++ +			if idx < length { +				b = appendArrayElemIndent(ctx, code, b) +				store(ctxptr, code.ElemIdx, idx) +				data := load(ctxptr, code.Idx) +				size := uintptr(code.Size) +				code = code.Next +				store(ctxptr, code.Idx, data+idx*size) +			} else { +				b = appendArrayEnd(ctx, code, b) +				code = code.End.Next +			} +		case encoder.OpArrayPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpArray: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			if code.Length > 0 { +				b = appendArrayHead(ctx, code, b) +				store(ctxptr, code.ElemIdx, 0) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				b = appendEmptyArray(ctx, b) +				code = code.End.Next +			} +		case encoder.OpArrayElem: +			idx := load(ctxptr, code.ElemIdx) +			idx++ +			if idx < uintptr(code.Length) { +				b = appendArrayElemIndent(ctx, code, b) +				store(ctxptr, code.ElemIdx, idx) +				p := load(ctxptr, code.Idx) +				size := uintptr(code.Size) +				code = code.Next +				store(ctxptr, code.Idx, p+idx*size) +			} else { +				b = appendArrayEnd(ctx, code, b) +				code = code.End.Next +			} +		case encoder.OpMapPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpMap: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			uptr := ptrToUnsafePtr(p) +			mlen := maplen(uptr) +			if mlen <= 0 { +				b = appendEmptyObject(ctx, b) +				code = code.End.Next +				break +			} +			b = appendStructHead(ctx, b) +			unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 +			mapCtx := encoder.NewMapContext(mlen, unorderedMap) +			mapiterinit(code.Type, uptr, &mapCtx.Iter) +			store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx))) +			ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) +			if unorderedMap { +				b = appendMapKeyIndent(ctx, code.Next, b) +			} else { +				mapCtx.Start = len(b) +				mapCtx.First = len(b) +			} +			key := mapiterkey(&mapCtx.Iter) +			store(ctxptr, code.Next.Idx, uintptr(key)) +			code = code.Next +		case encoder.OpMapKey: +			mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) +			idx := mapCtx.Idx +			idx++ +			if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { +				if idx < mapCtx.Len { +					b = appendMapKeyIndent(ctx, code, b) +					mapCtx.Idx = int(idx) +					key := mapiterkey(&mapCtx.Iter) +					store(ctxptr, code.Next.Idx, uintptr(key)) +					code = code.Next +				} else { +					b = appendObjectEnd(ctx, code, b) +					encoder.ReleaseMapContext(mapCtx) +					code = code.End.Next +				} +			} else { +				mapCtx.Slice.Items[mapCtx.Idx].Value = b[mapCtx.Start:len(b)] +				if idx < mapCtx.Len { +					mapCtx.Idx = int(idx) +					mapCtx.Start = len(b) +					key := mapiterkey(&mapCtx.Iter) +					store(ctxptr, code.Next.Idx, uintptr(key)) +					code = code.Next +				} else { +					code = code.End +				} +			} +		case encoder.OpMapValue: +			mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) +			if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { +				b = appendColon(ctx, b) +			} else { +				mapCtx.Slice.Items[mapCtx.Idx].Key = b[mapCtx.Start:len(b)] +				mapCtx.Start = len(b) +			} +			value := mapitervalue(&mapCtx.Iter) +			store(ctxptr, code.Next.Idx, uintptr(value)) +			mapiternext(&mapCtx.Iter) +			code = code.Next +		case encoder.OpMapEnd: +			// this operation only used by sorted map. +			mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) +			sort.Sort(mapCtx.Slice) +			buf := mapCtx.Buf +			for _, item := range mapCtx.Slice.Items { +				buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value) +			} +			buf = appendMapEnd(ctx, code, buf) +			b = b[:mapCtx.First] +			b = append(b, buf...) +			mapCtx.Buf = buf +			encoder.ReleaseMapContext(mapCtx) +			code = code.Next +		case encoder.OpRecursivePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpRecursive: +			ptr := load(ctxptr, code.Idx) +			if ptr != 0 { +				if recursiveLevel > encoder.StartDetectingCyclesAfter { +					for _, seen := range ctx.SeenPtr { +						if ptr == seen { +							return nil, errUnsupportedValue(code, ptr) +						} +					} +				} +			} +			ctx.SeenPtr = append(ctx.SeenPtr, ptr) +			c := code.Jmp.Code +			curlen := uintptr(len(ctx.Ptrs)) +			offsetNum := ptrOffset / uintptrSize +			oldOffset := ptrOffset +			ptrOffset += code.Jmp.CurLen * uintptrSize +			oldBaseIndent := ctx.BaseIndent +			indentDiffFromTop := c.Indent - 1 +			ctx.BaseIndent += code.Indent - indentDiffFromTop + +			newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen +			if curlen < newLen { +				ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) +			} +			ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + +			store(ctxptr, c.Idx, ptr) +			store(ctxptr, c.End.Next.Idx, oldOffset) +			store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) +			storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent)) +			code = c +			recursiveLevel++ +		case encoder.OpRecursiveEnd: +			recursiveLevel-- + +			// restore ctxptr +			restoreIndent(ctx, code, ctxptr) +			offset := load(ctxptr, code.Idx) +			ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + +			codePtr := load(ctxptr, code.ElemIdx) +			code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) +			ctxptr = ctx.Ptr() + offset +			ptrOffset = offset +		case encoder.OpStructPtrHead: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHead: +			p := load(ctxptr, code.Idx) +			if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if len(code.Key) > 0 { +				if (code.Flags&encoder.IsTaggedKeyFlags) != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { +					b = appendStructKey(ctx, code, b) +				} +			} +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmpty: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmpty: +			p := load(ctxptr, code.Idx) +			if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadInt: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadInt: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyInt: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyInt: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadIntString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadIntString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyIntString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyIntString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			u64 := ptrToUint64(p, code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendInt(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadUint: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadUint: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUint: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyUint: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadUintString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadUintString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUintString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyUintString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendUint(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat32: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat32: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat32String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat32String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat64: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat64: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat64String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat64String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat64(ctx, b, v) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNull(ctx, b) +					b = appendComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToString(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadStringString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadStringString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset))))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyStringString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyStringString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToString(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, ptrToString(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, ptrToString(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadBool: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadBool: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBool: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyBool: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} else { +				code = code.NextField +			} +		case encoder.OpStructPtrHeadBoolString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadBoolString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBoolString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyBoolString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} else { +				code = code.NextField +			} +		case encoder.OpStructPtrHeadBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendBool(ctx, b, ptrToBool(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, ptrToBool(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadBytes: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadBytes: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBytes: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyBytes: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToBytes(p + uintptr(code.Offset)) +			if len(v) == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadNumber: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadNumber: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumber: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumber: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +				code = code.Next +			} +		case encoder.OpStructPtrHeadNumberString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadNumberString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = append(bb, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumberString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumberString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructPtrHeadNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadArray, encoder.OpStructHeadSlice: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmptyArray: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyArray: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			b = appendStructKey(ctx, code, b) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmptySlice: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptySlice: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			slice := ptrToSlice(p) +			if slice.Len == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.NextField +			} else { +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadMap: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMap: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p + uintptr(code.Offset)) +			} +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmptyMap: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMap: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p + uintptr(code.Offset)) +			} +			if maplen(ptrToUnsafePtr(p)) == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.NextField +				break +			} +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.NextField +			} else { +				if (code.Flags & encoder.IndirectFlags) != 0 { +					p = ptrToNPtr(p, code.PtrNum) +				} +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadOmitEmptyMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p == 0 { +				code = code.NextField +				break +			} +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p == 0 { +				code = code.NextField +			} else { +				if (code.Flags & encoder.IndirectFlags) != 0 { +					p = ptrToNPtr(p, code.PtrNum) +				} +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { +					p = ptrToPtr(p) +				} +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { +					p = ptrToPtr(p) +				} +			} +			iface := ptrToInterface(code, p) +			if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalJSON(ctx, code, b, iface) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { +					p = ptrToPtr(p) +				} +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { +					p = ptrToPtr(p) +				} +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructField: +			if code.Flags&encoder.IsTaggedKeyFlags != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { +				b = appendStructKey(ctx, code, b) +			} +			p := load(ctxptr, code.Idx) + uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmpty: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructFieldInt: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyInt: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldIntString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyIntString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldIntPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendInt(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldIntPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUint: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUint: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUintString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUintString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUintPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendUint(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUintPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32String: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat64(ctx, b, v) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			v := ptrToFloat64(p) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldStringString: +			p := load(ctxptr, code.Idx) +			s := ptrToString(p + uintptr(code.Offset)) +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyStringString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldStringPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, ptrToString(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, ptrToString(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldStringPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBool: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBool: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBoolString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBoolString: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBoolPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendBool(ctx, b, ptrToBool(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, ptrToBool(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBoolPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBytes: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBytes: +			p := load(ctxptr, code.Idx) +			v := ptrToBytes(p + uintptr(code.Offset)) +			if len(v) > 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBytesPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldNumber: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumber: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldNumberString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = append(bb, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumberString: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldNumberPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldNumberPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldMarshalJSON: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalJSON: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				code = code.NextField +				break +			} +			iface := ptrToInterface(code, p) +			if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { +				code = code.NextField +				break +			} +			b = appendStructKey(ctx, code, b) +			bb, err := appendMarshalJSON(ctx, code, b, iface) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructFieldMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldMarshalText: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalText: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				code = code.NextField +				break +			} +			b = appendStructKey(ctx, code, b) +			bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructFieldMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldArray: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyArray: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldArrayPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyArrayPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				code = code.NextField +			} +		case encoder.OpStructFieldSlice: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptySlice: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			slice := ptrToSlice(p) +			if slice.Len == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructFieldSlicePtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptySlicePtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				code = code.NextField +			} +		case encoder.OpStructFieldMap: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyMap: +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructFieldMapPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p != 0 { +				p = ptrToNPtr(p, code.PtrNum) +			} +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyMapPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p != 0 { +				p = ptrToNPtr(p, code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				code = code.NextField +			} +		case encoder.OpStructFieldStruct: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyStruct: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructEnd: +			b = appendStructEndSkipLast(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndInt: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyInt: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndIntString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyIntString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndIntPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendInt(ctx, b, p, code) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p, code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndIntPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUint: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUint: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUintString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUintString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUintPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendUint(ctx, b, p, code) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p, code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUintPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32String: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32Ptr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32PtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = appendFloat64(ctx, b, v) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = appendFloat64(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat64(ctx, b, v) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64Ptr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +				b = appendStructEnd(ctx, code, b) +				code = code.Next +				break +			} +			v := ptrToFloat64(p) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64PtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndStringString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			s := ptrToString(p + uintptr(code.Offset)) +			b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyStringString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndStringPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, ptrToString(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, ptrToString(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndStringPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBool: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBool: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBoolString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBoolString: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBoolPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendBool(ctx, b, ptrToBool(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, ptrToBool(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBoolPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBytes: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBytes: +			p := load(ctxptr, code.Idx) +			v := ptrToBytes(p + uintptr(code.Offset)) +			if len(v) > 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBytesPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumber: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = appendStructEnd(ctx, code, bb) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumber: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = appendStructEnd(ctx, code, bb) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumberString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = append(bb, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumberString: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumberPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = appendStructEnd(ctx, code, bb) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumberPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpEnd: +			goto END +		} +	} +END: +	return b, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go new file mode 100644 index 000000000..99395388c --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go @@ -0,0 +1,35 @@ +package vm_indent + +import ( +	"fmt" + +	"github.com/goccy/go-json/internal/encoder" +) + +func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { +	var code *encoder.Opcode +	if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { +		code = codeSet.EscapeKeyCode +	} else { +		code = codeSet.NoescapeKeyCode +	} + +	defer func() { +		if err := recover(); err != nil { +			w := ctx.Option.DebugOut +			fmt.Fprintln(w, "=============[DEBUG]===============") +			fmt.Fprintln(w, "* [TYPE]") +			fmt.Fprintln(w, codeSet.Type) +			fmt.Fprintf(w, "\n") +			fmt.Fprintln(w, "* [ALL OPCODE]") +			fmt.Fprintln(w, code.Dump()) +			fmt.Fprintf(w, "\n") +			fmt.Fprintln(w, "* [CONTEXT]") +			fmt.Fprintf(w, "%+v\n", ctx) +			fmt.Fprintln(w, "===================================") +			panic(err) +		} +	}() + +	return Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go new file mode 100644 index 000000000..9e245bfe5 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go @@ -0,0 +1,9 @@ +package vm_indent + +import ( +	// HACK: compile order +	// `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile, +	// so forcibly make dependencies and avoid compiling in concurrent. +	// dependency order: vm => vm_indent => vm_color => vm_color_indent +	_ "github.com/goccy/go-json/internal/encoder/vm_color" +) diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go new file mode 100644 index 000000000..fca8f1855 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go @@ -0,0 +1,229 @@ +package vm_indent + +import ( +	"encoding/json" +	"fmt" +	"unsafe" + +	"github.com/goccy/go-json/internal/encoder" +	"github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +var ( +	appendInt           = encoder.AppendInt +	appendUint          = encoder.AppendUint +	appendFloat32       = encoder.AppendFloat32 +	appendFloat64       = encoder.AppendFloat64 +	appendString        = encoder.AppendString +	appendByteSlice     = encoder.AppendByteSlice +	appendNumber        = encoder.AppendNumber +	appendStructEnd     = encoder.AppendStructEndIndent +	appendIndent        = encoder.AppendIndent +	errUnsupportedValue = encoder.ErrUnsupportedValue +	errUnsupportedFloat = encoder.ErrUnsupportedFloat +	mapiterinit         = encoder.MapIterInit +	mapiterkey          = encoder.MapIterKey +	mapitervalue        = encoder.MapIterValue +	mapiternext         = encoder.MapIterNext +	maplen              = encoder.MapLen +) + +type emptyInterface struct { +	typ *runtime.Type +	ptr unsafe.Pointer +} + +type nonEmptyInterface struct { +	itab *struct { +		ityp *runtime.Type // static interface type +		typ  *runtime.Type // dynamic concrete type +		// unused fields... +	} +	ptr unsafe.Pointer +} + +func errUnimplementedOp(op encoder.OpType) error { +	return fmt.Errorf("encoder (indent): opcode %s has not been implemented", op) +} + +func load(base uintptr, idx uint32) uintptr { +	addr := base + uintptr(idx) +	return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uint32, p uintptr) { +	addr := base + uintptr(idx) +	**(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr { +	addr := base + uintptr(idx) +	p := **(**uintptr)(unsafe.Pointer(&addr)) +	for i := uint8(0); i < ptrNum; i++ { +		if p == 0 { +			return 0 +		} +		p = ptrToPtr(p) +	} +	return p +} + +func ptrToUint64(p uintptr, bitSize uint8) uint64 { +	switch bitSize { +	case 8: +		return (uint64)(**(**uint8)(unsafe.Pointer(&p))) +	case 16: +		return (uint64)(**(**uint16)(unsafe.Pointer(&p))) +	case 32: +		return (uint64)(**(**uint32)(unsafe.Pointer(&p))) +	case 64: +		return **(**uint64)(unsafe.Pointer(&p)) +	} +	return 0 +} +func ptrToFloat32(p uintptr) float32            { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64            { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool                  { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte               { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number         { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string              { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { +	return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum uint8) uintptr { +	for i := uint8(0); i < ptrNum; i++ { +		if p == 0 { +			return 0 +		} +		p = ptrToPtr(p) +	} +	return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { +	return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { +	return *(*interface{})(unsafe.Pointer(&emptyInterface{ +		typ: code.Type, +		ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), +	})) +} + +func appendBool(_ *encoder.RuntimeContext, b []byte, v bool) []byte { +	if v { +		return append(b, "true"...) +	} +	return append(b, "false"...) +} + +func appendNull(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, "null"...) +} + +func appendComma(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, ',', '\n') +} + +func appendNullComma(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, "null,\n"...) +} + +func appendColon(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, ':', ' ') +} + +func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte { +	b = appendIndent(ctx, b, code.Indent+1) +	b = append(b, key...) +	b[len(b)-2] = ':' +	b[len(b)-1] = ' ' +	return append(b, value...) +} + +func appendMapEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	b = b[:len(b)-2] +	b = append(b, '\n') +	b = appendIndent(ctx, b, code.Indent) +	return append(b, '}', ',', '\n') +} + +func appendArrayHead(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	b = append(b, '[', '\n') +	return appendIndent(ctx, b, code.Indent+1) +} + +func appendArrayEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	b = b[:len(b)-2] +	b = append(b, '\n') +	b = appendIndent(ctx, b, code.Indent) +	return append(b, ']', ',', '\n') +} + +func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, '[', ']', ',', '\n') +} + +func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, '{', '}', ',', '\n') +} + +func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	last := len(b) - 1 +	b[last] = '\n' +	b = appendIndent(ctx, b, code.Indent-1) +	return append(b, '}', ',', '\n') +} + +func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { +	return encoder.AppendMarshalJSONIndent(ctx, code, b, v) +} + +func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { +	return encoder.AppendMarshalTextIndent(ctx, code, b, v) +} + +func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte { +	return append(b, '{', '\n') +} + +func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	b = appendIndent(ctx, b, code.Indent) +	b = append(b, code.Key...) +	return append(b, ' ') +} + +func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	last := len(b) - 1 +	if b[last-1] == '{' { +		b[last] = '}' +	} else { +		if b[last] == '\n' { +			// to remove ',' and '\n' characters +			b = b[:len(b)-2] +		} +		b = append(b, '\n') +		b = appendIndent(ctx, b, code.Indent-1) +		b = append(b, '}') +	} +	return appendComma(ctx, b) +} + +func restoreIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, ctxptr uintptr) { +	ctx.BaseIndent = uint32(load(ctxptr, code.Length)) +} + +func storeIndent(ctxptr uintptr, code *encoder.Opcode, indent uintptr) { +	store(ctxptr, code.Length, indent) +} + +func appendArrayElemIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	return appendIndent(ctx, b, code.Indent+1) +} + +func appendMapKeyIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { +	return appendIndent(ctx, b, code.Indent) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go new file mode 100644 index 000000000..836c5c8a8 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go @@ -0,0 +1,4859 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package vm_indent + +import ( +	"math" +	"reflect" +	"sort" +	"unsafe" + +	"github.com/goccy/go-json/internal/encoder" +	"github.com/goccy/go-json/internal/runtime" +) + +func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { +	recursiveLevel := 0 +	ptrOffset := uintptr(0) +	ctxptr := ctx.Ptr() +	var code *encoder.Opcode +	if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { +		code = codeSet.EscapeKeyCode +	} else { +		code = codeSet.NoescapeKeyCode +	} + +	for { +		switch code.Op { +		default: +			return nil, errUnimplementedOp(code.Op) +		case encoder.OpPtr: +			p := load(ctxptr, code.Idx) +			code = code.Next +			store(ctxptr, code.Idx, ptrToPtr(p)) +		case encoder.OpIntPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpInt: +			b = appendInt(ctx, b, load(ctxptr, code.Idx), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpUintPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpUint: +			b = appendUint(ctx, b, load(ctxptr, code.Idx), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpIntString: +			b = append(b, '"') +			b = appendInt(ctx, b, load(ctxptr, code.Idx), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpUintString: +			b = append(b, '"') +			b = appendUint(ctx, b, load(ctxptr, code.Idx), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpFloat32Ptr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +				b = appendComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpFloat32: +			b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpFloat64Ptr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpFloat64: +			v := ptrToFloat64(load(ctxptr, code.Idx)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStringPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpString: +			b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpBoolPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpBool: +			b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpBytesPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpBytes: +			b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpNumberPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpNumber: +			bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx))) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpInterfacePtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpInterface: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			if recursiveLevel > encoder.StartDetectingCyclesAfter { +				for _, seen := range ctx.SeenPtr { +					if p == seen { +						return nil, errUnsupportedValue(code, p) +					} +				} +			} +			ctx.SeenPtr = append(ctx.SeenPtr, p) +			var ( +				typ      *runtime.Type +				ifacePtr unsafe.Pointer +			) +			up := ptrToUnsafePtr(p) +			if code.Flags&encoder.NonEmptyInterfaceFlags != 0 { +				iface := (*nonEmptyInterface)(up) +				ifacePtr = iface.ptr +				if iface.itab != nil { +					typ = iface.itab.typ +				} +			} else { +				iface := (*emptyInterface)(up) +				ifacePtr = iface.ptr +				typ = iface.typ +			} +			if ifacePtr == nil { +				isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ) +				if !isDirectedNil { +					b = appendNullComma(ctx, b) +					code = code.Next +					break +				} +			} +			ctx.KeepRefs = append(ctx.KeepRefs, up) +			ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ))) +			if err != nil { +				return nil, err +			} + +			totalLength := uintptr(code.Length) + 3 +			nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3 + +			var c *encoder.Opcode +			if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { +				c = ifaceCodeSet.InterfaceEscapeKeyCode +			} else { +				c = ifaceCodeSet.InterfaceNoescapeKeyCode +			} +			curlen := uintptr(len(ctx.Ptrs)) +			offsetNum := ptrOffset / uintptrSize +			oldOffset := ptrOffset +			ptrOffset += totalLength * uintptrSize +			oldBaseIndent := ctx.BaseIndent +			ctx.BaseIndent += code.Indent + +			newLen := offsetNum + totalLength + nextTotalLength +			if curlen < newLen { +				ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) +			} +			ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + +			end := ifaceCodeSet.EndCode +			store(ctxptr, c.Idx, uintptr(ifacePtr)) +			store(ctxptr, end.Idx, oldOffset) +			store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next))) +			storeIndent(ctxptr, end, uintptr(oldBaseIndent)) +			code = c +			recursiveLevel++ +		case encoder.OpInterfaceEnd: +			recursiveLevel-- + +			// restore ctxptr +			offset := load(ctxptr, code.Idx) +			restoreIndent(ctx, code, ctxptr) +			ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + +			codePtr := load(ctxptr, code.ElemIdx) +			code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) +			ctxptr = ctx.Ptr() + offset +			ptrOffset = offset +		case encoder.OpMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, ptrToPtr(p)) +			fallthrough +		case encoder.OpMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p) +			} +			bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, ptrToPtr(p)) +			fallthrough +		case encoder.OpMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = append(b, `""`...) +				b = appendComma(ctx, b) +				code = code.Next +				break +			} +			if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p) +			} +			bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpSlicePtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpSlice: +			p := load(ctxptr, code.Idx) +			slice := ptrToSlice(p) +			if p == 0 || slice.Data == nil { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.ElemIdx, 0) +			store(ctxptr, code.Length, uintptr(slice.Len)) +			store(ctxptr, code.Idx, uintptr(slice.Data)) +			if slice.Len > 0 { +				b = appendArrayHead(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, uintptr(slice.Data)) +			} else { +				b = appendEmptyArray(ctx, b) +				code = code.End.Next +			} +		case encoder.OpSliceElem: +			idx := load(ctxptr, code.ElemIdx) +			length := load(ctxptr, code.Length) +			idx++ +			if idx < length { +				b = appendArrayElemIndent(ctx, code, b) +				store(ctxptr, code.ElemIdx, idx) +				data := load(ctxptr, code.Idx) +				size := uintptr(code.Size) +				code = code.Next +				store(ctxptr, code.Idx, data+idx*size) +			} else { +				b = appendArrayEnd(ctx, code, b) +				code = code.End.Next +			} +		case encoder.OpArrayPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpArray: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			if code.Length > 0 { +				b = appendArrayHead(ctx, code, b) +				store(ctxptr, code.ElemIdx, 0) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				b = appendEmptyArray(ctx, b) +				code = code.End.Next +			} +		case encoder.OpArrayElem: +			idx := load(ctxptr, code.ElemIdx) +			idx++ +			if idx < uintptr(code.Length) { +				b = appendArrayElemIndent(ctx, code, b) +				store(ctxptr, code.ElemIdx, idx) +				p := load(ctxptr, code.Idx) +				size := uintptr(code.Size) +				code = code.Next +				store(ctxptr, code.Idx, p+idx*size) +			} else { +				b = appendArrayEnd(ctx, code, b) +				code = code.End.Next +			} +		case encoder.OpMapPtr: +			p := loadNPtr(ctxptr, code.Idx, code.PtrNum) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, p) +			fallthrough +		case encoder.OpMap: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.End.Next +				break +			} +			uptr := ptrToUnsafePtr(p) +			mlen := maplen(uptr) +			if mlen <= 0 { +				b = appendEmptyObject(ctx, b) +				code = code.End.Next +				break +			} +			b = appendStructHead(ctx, b) +			unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 +			mapCtx := encoder.NewMapContext(mlen, unorderedMap) +			mapiterinit(code.Type, uptr, &mapCtx.Iter) +			store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx))) +			ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) +			if unorderedMap { +				b = appendMapKeyIndent(ctx, code.Next, b) +			} else { +				mapCtx.Start = len(b) +				mapCtx.First = len(b) +			} +			key := mapiterkey(&mapCtx.Iter) +			store(ctxptr, code.Next.Idx, uintptr(key)) +			code = code.Next +		case encoder.OpMapKey: +			mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) +			idx := mapCtx.Idx +			idx++ +			if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { +				if idx < mapCtx.Len { +					b = appendMapKeyIndent(ctx, code, b) +					mapCtx.Idx = int(idx) +					key := mapiterkey(&mapCtx.Iter) +					store(ctxptr, code.Next.Idx, uintptr(key)) +					code = code.Next +				} else { +					b = appendObjectEnd(ctx, code, b) +					encoder.ReleaseMapContext(mapCtx) +					code = code.End.Next +				} +			} else { +				mapCtx.Slice.Items[mapCtx.Idx].Value = b[mapCtx.Start:len(b)] +				if idx < mapCtx.Len { +					mapCtx.Idx = int(idx) +					mapCtx.Start = len(b) +					key := mapiterkey(&mapCtx.Iter) +					store(ctxptr, code.Next.Idx, uintptr(key)) +					code = code.Next +				} else { +					code = code.End +				} +			} +		case encoder.OpMapValue: +			mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) +			if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { +				b = appendColon(ctx, b) +			} else { +				mapCtx.Slice.Items[mapCtx.Idx].Key = b[mapCtx.Start:len(b)] +				mapCtx.Start = len(b) +			} +			value := mapitervalue(&mapCtx.Iter) +			store(ctxptr, code.Next.Idx, uintptr(value)) +			mapiternext(&mapCtx.Iter) +			code = code.Next +		case encoder.OpMapEnd: +			// this operation only used by sorted map. +			mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) +			sort.Sort(mapCtx.Slice) +			buf := mapCtx.Buf +			for _, item := range mapCtx.Slice.Items { +				buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value) +			} +			buf = appendMapEnd(ctx, code, buf) +			b = b[:mapCtx.First] +			b = append(b, buf...) +			mapCtx.Buf = buf +			encoder.ReleaseMapContext(mapCtx) +			code = code.Next +		case encoder.OpRecursivePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				code = code.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpRecursive: +			ptr := load(ctxptr, code.Idx) +			if ptr != 0 { +				if recursiveLevel > encoder.StartDetectingCyclesAfter { +					for _, seen := range ctx.SeenPtr { +						if ptr == seen { +							return nil, errUnsupportedValue(code, ptr) +						} +					} +				} +			} +			ctx.SeenPtr = append(ctx.SeenPtr, ptr) +			c := code.Jmp.Code +			curlen := uintptr(len(ctx.Ptrs)) +			offsetNum := ptrOffset / uintptrSize +			oldOffset := ptrOffset +			ptrOffset += code.Jmp.CurLen * uintptrSize +			oldBaseIndent := ctx.BaseIndent +			indentDiffFromTop := c.Indent - 1 +			ctx.BaseIndent += code.Indent - indentDiffFromTop + +			newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen +			if curlen < newLen { +				ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) +			} +			ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + +			store(ctxptr, c.Idx, ptr) +			store(ctxptr, c.End.Next.Idx, oldOffset) +			store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) +			storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent)) +			code = c +			recursiveLevel++ +		case encoder.OpRecursiveEnd: +			recursiveLevel-- + +			// restore ctxptr +			restoreIndent(ctx, code, ctxptr) +			offset := load(ctxptr, code.Idx) +			ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + +			codePtr := load(ctxptr, code.ElemIdx) +			code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) +			ctxptr = ctx.Ptr() + offset +			ptrOffset = offset +		case encoder.OpStructPtrHead: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHead: +			p := load(ctxptr, code.Idx) +			if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if len(code.Key) > 0 { +				if (code.Flags&encoder.IsTaggedKeyFlags) != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { +					b = appendStructKey(ctx, code, b) +				} +			} +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmpty: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmpty: +			p := load(ctxptr, code.Idx) +			if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadInt: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadInt: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyInt: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyInt: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadIntString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadIntString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyIntString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyIntString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			u64 := ptrToUint64(p, code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendInt(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadUint: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadUint: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUint: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyUint: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadUintString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadUintString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUintString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyUintString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendUint(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat32: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat32: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat32String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat32String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat64: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat64: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat64String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadFloat64String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat64(ctx, b, v) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64String: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64String: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v == 0 { +				code = code.NextField +			} else { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNull(ctx, b) +					b = appendComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToString(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadStringString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadStringString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset))))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyStringString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyStringString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToString(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, ptrToString(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, ptrToString(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadBool: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadBool: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBool: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyBool: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} else { +				code = code.NextField +			} +		case encoder.OpStructPtrHeadBoolString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadBoolString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBoolString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyBoolString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} else { +				code = code.NextField +			} +		case encoder.OpStructPtrHeadBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendBool(ctx, b, ptrToBool(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, ptrToBool(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadBytes: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadBytes: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBytes: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyBytes: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToBytes(p + uintptr(code.Offset)) +			if len(v) == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, v) +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadNumber: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadNumber: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumber: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumber: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +				code = code.Next +			} +		case encoder.OpStructPtrHeadNumberString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadNumberString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = append(bb, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumberString: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumberString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v == "" { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructPtrHeadNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadArray, encoder.OpStructHeadSlice: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmptyArray: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyArray: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			b = appendStructKey(ctx, code, b) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmptySlice: +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p := load(ctxptr, code.Idx) +				if p == 0 { +					if code.Flags&encoder.AnonymousHeadFlags == 0 { +						b = appendNullComma(ctx, b) +					} +					code = code.End.Next +					break +				} +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptySlice: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			slice := ptrToSlice(p) +			if slice.Len == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.NextField +			} else { +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadMap: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMap: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p + uintptr(code.Offset)) +			} +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructPtrHeadOmitEmptyMap: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMap: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				p = ptrToPtr(p + uintptr(code.Offset)) +			} +			if maplen(ptrToUnsafePtr(p)) == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.NextField +				break +			} +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.NextField +			} else { +				if (code.Flags & encoder.IndirectFlags) != 0 { +					p = ptrToNPtr(p, code.PtrNum) +				} +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadOmitEmptyMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMapPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p == 0 { +				code = code.NextField +				break +			} +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p == 0 { +				code = code.NextField +			} else { +				if (code.Flags & encoder.IndirectFlags) != 0 { +					p = ptrToNPtr(p, code.PtrNum) +				} +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructPtrHeadMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { +					p = ptrToPtr(p) +				} +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalJSON: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { +					p = ptrToPtr(p) +				} +			} +			iface := ptrToInterface(code, p) +			if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalJSON(ctx, code, b, iface) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { +					p = ptrToPtr(p) +				} +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			} +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalText: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { +					p = ptrToPtr(p) +				} +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructPtrHeadMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			b = appendStructKey(ctx, code, b) +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) +			fallthrough +		case encoder.OpStructHeadOmitEmptyMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { +				if code.Flags&encoder.AnonymousHeadFlags == 0 { +					b = appendNullComma(ctx, b) +				} +				code = code.End.Next +				break +			} +			if (code.Flags & encoder.IndirectFlags) != 0 { +				p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			} +			if code.Flags&encoder.AnonymousHeadFlags == 0 { +				b = appendStructHead(ctx, b) +			} +			if p == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +				b = appendComma(ctx, b) +				code = code.Next +			} +		case encoder.OpStructField: +			if code.Flags&encoder.IsTaggedKeyFlags != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { +				b = appendStructKey(ctx, code, b) +			} +			p := load(ctxptr, code.Idx) + uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmpty: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructFieldInt: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyInt: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldIntString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyIntString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldIntPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendInt(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldIntPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUint: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUint: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUintString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUintString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUintPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendUint(ctx, b, p, code) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p, code) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldUintPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32String: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat32PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat64(ctx, b, v) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNullComma(ctx, b) +				code = code.Next +				break +			} +			v := ptrToFloat64(p) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldFloat64PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldStringString: +			p := load(ctxptr, code.Idx) +			s := ptrToString(p + uintptr(code.Offset)) +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyStringString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldStringPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, ptrToString(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, ptrToString(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldStringPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBool: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBool: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBoolString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBoolString: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, v) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBoolPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendBool(ctx, b, ptrToBool(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, ptrToBool(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBoolPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBytes: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBytes: +			p := load(ctxptr, code.Idx) +			v := ptrToBytes(p + uintptr(code.Offset)) +			if len(v) > 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, v) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldBytesPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldNumber: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumber: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldNumberString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = append(bb, '"') +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumberString: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldNumberPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldNumberPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			b = appendStructKey(ctx, code, b) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendComma(ctx, b) +			} +			code = code.Next +		case encoder.OpStructFieldMarshalJSON: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalJSON: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				code = code.NextField +				break +			} +			iface := ptrToInterface(code, p) +			if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { +				code = code.NextField +				break +			} +			b = appendStructKey(ctx, code, b) +			bb, err := appendMarshalJSON(ctx, code, b, iface) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructFieldMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalJSONPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldMarshalText: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalText: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if (code.Flags & encoder.IsNilableTypeFlags) != 0 { +				p = ptrToPtr(p) +			} +			if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { +				code = code.NextField +				break +			} +			b = appendStructKey(ctx, code, b) +			bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +			if err != nil { +				return nil, err +			} +			b = appendComma(ctx, bb) +			code = code.Next +		case encoder.OpStructFieldMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendComma(ctx, b) +			code = code.Next +		case encoder.OpStructFieldOmitEmptyMarshalTextPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) +				if err != nil { +					return nil, err +				} +				b = appendComma(ctx, bb) +			} +			code = code.Next +		case encoder.OpStructFieldArray: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyArray: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldArrayPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyArrayPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				code = code.NextField +			} +		case encoder.OpStructFieldSlice: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptySlice: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			slice := ptrToSlice(p) +			if slice.Len == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructFieldSlicePtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptySlicePtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				code = code.NextField +			} +		case encoder.OpStructFieldMap: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyMap: +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructFieldMapPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p != 0 { +				p = ptrToNPtr(p, code.PtrNum) +			} +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyMapPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToPtr(p + uintptr(code.Offset)) +			if p != 0 { +				p = ptrToNPtr(p, code.PtrNum) +			} +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} else { +				code = code.NextField +			} +		case encoder.OpStructFieldStruct: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			code = code.Next +			store(ctxptr, code.Idx, p) +		case encoder.OpStructFieldOmitEmptyStruct: +			p := load(ctxptr, code.Idx) +			p += uintptr(code.Offset) +			if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { +				code = code.NextField +			} else { +				b = appendStructKey(ctx, code, b) +				code = code.Next +				store(ctxptr, code.Idx, p) +			} +		case encoder.OpStructEnd: +			b = appendStructEndSkipLast(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndInt: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyInt: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndIntString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendInt(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyIntString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndIntPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendInt(ctx, b, p, code) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyIntPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendInt(ctx, b, p, code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndIntPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyIntPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendInt(ctx, b, p, code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUint: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUint: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUintString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendUint(ctx, b, p+uintptr(code.Offset), code) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUintString: +			p := load(ctxptr, code.Idx) +			u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) +			v := u64 & ((1 << code.NumBitSize) - 1) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p+uintptr(code.Offset), code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUintPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendUint(ctx, b, p, code) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUintPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendUint(ctx, b, p, code) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndUintPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyUintPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendUint(ctx, b, p, code) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32String: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat32(p + uintptr(code.Offset)) +			if v != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32Ptr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat32PtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat32PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat32(ctx, b, ptrToFloat32(p)) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = appendFloat64(ctx, b, v) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = appendFloat64(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendFloat64(ctx, b, v) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64String: +			p := load(ctxptr, code.Idx) +			v := ptrToFloat64(p + uintptr(code.Offset)) +			if v != 0 { +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64Ptr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +				b = appendStructEnd(ctx, code, b) +				code = code.Next +				break +			} +			v := ptrToFloat64(p) +			if math.IsInf(v, 0) || math.IsNaN(v) { +				return nil, errUnsupportedFloat(v) +			} +			b = appendFloat64(ctx, b, v) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64Ptr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndFloat64PtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyFloat64PtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				v := ptrToFloat64(p) +				if math.IsInf(v, 0) || math.IsNaN(v) { +					return nil, errUnsupportedFloat(v) +				} +				b = append(b, '"') +				b = appendFloat64(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndStringString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			s := ptrToString(p + uintptr(code.Offset)) +			b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyStringString: +			p := load(ctxptr, code.Idx) +			v := ptrToString(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndStringPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, ptrToString(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyStringPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, ptrToString(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndStringPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyStringPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBool: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBool: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBoolString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) +			b = append(b, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBoolString: +			p := load(ctxptr, code.Idx) +			v := ptrToBool(p + uintptr(code.Offset)) +			if v { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, v) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBoolPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendBool(ctx, b, ptrToBool(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBoolPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendBool(ctx, b, ptrToBool(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBoolPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBoolPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				b = appendBool(ctx, b, ptrToBool(p)) +				b = append(b, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBytes: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBytes: +			p := load(ctxptr, code.Idx) +			v := ptrToBytes(p + uintptr(code.Offset)) +			if len(v) > 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, v) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndBytesPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyBytesPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = appendByteSlice(ctx, b, ptrToBytes(p)) +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumber: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = appendStructEnd(ctx, code, bb) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumber: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = appendStructEnd(ctx, code, bb) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumberString: +			p := load(ctxptr, code.Idx) +			b = appendStructKey(ctx, code, b) +			b = append(b, '"') +			bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) +			if err != nil { +				return nil, err +			} +			b = append(bb, '"') +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumberString: +			p := load(ctxptr, code.Idx) +			v := ptrToNumber(p + uintptr(code.Offset)) +			if v != "" { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, v) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumberPtr: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = bb +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumberPtr: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = appendStructEnd(ctx, code, bb) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpStructEndNumberPtrString: +			b = appendStructKey(ctx, code, b) +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p == 0 { +				b = appendNull(ctx, b) +			} else { +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +			} +			b = appendStructEnd(ctx, code, b) +			code = code.Next +		case encoder.OpStructEndOmitEmptyNumberPtrString: +			p := load(ctxptr, code.Idx) +			p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) +			if p != 0 { +				b = appendStructKey(ctx, code, b) +				b = append(b, '"') +				bb, err := appendNumber(ctx, b, ptrToNumber(p)) +				if err != nil { +					return nil, err +				} +				b = append(bb, '"') +				b = appendStructEnd(ctx, code, b) +			} else { +				b = appendStructEndSkipLast(ctx, code, b) +			} +			code = code.Next +		case encoder.OpEnd: +			goto END +		} +	} +END: +	return b, nil +}  | 
