Help us shape the future of Go! Take the 2026 Go Developer Survey

encoder

package
v0.12.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 29, 2026 License: MIT Imports: 35 Imported by: 0

Documentation

Overview

This files's processing codes are inspired by https://github.com/segmentio/encoding. The license notation is as follows.

MIT License

Copyright (c) 2019 Segment.io, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Code generated by internal/cmd/generator. DO NOT EDIT.

Index

Constants

View Source
const KeyChunkSize = 32

KeyChunkSize is the size of the chunk which the VM copies a key by: a key up to it is written by the opcode of its field, as a chunk. A longer key is written by the generic field opcode, and its value by the opcode of the value.

View Source
const KeyEscapeOptions = HTMLEscapeOption | NormalizeUTF8Option

KeyEscapeOptions are the options by which the names of the fields are escaped, whose bits are the index of the opcodes of each escape ( see OpcodeSet.KeyCodes ): for HTML, and for JavaScript, U+2028 and U+2029.

View Source
const MaxDepth = 10000

MaxDepth is the deepest nesting of the objects and the arrays which encoding/json and encoding/json/v2 of Go 1.27 take: 10000 levels. The VM checks it where a frame is entered, and where a value of a list is ( see TailRecursiveFlags ), by the indent of the frame and the deepest level which the opcodes of the frame go to ( see deepestLevel ). The encoder of a method or a function, and the default representation of a value it declines, count their levels after the depth of the value ( see RuntimeContext.ValueDepth ). A value which is null, omitted or empty, as a nil pointer or a nil or empty map or slice, is counted as the levels its type would open, and a raw value which a method or a function returns is checked by its own depth only ( see AppendRaw ): an output which is so deep there passes.

View Source
const StartDetectingCyclesAfter = 998

StartDetectingCyclesAfter is the number of the frames ( see RuntimeContext.RecursiveLevel ) after which the values entered, and the maps, are recorded to detect a cycle.

It is 998, not the 1000 of encoding/json, as it counts frames, not the depth of the JSON value: the top-level value is written in the frame of the caller, and the check is made before the frame of a value is entered, so the level is the depth minus 1 there. With 998, the first value recorded is at the depth 1000 and a cycle is found at the depth 1001, where encoding/json/v2 reports it: its byte offset and JSON pointer are the same.

View Source
const StartDetectingMapCyclesAfter = StartDetectingCyclesAfter + 1

StartDetectingMapCyclesAfter is StartDetectingCyclesAfter for a map ( see RuntimeContext.RecordMap ), whose check is made in the frame of its value, one level past the check of a frame, which is made before it is entered.

View Source
const UncachedOption = recentUncachedOption | v1OpcodeOptions

UncachedOption are the options whose opcodes are not the ones of the tables shared by every goroutine: the ones of recentUncachedOption, and the options of encoding/json which change the opcodes of a type, whose opcodes are kept apart ( see v1OptionModes ).

Variables

View Source
var (
	Marshal   func(any) ([]byte, error)
	Unmarshal func([]byte, any) error
)
View Source
var ErrUseDefault = stderrors.New("use the default representation")

ErrUseDefault is the error of a method or a function of marshaling which declined to write the value: the value is written as if it didn't have it.

View Source
var RunHook func(ctx *RuntimeContext, b []byte, codeSet *OpcodeSet) ([]byte, error)

RunHook runs the VM of the options of ctx for the opcodes of a value, which ctx is set up for, after the output b: the run package sets it, which the encoder can't import.

View Source
var V2Hooks struct {
	// MarshalerToType is the interface of MarshalJSONTo.
	MarshalerToType reflect.Type
	// FormatRaw appends the raw value which a method or a function returned, checked and formatted as the options
	// of the context want it, which AppendFormattedRaw doesn't append ( see AppendRaw ): a SyntacticError of
	// jsontext for a value which is not valid, at its place in the output.
	FormatRaw func(ctx *RuntimeContext, b, raw []byte) ([]byte, error)
	// AppendRawMembers appends the members of the JSON object raw, a jsontext.Value embedded as a fallback, after
	// b, each followed by a comma: insertName records a name, and reports whether it may be written, if it is not
	// nil. Its errors are the ones of the v2 json package, at their places in the output.
	AppendRawMembers func(ctx *RuntimeContext, b, raw []byte, insertName func(name []byte) bool) ([]byte, error)
	// MarshalTo calls MarshalJSONTo of recv, the pointer to a value of typ, with an encoder which writes after the
	// output b.
	MarshalTo func(ctx *RuntimeContext, b []byte, typ reflect.Type, recv any) ([]byte, error)
	// MarshalToOf returns the function which calls MarshalJSONTo of the value of typ at an address, as MarshalTo
	// does, with the method found once for the type, or appendDefault if it declines ( see ErrUseDefault ).
	MarshalToOf func(typ reflect.Type, appendDefault AppendFunc) AppendFunc
}

V2Hooks are what the v2 json package gives the encoder: the functions which take jsontext, which the encoder doesn't import.

Functions

func AppendByteSlice

func AppendByteSlice(ctx *RuntimeContext, b []byte, src []byte) []byte

func AppendComma

func AppendComma(_ *RuntimeContext, b []byte) []byte

func AppendCommaIndent

func AppendCommaIndent(_ *RuntimeContext, b []byte) []byte

func AppendFloat32

func AppendFloat32(_ *RuntimeContext, b []byte, v float32) []byte

AppendFloat32 appends v as encoding/json writes a float32: by the shortest decimal which rounds to it, in the format 'f', or 'e' below 1e-6 and from 1e21, whose exponent has no leading zero.

func AppendFloat64

func AppendFloat64(_ *RuntimeContext, b []byte, v float64) []byte

AppendFloat64 appends v as encoding/json writes a float64, as AppendFloat32 does.

func AppendFormattedRaw added in v0.12.0

func AppendFormattedRaw(ctx *RuntimeContext, dst, src []byte) ([]byte, bool)

AppendFormattedRaw appends src, a raw value, to dst as the formatting of the v2 semantics with the escaping of ctx appends it, and reports true, if src is compact, valid JSON whose strings are valid UTF-8 without a control character or an escape of a surrogate, whose names have no escape, and whose objects have no duplicate names. Otherwise it reports false, and src is to be formatted: dst may have been written after its length then.

It reads src once, and once more for the escaping of the options, if any, and for UTF-8, if src has a byte which is not ASCII.

func AppendIndent

func AppendIndent(ctx *RuntimeContext, b []byte, indent uint32) []byte

func AppendInt

func AppendInt(_ *RuntimeContext, out []byte, p unsafe.Pointer, code *Opcode) []byte

func AppendMarshalJSON

func AppendMarshalJSON(ctx *RuntimeContext, code *Opcode, b []byte, p unsafe.Pointer) ([]byte, error)

AppendMarshalJSON appends what MarshalJSON of the value returns, compacted. p is the data word of the interface value of the type of the opcode: the address of the value, or the pointer for a pointer type.

func AppendMarshalJSONIndent

func AppendMarshalJSONIndent(ctx *RuntimeContext, code *Opcode, b []byte, p unsafe.Pointer) ([]byte, error)

func AppendMarshalText

func AppendMarshalText(ctx *RuntimeContext, code *Opcode, b []byte, p unsafe.Pointer) ([]byte, error)

AppendMarshalText appends what MarshalText of the value returns, as a string. p is the data word of the interface value of the type of the opcode: the address of the value, or the pointer for a pointer type.

func AppendMarshalTextIndent

func AppendMarshalTextIndent(ctx *RuntimeContext, code *Opcode, b []byte, p unsafe.Pointer) ([]byte, error)

AppendMarshalTextIndent is AppendMarshalText: the text has no indent.

func AppendNull

func AppendNull(_ *RuntimeContext, b []byte) []byte

func AppendNumber

func AppendNumber(ctx *RuntimeContext, b []byte, n json.Number) ([]byte, error)

AppendNumber appends n, which must be a JSON number by its grammar, as encoding/json writes a json.Number: an empty one as 0.

A number of up to 24 bytes is copied by the words which overlap, without a call of memmove, and the bytes which are not digits are found in the words as they are loaded, which the grammar is then checked by, without a call: an integer at once, and another number by the places of its bytes which are not digits.

A json.Number is a raw value for the options of encoding/json/v2 which rewrite raw values: they are checked here, in the function itself, as a call more costs every number.

func AppendNumberString added in v0.12.0

func AppendNumberString(ctx *RuntimeContext, b []byte, n json.Number) ([]byte, error)

AppendNumberString is AppendNumber of a json.Number of a field with the option string, which the caller quotes: its error shows the number quoted, as encoding/json shows it.

func AppendRaw added in v0.12.0

func AppendRaw(ctx *RuntimeContext, b, raw []byte) ([]byte, error)

AppendRaw appends the raw value which a method or a function returned, checked and formatted as the options of the context want it: as it is, or as AppendFormattedRaw writes it, without a call of the v2 json package, which formats the other values.

func AppendString

func AppendString(ctx *RuntimeContext, buf []byte, s string) []byte

AppendString appends the string as a JSON string, escaped as the options want it ( see jsonstring.AppendQuoted ).

func AppendStructEndIndent

func AppendStructEndIndent(ctx *RuntimeContext, code *Opcode, b []byte) []byte

func AppendUint

func AppendUint(_ *RuntimeContext, out []byte, p unsafe.Pointer, code *Opcode) []byte

func Compact

func Compact(buf *bytes.Buffer, src []byte, escape bool) error

Compact appends src to buf with the white space between its tokens left out, and the characters for HTML escaped if escape is set.

func DuplicateMapNameError added in v0.12.0

func DuplicateMapNameError(key, out []byte) error

DuplicateMapNameError returns the error of key, the name of an entry of a sorted map as it is encoded with a comma after it, which an entry before it has: out is the output before the name.

func EnterNested added in v0.12.0

func EnterNested(c, outer *RuntimeContext, codeSet *OpcodeSet, p unsafe.Pointer) error

EnterNested makes c, which encodes the value at p by codeSet within the encoding by outer, the frame after the ones of outer for the detection of cycles: a default representation of a value, which runs in a context of its own ( see runInner ), or MarshalEncode called by a method, whose cycles pass no frame of the VM. Past StartDetectingCyclesAfter, c has the records of outer, in the same arrays, as outer goes on only after c ends, and records the value by codeSet, not by its type: a value which a function declined is encoded again by the opcodes of its default representation, at the same address.

func ErrMaxDepth added in v0.12.0

func ErrMaxDepth(ctx *RuntimeContext) error

ErrMaxDepth returns the error of a value nested deeper than MaxDepth, as encoding/json and encoding/json/v2 report it: an error of the syntax of the output.

func ErrNilMapKey added in v0.12.0

func ErrNilMapKey(code *Opcode) error

ErrNilMapKey returns the error of a key of a map which is a nil pointer, the operand of code, which has no name ( see MapKeyFlags ).

func ErrUnsupportedFloat

func ErrUnsupportedFloat(ctx *RuntimeContext, code *Opcode, v float64) error

ErrUnsupportedFloat returns the error of a float which is not finite, the value of the opcode: of encoding/json, with the float, for v1 and for ReportErrorsWithLegacySemantics.

func ErrUnsupportedValue

func ErrUnsupportedValue(ctx *RuntimeContext, code *Opcode, ptr unsafe.Pointer) error

ErrUnsupportedValue returns the error of a cycle through the value at ptr, of the type of code: of the pointer to it for the opcode of a pointer.

func IfaceIndir added in v0.11.0

func IfaceIndir(typ unsafe.Pointer) bool

IfaceIndir reports whether a value of the type is stored indirectly in an interface value. It is decided only once per type, when the type is compiled.

func Indent

func Indent(buf *bytes.Buffer, src []byte, prefix, indent string) error

Indent appends src to buf indented, as encoding/json does: each element of an object or an array on a line of its own, after prefix and one indent for each level, and the white space after the value kept.

func InvalidUTF8 added in v0.12.0

func InvalidUTF8(ctx *RuntimeContext, before, after []byte) ([]byte, error)

InvalidUTF8 returns the output of a string which has invalid UTF-8, written by textEscaper, after the output before it: an error of RejectInvalidUTF8Option, or the string with U+FFFD.

func IsEmptyField added in v0.11.0

func IsEmptyField(kind EmptyKind, bitSize uint8, p unsafe.Pointer) bool

IsEmptyField is whether the value at p, of a field whose kind of emptiness is kind, is empty for omitempty.

func IsZeroField added in v0.11.1

func IsZeroField(code *Opcode, p unsafe.Pointer) bool

IsZeroField is whether the value at p, of the field of the opcode, is zero for omitzero.

func MapLen

func MapLen(p unsafe.Pointer) int

MapLen returns the number of the entries of the map at p. The length of a map is in its header, whatever its type, so the map is read as one of any type.

func NilMapIsEmpty added in v0.12.0

func NilMapIsEmpty(ctx *RuntimeContext) bool

NilMapIsEmpty is whether a nil map is written as an empty JSON object, as encoding/json/v2 does unless FormatNilMapAsNull, or as null.

func NilMapKeyError added in v0.12.0

func NilMapKeyError(code *Opcode) error

NilMapKeyError is the error of a key whose pointers, which the opcode code of what they lead to follows, end at nil ( see pointerMapKeyCode ), as encoding/json reports it: the nil pointer is reported as the last of them.

func NilSliceIsEmpty added in v0.12.0

func NilSliceIsEmpty(ctx *RuntimeContext) bool

NilSliceIsEmpty is whether a nil slice is written as an empty JSON array, as encoding/json/v2 does unless FormatNilSliceAsNull, or as null.

func PaddedKey added in v0.11.0

func PaddedKey(key string) string

PaddedKey returns the key whose memory has the bytes after it up to a chunk, so that a chunk is copied from the key without reading the memory of others.

func ReleaseMapContext

func ReleaseMapContext(rctx *RuntimeContext, c *MapContext)

func ReleaseRuntimeContext added in v0.4.13

func ReleaseRuntimeContext(ctx *RuntimeContext)

func SameMapName added in v0.12.0

func SameMapName(ctx *RuntimeContext, key, prev []byte) bool

SameMapName reports whether key, the name of an entry of a sorted map as it is encoded with a comma after it ( see MapItem ), is the name of the entry before it, prev, which is an error unless AllowDuplicateNamesOption.

func SetFieldQueryToContext added in v0.9.0

func SetFieldQueryToContext(ctx context.Context, query *FieldQuery) context.Context

func SetFlags added in v0.12.0

func SetFlags(ctx *RuntimeContext, flags OptionFlag)

SetFlags sets the options of ctx for an encoding of v2, which every setting of them which may change the options of encoding/json is made by, the others adding or dropping other options only: the recent opcodes are emptied if they were compiled for other options of encoding/json which change the opcodes, which their keys have no room for ( see recentV1Options ), by a call of its own, so that SetFlags is inlined into the callers.

func StringEscaper added in v0.12.0

func StringEscaper(ctx *RuntimeContext) *jsonstring.Escaper

StringEscaper is the escaper of the strings of the options, which the VM calls jsonstring.AppendQuoted with: set before the VM runs ( see RuntimeContext.SetEscaper ).

func UnwriteEmptyMember added in v0.12.0

func UnwriteEmptyMember(ctx *RuntimeContext, b []byte, keyLen int) []byte

UnwriteEmptyMember unwrites the member which ends the output b, whose key has keyLen bytes, if its value is empty, as the v2 semantics define it: null, "", {} or []. The opcode runs only right after the opcodes of its field wrote the member, the key followed by the value and a comma: a field which is omitted goes to NextField, past the opcode, so the member starts keyLen bytes before its value.

The value is empty if it is one of them right after the colon of the key: a longer value can end with the bytes of one, as "\"" ends with "", but doesn't start there.

Types

type AnonymousCode added in v0.8.0

type AnonymousCode interface {
	ToAnonymousOpcode(*compileContext) Opcodes
}

type AppendFunc added in v0.12.0

type AppendFunc func(ctx *RuntimeContext, b []byte, p unsafe.Pointer) ([]byte, error)

AppendFunc appends the JSON value of the value at p, the address of the value.

type ArrayCode added in v0.8.0

type ArrayCode struct {
	// contains filtered or unexported fields
}

func (*ArrayCode) Filter added in v0.9.0

func (c *ArrayCode) Filter(_ *FieldQuery) Code

func (*ArrayCode) Kind added in v0.8.0

func (c *ArrayCode) Kind() CodeKind

func (*ArrayCode) ToOpcode added in v0.8.0

func (c *ArrayCode) ToOpcode(ctx *compileContext) Opcodes

type BoolCode added in v0.8.0

type BoolCode struct {
	// contains filtered or unexported fields
}

func (*BoolCode) Filter added in v0.9.0

func (c *BoolCode) Filter(_ *FieldQuery) Code

func (*BoolCode) Kind added in v0.8.0

func (c *BoolCode) Kind() CodeKind

func (*BoolCode) ToOpcode added in v0.8.0

func (c *BoolCode) ToOpcode(ctx *compileContext) Opcodes

type BytesCode added in v0.8.0

type BytesCode struct {
	// contains filtered or unexported fields
}

func (*BytesCode) Filter added in v0.9.0

func (c *BytesCode) Filter(_ *FieldQuery) Code

func (*BytesCode) Kind added in v0.8.0

func (c *BytesCode) Kind() CodeKind

func (*BytesCode) ToOpcode added in v0.8.0

func (c *BytesCode) ToOpcode(ctx *compileContext) Opcodes

type Code added in v0.8.0

type Code interface {
	Kind() CodeKind
	ToOpcode(*compileContext) Opcodes
	Filter(*FieldQuery) Code
}

type CodeKind added in v0.8.0

type CodeKind int
const (
	CodeKindInterface CodeKind = iota
	CodeKindPtr
	CodeKindInt
	CodeKindUint
	CodeKindFloat
	CodeKindString
	CodeKindBool
	CodeKindStruct
	CodeKindMap
	CodeKindSlice
	CodeKindArray
	CodeKindBytes
	CodeKindMarshalJSON
	CodeKindMarshalText
	CodeKindRecursive
)

type CodeType

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
)

type ColorFormat added in v0.6.0

type ColorFormat = EncodeFormat

type ColorScheme added in v0.6.0

type ColorScheme = EncodeFormatScheme

type CompiledCode

type CompiledCode struct {
	Code    *Opcode
	CurLen  uintptr
	NextLen uintptr
	// Levels is the deepest level which Code goes to in its frame ( see deepestLevel ).
	Levels uint32
	// Embedded is whether the recursive struct is embedded in the struct which jumps to it.
	// The code to jump to is only the fields of the struct then: it has neither the braces nor the check of nil.
	Embedded bool
}

type Compiler added in v0.8.0

type Compiler struct {
	// contains filtered or unexported fields
}

type EmptyKind added in v0.11.0

type EmptyKind uint8

EmptyKind is what makes the value of a field empty for omitempty, as encoding/json decides it by the kind of the type of the field: false, 0, a nil pointer or interface value, or an empty array, slice, map or string.

const (
	EmptyNever EmptyKind = iota
	EmptyNil             // a nil pointer or interface value: the first word is zero
	EmptyBool
	EmptyInt // an integer of NumBitSize bits which is 0
	EmptyFloat32
	EmptyFloat64
	EmptyStringLen // a string whose length is zero
	EmptySliceLen  // a slice whose length is zero
	EmptyMapLen    // a map whose length is zero
	EmptyAlways    // an array of no element
)

type EncodeFormat added in v0.6.0

type EncodeFormat struct {
	Header string
	Footer string
}

type EncodeFormatScheme added in v0.6.0

type EncodeFormatScheme struct {
	Int       EncodeFormat
	Uint      EncodeFormat
	Float     EncodeFormat
	Bool      EncodeFormat
	String    EncodeFormat
	Binary    EncodeFormat
	ObjectKey EncodeFormat
	Null      EncodeFormat
}

type FieldQuery added in v0.9.0

type FieldQuery struct {
	Name   string
	Fields []*FieldQuery
	// contains filtered or unexported fields
}

func FieldQueryFromContext added in v0.9.0

func FieldQueryFromContext(ctx context.Context) *FieldQuery

func (*FieldQuery) Hash added in v0.9.0

func (q *FieldQuery) Hash() string

Hash returns the key of the opcodes filtered by the query.

func (*FieldQuery) MarshalJSON added in v0.9.0

func (q *FieldQuery) MarshalJSON() ([]byte, error)

func (*FieldQuery) QueryString added in v0.9.0

func (q *FieldQuery) QueryString() (FieldQueryString, error)

type FieldQueryString added in v0.9.0

type FieldQueryString string

func (FieldQueryString) Build added in v0.9.0

func (s FieldQueryString) Build() (*FieldQuery, error)

type FloatCode added in v0.8.0

type FloatCode struct {
	// contains filtered or unexported fields
}

func (*FloatCode) Filter added in v0.9.0

func (c *FloatCode) Filter(_ *FieldQuery) Code

func (*FloatCode) Kind added in v0.8.0

func (c *FloatCode) Kind() CodeKind

func (*FloatCode) ToOpcode added in v0.8.0

func (c *FloatCode) ToOpcode(ctx *compileContext) Opcodes

type IntCode added in v0.8.0

type IntCode struct {
	// contains filtered or unexported fields
}

func (*IntCode) Filter added in v0.9.0

func (c *IntCode) Filter(_ *FieldQuery) Code

func (*IntCode) Kind added in v0.8.0

func (c *IntCode) Kind() CodeKind

func (*IntCode) ToOpcode added in v0.8.0

func (c *IntCode) ToOpcode(ctx *compileContext) Opcodes

type InterfaceCode added in v0.8.0

type InterfaceCode struct {
	// contains filtered or unexported fields
}

func (*InterfaceCode) Filter added in v0.9.0

func (c *InterfaceCode) Filter(query *FieldQuery) Code

func (*InterfaceCode) Kind added in v0.8.0

func (c *InterfaceCode) Kind() CodeKind

func (*InterfaceCode) ToOpcode added in v0.8.0

func (c *InterfaceCode) ToOpcode(ctx *compileContext) Opcodes

type MapCode added in v0.8.0

type MapCode struct {
	// contains filtered or unexported fields
}

func (*MapCode) Filter added in v0.9.0

func (c *MapCode) Filter(_ *FieldQuery) Code

func (*MapCode) Kind added in v0.8.0

func (c *MapCode) Kind() CodeKind

func (*MapCode) ToOpcode added in v0.8.0

func (c *MapCode) ToOpcode(ctx *compileContext) Opcodes

type MapContext

type MapContext struct {

	// Keys are the keys of the entries, for keys of a string kind; RawKeys are the bytes of the keys of another
	// kind, keySize each; Values are the bytes of the values, valueSize each. The copies of the values may hold
	// pointers which the GC doesn't see, as the slots of the VM do: the map holds the values while they are
	// encoded.
	Keys    []string
	RawKeys []byte
	Values  []byte
	// Order is the entries sorted by their keys ( SortKeys ), for keys of a string kind; Sorted is whether
	// the entries are encoded in that order, or in the order of Slice, which is sorted when every key is encoded.
	Order []int32

	Sorted bool
	// DirectEntries is whether the entries of a sorted map are written directly by one call of the VM, up to one
	// whose value is left to its opcodes, as the entries of a map which is not sorted are written as it is read:
	// the values are written by one opcode of a scalar, or are of interface{} ( see MapLayout ).
	DirectEntries bool
	Len           int
	Idx           int
	// The keys of a sorted map whose keys are not of a string kind are encoded first, and the entries are written in
	// the order of their names after ( see SortEncodedKeys ): First is where the entries start in the buffer, Slice
	// has the keys and Buf is where they are copied.
	First int
	Slice *Mapslice

	Buf []byte
	// contains filtered or unexported fields
}

MapContext is what the VM encodes a map from: the entries read from the map ( MapLayout.Collect ), and the state of the entry being encoded.

func NewMapContext

func NewMapContext(rctx *RuntimeContext) *MapContext

NewMapContext returns the context to encode a map: the runtime context has one for each level of the maps nested in each other, kept from a call to the next, and refers to it while the VM has it in a slot, which the GC doesn't see.

func (*MapContext) KeyAt added in v0.11.0

func (c *MapContext) KeyAt(i int) unsafe.Pointer

KeyAt returns the address of the key of the entry: the string in Keys, or the bytes in RawKeys.

func (*MapContext) ScalarValue added in v0.11.2

func (c *MapContext) ScalarValue() bool

ScalarValue is whether the values of the map are written by one opcode of a scalar ( MapLayout.ScalarValue ).

func (*MapContext) SortByEncodedKeys added in v0.11.0

func (c *MapContext) SortByEncodedKeys()

SortByEncodedKeys makes the context write the entries in the order of their encoded keys, for a sorted map whose keys are not of a string kind: the VM encodes every key first and keeps it in Slice ( see OpMapValue ).

func (*MapContext) SortEncodedKeys added in v0.12.0

func (c *MapContext) SortEncodedKeys(rctx *RuntimeContext, b []byte, footer int) []byte

SortEncodedKeys sorts the keys of a sorted map whose keys are not of a string kind, which the VM has encoded one after another in b from First, each item with the keys up to the end of its own: they are moved to Buf, and the output is put back to First, where the entries are written in the order of the names.

The keys are sorted by their names, as encoding/json sorts them. A key is its name between quotes, with the codes of a color around it, which are the same for every key: the keys are compared without the quote which ends the name and what follows it, as a space or a '!' comes before the quote, and without the codes of the color which end the name of an integer, which is colored within its quotes: footer is their length, which the VM finds from the opcode of the keys. When a key has an escape, which is not in the order of its character, the escapes are decoded where the names differ ( see compareKeyNames ). It is not sort.Sort, which calls Less and Swap through an interface for every comparison: the maps to encode are small in most cases, and the sort was a tenth of the time to encode one.

func (*MapContext) SortKeys added in v0.11.0

func (c *MapContext) SortKeys()

SortKeys sorts the entries by their keys, which are strings, as encoding/json does: Order is the entries in that order.

A comparison of two keys is by their first eight bytes as one number first, which decides it for most of the keys of a JSON object, and by the strings only when those are the same: a comparison of strings is a call which costs more than the rest of a sort of a small map. The sort is written here, so that the comparisons are inlined into it: a sort which takes the comparison as a function, as slices.SortFunc does, calls it for every one.

func (*MapContext) ValueAt added in v0.11.0

func (c *MapContext) ValueAt(i int) unsafe.Pointer

ValueAt returns the address of the value of the entry. A value of no size has an address all the same: the opcode of a struct takes a nil one for a nil pointer.

type MapItem

type MapItem struct {
	Key   []byte
	Entry int
}

MapItem is a key of a sorted map whose keys are not of a string kind, as it is encoded with a comma after it, and the index of its entry in the MapContext. While the keys are encoded, Key is the keys from the first one up to the end of this one, in the output, which tells where it ends ( see MapContext.SortEncodedKeys ).

type MapLayout added in v0.11.0

type MapLayout struct {

	// StringKey is whether the keys are of a string kind: then they are in MapContext.Keys.
	StringKey bool
	// A map whose entries are not sorted is written by the VM as it reads the map, when its keys are of a
	// string kind and the values are written by one opcode of a scalar ( ScalarValue: the map is ranged over
	// as a map of the values of the basic type of ValueKind, appendMapScalarValues ), or when the values are of
	// interface{}, the map of a JSON object as a value of interface{} ( InterfaceValue: the values which hold a
	// scalar are written, and the others are read into the context, appendMapAsRead ).
	ScalarValue    bool
	InterfaceValue bool
	// ValueKind is the kind of the values.
	ValueKind reflect.Kind

	// Cyclic is whether an entry may hold the map again, which is recorded for the detection of cycles then ( see
	// RuntimeContext.RecordMap ): the type of a key or a value reaches the type of the map, or an interface.
	Cyclic bool
	// contains filtered or unexported fields
}

MapLayout is how the VM reads the entries of a map of a type, decided when the type is compiled.

func NewMapLayout added in v0.11.0

func NewMapLayout(typ reflect.Type) *MapLayout

NewMapLayout returns how the VM reads a map of the type.

func (*MapLayout) Collect added in v0.11.0

func (l *MapLayout) Collect(p unsafe.Pointer, c *MapContext) int

Collect reads the entries of the map at p into the context, and returns their number.

func (*MapLayout) Reset added in v0.11.0

func (l *MapLayout) Reset(c *MapContext)

Reset empties the context for the entries of a map of the layout.

type Mapslice

type Mapslice struct {
	Items []MapItem
}

type MarshalFunc added in v0.12.0

type MarshalFunc struct {
	Type reflect.Type
	// Append appends the value at p, of the type from: ErrUseDefault if the function declined to write it, which
	// lets the next function, the method or the kind of the type write it.
	Append func(ctx *RuntimeContext, b []byte, p unsafe.Pointer, from reflect.Type) ([]byte, error)
}

MarshalFunc is a function of marshaling, for the values of the types castable to Type ( see runtime.CastableTo ).

type MarshalFuncs added in v0.12.0

type MarshalFuncs struct {
	Funcs []MarshalFunc
	// contains filtered or unexported fields
}

MarshalFuncs are the functions of marshaling of a call, in the order they are tried, with the opcodes compiled for them.

type MarshalJSONCode added in v0.8.0

type MarshalJSONCode struct {
	// contains filtered or unexported fields
}

func (*MarshalJSONCode) Filter added in v0.9.0

func (c *MarshalJSONCode) Filter(query *FieldQuery) Code

func (*MarshalJSONCode) Kind added in v0.8.0

func (c *MarshalJSONCode) Kind() CodeKind

func (*MarshalJSONCode) ToOpcode added in v0.8.0

func (c *MarshalJSONCode) ToOpcode(ctx *compileContext) Opcodes

type MarshalTextCode added in v0.8.0

type MarshalTextCode struct {
	// contains filtered or unexported fields
}

func (*MarshalTextCode) Filter added in v0.9.0

func (c *MarshalTextCode) Filter(query *FieldQuery) Code

func (*MarshalTextCode) Kind added in v0.8.0

func (c *MarshalTextCode) Kind() CodeKind

func (*MarshalTextCode) ToOpcode added in v0.8.0

func (c *MarshalTextCode) ToOpcode(ctx *compileContext) Opcodes

type MarshalerCall added in v0.11.0

type MarshalerCall struct {
	// contains filtered or unexported fields
}

MarshalerCall is the method of a marshaler, as it is called with the data word of the interface value.

type OpFlags added in v0.6.0

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
	MapStringKeyFlags      OpFlags = 1 << 10 // the key of the map is a string, written by OpMapKey itself
	TailRecursiveFlags     OpFlags = 1 << 11 // the recursive value is the last field of a value of its own type, encoded in its frame
	InterfaceMapKeyFlags   OpFlags = 1 << 12 // the key of a map of an interface type, whose name is of its dynamic value, or of pointers, whose name is of what they lead to ( see appendInterfaceMapKey ): a key whose pointers end at nil has no name
	MapKeyFlags            OpFlags = 1 << 13 // the key of a map, whose name is "" for a nil pointer of MarshalText and an error for another nil pointer, while a nil pointer value is null
	StaticTypeFlags        OpFlags = 1 << 14 // the opcode of an interface encodes a value by the opcodes of its own type, as a value of interface{} would be, given the address of the value or, for a pointer type compiled to the value it points to, the pointer ( see InterfaceCode.static )
	MarshalerFuncFlags     OpFlags = 1 << 15 // the marshaler of the opcode is a function of the v2 semantics ( see MarshalerCall.appendValue ), which is called where the one of a context is
)

type OpType

type OpType uint16
const (
	OpEnd                                  OpType = 0
	OpInterface                            OpType = 1
	OpSliceElem                            OpType = 2
	OpSliceEnd                             OpType = 3
	OpArrayElem                            OpType = 4
	OpArrayEnd                             OpType = 5
	OpMapKey                               OpType = 6
	OpMapValue                             OpType = 7
	OpMapEnd                               OpType = 8
	OpRecursive                            OpType = 9
	OpRecursivePtr                         OpType = 10
	OpRecursiveEnd                         OpType = 11
	OpInterfaceEnd                         OpType = 12
	OpInt                                  OpType = 13
	OpUint                                 OpType = 14
	OpFloat32                              OpType = 15
	OpFloat64                              OpType = 16
	OpBool                                 OpType = 17
	OpString                               OpType = 18
	OpBytes                                OpType = 19
	OpNumber                               OpType = 20
	OpArray                                OpType = 21
	OpMap                                  OpType = 22
	OpSlice                                OpType = 23
	OpStruct                               OpType = 24
	OpMarshalJSON                          OpType = 25
	OpMarshalText                          OpType = 26
	OpIntString                            OpType = 27
	OpUintString                           OpType = 28
	OpFloat32String                        OpType = 29
	OpFloat64String                        OpType = 30
	OpBoolString                           OpType = 31
	OpStringString                         OpType = 32
	OpNumberString                         OpType = 33
	OpIntPtr                               OpType = 34
	OpUintPtr                              OpType = 35
	OpFloat32Ptr                           OpType = 36
	OpFloat64Ptr                           OpType = 37
	OpBoolPtr                              OpType = 38
	OpStringPtr                            OpType = 39
	OpBytesPtr                             OpType = 40
	OpNumberPtr                            OpType = 41
	OpArrayPtr                             OpType = 42
	OpMapPtr                               OpType = 43
	OpSlicePtr                             OpType = 44
	OpMarshalJSONPtr                       OpType = 45
	OpMarshalTextPtr                       OpType = 46
	OpInterfacePtr                         OpType = 47
	OpIntPtrString                         OpType = 48
	OpUintPtrString                        OpType = 49
	OpFloat32PtrString                     OpType = 50
	OpFloat64PtrString                     OpType = 51
	OpBoolPtrString                        OpType = 52
	OpStringPtrString                      OpType = 53
	OpNumberPtrString                      OpType = 54
	OpStructHead                           OpType = 55
	OpStructPtrHead                        OpType = 56
	OpStructFieldInt                       OpType = 57
	OpStructFieldOmitEmptyInt              OpType = 58
	OpStructEndInt                         OpType = 59
	OpStructEndOmitEmptyInt                OpType = 60
	OpStructFieldUint                      OpType = 61
	OpStructFieldOmitEmptyUint             OpType = 62
	OpStructEndUint                        OpType = 63
	OpStructEndOmitEmptyUint               OpType = 64
	OpStructFieldFloat32                   OpType = 65
	OpStructFieldOmitEmptyFloat32          OpType = 66
	OpStructEndFloat32                     OpType = 67
	OpStructEndOmitEmptyFloat32            OpType = 68
	OpStructFieldFloat64                   OpType = 69
	OpStructFieldOmitEmptyFloat64          OpType = 70
	OpStructEndFloat64                     OpType = 71
	OpStructEndOmitEmptyFloat64            OpType = 72
	OpStructFieldBool                      OpType = 73
	OpStructFieldOmitEmptyBool             OpType = 74
	OpStructEndBool                        OpType = 75
	OpStructEndOmitEmptyBool               OpType = 76
	OpStructFieldString                    OpType = 77
	OpStructFieldOmitEmptyString           OpType = 78
	OpStructEndString                      OpType = 79
	OpStructEndOmitEmptyString             OpType = 80
	OpStructFieldBytes                     OpType = 81
	OpStructFieldOmitEmptyBytes            OpType = 82
	OpStructEndBytes                       OpType = 83
	OpStructEndOmitEmptyBytes              OpType = 84
	OpStructFieldNumber                    OpType = 85
	OpStructFieldOmitEmptyNumber           OpType = 86
	OpStructEndNumber                      OpType = 87
	OpStructEndOmitEmptyNumber             OpType = 88
	OpStructFieldArray                     OpType = 89
	OpStructFieldOmitEmptyArray            OpType = 90
	OpStructEndArray                       OpType = 91
	OpStructEndOmitEmptyArray              OpType = 92
	OpStructFieldMap                       OpType = 93
	OpStructFieldOmitEmptyMap              OpType = 94
	OpStructEndMap                         OpType = 95
	OpStructEndOmitEmptyMap                OpType = 96
	OpStructFieldSlice                     OpType = 97
	OpStructFieldOmitEmptySlice            OpType = 98
	OpStructEndSlice                       OpType = 99
	OpStructEndOmitEmptySlice              OpType = 100
	OpStructFieldStruct                    OpType = 101
	OpStructFieldOmitEmptyStruct           OpType = 102
	OpStructEndStruct                      OpType = 103
	OpStructEndOmitEmptyStruct             OpType = 104
	OpStructFieldMarshalJSON               OpType = 105
	OpStructFieldOmitEmptyMarshalJSON      OpType = 106
	OpStructEndMarshalJSON                 OpType = 107
	OpStructEndOmitEmptyMarshalJSON        OpType = 108
	OpStructFieldMarshalText               OpType = 109
	OpStructFieldOmitEmptyMarshalText      OpType = 110
	OpStructEndMarshalText                 OpType = 111
	OpStructEndOmitEmptyMarshalText        OpType = 112
	OpStructFieldIntString                 OpType = 113
	OpStructFieldOmitEmptyIntString        OpType = 114
	OpStructEndIntString                   OpType = 115
	OpStructEndOmitEmptyIntString          OpType = 116
	OpStructFieldUintString                OpType = 117
	OpStructFieldOmitEmptyUintString       OpType = 118
	OpStructEndUintString                  OpType = 119
	OpStructEndOmitEmptyUintString         OpType = 120
	OpStructFieldFloat32String             OpType = 121
	OpStructFieldOmitEmptyFloat32String    OpType = 122
	OpStructEndFloat32String               OpType = 123
	OpStructEndOmitEmptyFloat32String      OpType = 124
	OpStructFieldFloat64String             OpType = 125
	OpStructFieldOmitEmptyFloat64String    OpType = 126
	OpStructEndFloat64String               OpType = 127
	OpStructEndOmitEmptyFloat64String      OpType = 128
	OpStructFieldBoolString                OpType = 129
	OpStructFieldOmitEmptyBoolString       OpType = 130
	OpStructEndBoolString                  OpType = 131
	OpStructEndOmitEmptyBoolString         OpType = 132
	OpStructFieldStringString              OpType = 133
	OpStructFieldOmitEmptyStringString     OpType = 134
	OpStructEndStringString                OpType = 135
	OpStructEndOmitEmptyStringString       OpType = 136
	OpStructFieldNumberString              OpType = 137
	OpStructFieldOmitEmptyNumberString     OpType = 138
	OpStructEndNumberString                OpType = 139
	OpStructEndOmitEmptyNumberString       OpType = 140
	OpStructFieldIntPtr                    OpType = 141
	OpStructFieldOmitEmptyIntPtr           OpType = 142
	OpStructEndIntPtr                      OpType = 143
	OpStructEndOmitEmptyIntPtr             OpType = 144
	OpStructFieldUintPtr                   OpType = 145
	OpStructFieldOmitEmptyUintPtr          OpType = 146
	OpStructEndUintPtr                     OpType = 147
	OpStructEndOmitEmptyUintPtr            OpType = 148
	OpStructFieldFloat32Ptr                OpType = 149
	OpStructFieldOmitEmptyFloat32Ptr       OpType = 150
	OpStructEndFloat32Ptr                  OpType = 151
	OpStructEndOmitEmptyFloat32Ptr         OpType = 152
	OpStructFieldFloat64Ptr                OpType = 153
	OpStructFieldOmitEmptyFloat64Ptr       OpType = 154
	OpStructEndFloat64Ptr                  OpType = 155
	OpStructEndOmitEmptyFloat64Ptr         OpType = 156
	OpStructFieldBoolPtr                   OpType = 157
	OpStructFieldOmitEmptyBoolPtr          OpType = 158
	OpStructEndBoolPtr                     OpType = 159
	OpStructEndOmitEmptyBoolPtr            OpType = 160
	OpStructFieldStringPtr                 OpType = 161
	OpStructFieldOmitEmptyStringPtr        OpType = 162
	OpStructEndStringPtr                   OpType = 163
	OpStructEndOmitEmptyStringPtr          OpType = 164
	OpStructFieldBytesPtr                  OpType = 165
	OpStructFieldOmitEmptyBytesPtr         OpType = 166
	OpStructEndBytesPtr                    OpType = 167
	OpStructEndOmitEmptyBytesPtr           OpType = 168
	OpStructFieldNumberPtr                 OpType = 169
	OpStructFieldOmitEmptyNumberPtr        OpType = 170
	OpStructEndNumberPtr                   OpType = 171
	OpStructEndOmitEmptyNumberPtr          OpType = 172
	OpStructFieldArrayPtr                  OpType = 173
	OpStructFieldOmitEmptyArrayPtr         OpType = 174
	OpStructEndArrayPtr                    OpType = 175
	OpStructEndOmitEmptyArrayPtr           OpType = 176
	OpStructFieldMapPtr                    OpType = 177
	OpStructFieldOmitEmptyMapPtr           OpType = 178
	OpStructEndMapPtr                      OpType = 179
	OpStructEndOmitEmptyMapPtr             OpType = 180
	OpStructFieldSlicePtr                  OpType = 181
	OpStructFieldOmitEmptySlicePtr         OpType = 182
	OpStructEndSlicePtr                    OpType = 183
	OpStructEndOmitEmptySlicePtr           OpType = 184
	OpStructFieldMarshalJSONPtr            OpType = 185
	OpStructFieldOmitEmptyMarshalJSONPtr   OpType = 186
	OpStructEndMarshalJSONPtr              OpType = 187
	OpStructEndOmitEmptyMarshalJSONPtr     OpType = 188
	OpStructFieldMarshalTextPtr            OpType = 189
	OpStructFieldOmitEmptyMarshalTextPtr   OpType = 190
	OpStructEndMarshalTextPtr              OpType = 191
	OpStructEndOmitEmptyMarshalTextPtr     OpType = 192
	OpStructFieldInterfacePtr              OpType = 193
	OpStructFieldOmitEmptyInterfacePtr     OpType = 194
	OpStructEndInterfacePtr                OpType = 195
	OpStructEndOmitEmptyInterfacePtr       OpType = 196
	OpStructFieldIntPtrString              OpType = 197
	OpStructFieldOmitEmptyIntPtrString     OpType = 198
	OpStructEndIntPtrString                OpType = 199
	OpStructEndOmitEmptyIntPtrString       OpType = 200
	OpStructFieldUintPtrString             OpType = 201
	OpStructFieldOmitEmptyUintPtrString    OpType = 202
	OpStructEndUintPtrString               OpType = 203
	OpStructEndOmitEmptyUintPtrString      OpType = 204
	OpStructFieldFloat32PtrString          OpType = 205
	OpStructFieldOmitEmptyFloat32PtrString OpType = 206
	OpStructEndFloat32PtrString            OpType = 207
	OpStructEndOmitEmptyFloat32PtrString   OpType = 208
	OpStructFieldFloat64PtrString          OpType = 209
	OpStructFieldOmitEmptyFloat64PtrString OpType = 210
	OpStructEndFloat64PtrString            OpType = 211
	OpStructEndOmitEmptyFloat64PtrString   OpType = 212
	OpStructFieldBoolPtrString             OpType = 213
	OpStructFieldOmitEmptyBoolPtrString    OpType = 214
	OpStructEndBoolPtrString               OpType = 215
	OpStructEndOmitEmptyBoolPtrString      OpType = 216
	OpStructFieldStringPtrString           OpType = 217
	OpStructFieldOmitEmptyStringPtrString  OpType = 218
	OpStructEndStringPtrString             OpType = 219
	OpStructEndOmitEmptyStringPtrString    OpType = 220
	OpStructFieldNumberPtrString           OpType = 221
	OpStructFieldOmitEmptyNumberPtrString  OpType = 222
	OpStructEndNumberPtrString             OpType = 223
	OpStructEndOmitEmptyNumberPtrString    OpType = 224
	OpStructFieldInterface                 OpType = 225
	OpStructFieldOmitEmptyInterface        OpType = 226
	OpStructEndInterface                   OpType = 227
	OpStructEndOmitEmptyInterface          OpType = 228
	OpStructField                          OpType = 229
	OpStructFieldOmitEmpty                 OpType = 230
	OpStructEnd                            OpType = 231
	OpStructEndOmitEmpty                   OpType = 232
	OpStructFieldInt3                      OpType = 233
	OpStructFieldInt2                      OpType = 234
	OpStructFieldUint3                     OpType = 235
	OpStructFieldUint2                     OpType = 236
	OpStructFieldFloat643                  OpType = 237
	OpStructFieldFloat642                  OpType = 238
	OpStructFieldString3                   OpType = 239
	OpStructFieldString2                   OpType = 240
	OpStructFieldBool3                     OpType = 241
	OpStructFieldBool2                     OpType = 242
	OpMapEndMayRepeatNames                 OpType = 243
	OpUnwriteEmpty                         OpType = 244
	OpStructFieldOmitEmptyStringPtrOrEmpty OpType = 245
)

func (OpType) CodeType

func (t OpType) CodeType() CodeType

func (OpType) FieldToEnd

func (t OpType) FieldToEnd() OpType

func (OpType) FieldToOmitEmptyField

func (t OpType) FieldToOmitEmptyField() OpType

func (OpType) HeadToPtrHead

func (t OpType) HeadToPtrHead() OpType

func (OpType) IsMultipleOpField

func (t OpType) IsMultipleOpField() bool

func (OpType) PtrHeadToHead

func (t OpType) PtrHeadToHead() OpType

func (OpType) String

func (t OpType) String() string

func (OpType) ToStringOp added in v0.11.0

func (t OpType) ToStringOp() OpType

ToStringOp returns the opcode which encodes the value of t as a string, for the string option of a field.

type Opcode

type Opcode struct {
	Op         OpType    // operation type
	EmptyKind  EmptyKind // what makes the value of the field empty for omitempty, for the generic field opcode and the ones of a marshaler
	ZeroKind   ZeroKind  // what makes the value of the field zero for omitzero, for the generic field opcode
	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       unsafe.Pointer      // pointer to the type descriptor of go type
	Jmp        *CompiledCode       // for recursive call
	Marshaler  *MarshalerCall      // the method of the marshaler, for MarshalJSON and MarshalText
	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
	KeyChunk   *[KeyChunkSize]byte // the key and the padding after it, which the VM copies as a chunk
	Map        *MapLayout          // how the entries of the map are read, for the opcode of a map
}

func ToEndCode added in v0.7.2

func ToEndCode(code *Opcode) *Opcode

func (*Opcode) Dump

func (c *Opcode) Dump() string

func (*Opcode) DumpDOT added in v0.10.2

func (c *Opcode) DumpDOT() string

func (*Opcode) IsEnd added in v0.8.0

func (c *Opcode) IsEnd() bool

func (*Opcode) IterNext added in v0.8.0

func (c *Opcode) IterNext() *Opcode

func (*Opcode) MaxIdx added in v0.6.1

func (c *Opcode) MaxIdx() uint32

func (*Opcode) ToFieldType

func (c *Opcode) ToFieldType(isString bool) OpType

func (*Opcode) TotalLength

func (c *Opcode) TotalLength() int

func (*Opcode) Validate added in v0.8.0

func (c *Opcode) Validate() error

type OpcodeSet

type OpcodeSet struct {
	Type reflect.Type
	// IfaceIndir is whether a value of Type is stored indirectly in an interface value.
	// It is decided when the type is compiled, because deciding it is not cheap.
	IfaceIndir bool
	// DataWordIsAddr is whether the data word of an interface value of Type is the address of the value
	// which the opcodes take: the type is stored indirectly, or it is a pointer, which is the address of
	// the value it points to.
	DataWordIsAddr bool
	// Levels is how many levels deeper than the place of the value its opcodes go in their frame ( see
	// deepestLevel ).
	Levels uint32
	// KeyCodes and InterfaceKeyCodes are the opcodes of the value, and of the value held by an interface value, for
	// each escape of the names of the fields, indexed by the options of KeyEscapeOptions.
	KeyCodes          [4]*Opcode
	InterfaceKeyCodes [4]*Opcode
	CodeLength        int
	EndCode           *Opcode
	// Scalar is the opcode of the value if the type is encoded by a single opcode of a scalar ( a number,
	// a string, a bool, ... ), or nil. Such a value held by an interface value is encoded without a frame.
	Scalar *Opcode
	Code   Code
	// contains filtered or unexported fields
}

func CompileToGetCodeSet

func CompileToGetCodeSet(ctx *RuntimeContext, typeptr uintptr) (*OpcodeSet, error)

CompileToGetCodeSet returns the opcodes of the type, compiling them if the type is new.

func PointeeOf added in v0.12.0

func PointeeOf(ctx *RuntimeContext, codeSet *OpcodeSet) *OpcodeSet

PointeeOf returns the opcodes of the value which a pointer of the type of codeSet points to, if it is stored indirectly in an interface value, or nil. With functions of marshaling, encoding/json/v2 encodes a pointer at the top level as the value it points to, addressable, so that the functions are given the value, or the pointer for the functions of pointers, not the address of the pointer: the pointer, the data word, is the address of the value for its opcodes. A value stored directly, as a pointer or a map, is encoded by the opcodes of the pointer, which give the functions of the pointer to it the address of it, as encoding/json/v2 does.

func (*OpcodeSet) TakeValue added in v0.11.0

func (s *OpcodeSet) TakeValue(ctx *RuntimeContext) unsafe.Pointer

TakeValue returns the address of a zero value of Type in the heap.

The runtime context keeps the value of the type it encoded last, because taking one from a sync.Pool costs as much as a small allocation, and a runtime context is already taken from a pool.

type Opcodes added in v0.8.0

type Opcodes []*Opcode

func (Opcodes) Add added in v0.8.0

func (o Opcodes) Add(codes ...*Opcode) Opcodes

func (Opcodes) First added in v0.8.0

func (o Opcodes) First() *Opcode

func (Opcodes) Last added in v0.8.0

func (o Opcodes) Last() *Opcode

type Option

type Option struct {
	Flag OptionFlag
	// Escaper is the escaper of the strings ( see RuntimeContext.SetEscaper ), set for the options EscaperFlags,
	// unless it is the one of RejectInvalidUTF8Option of the context: next to the options, which the VM reads for
	// every value, as it reads it for every string.
	Escaper      *jsonstring.Escaper
	EscaperFlags OptionFlag
	// V2 is the state of the call of the v2 json package, which its hooks take ( see V2Hooks ): a pointer to its
	// type, which the encoder doesn't know, read and compared without the type of an interface value.
	V2 unsafe.Pointer
	// Funcs are the functions of marshaling of the call, of MarshalFuncsOption.
	Funcs       *MarshalFuncs
	ColorScheme *ColorScheme
	Context     context.Context
	DebugOut    io.Writer
	DebugDOTOut io.WriteCloser
}

type OptionFlag added in v0.6.0

type OptionFlag uint32
const (
	// The options of the escaper of the strings are the lowest bits: they are its index ( see StringEscaper ).
	//
	// NormalizeUTF8Option replaces invalid UTF-8 with U+FFFD and escapes U+2028 and U+2029, as encoding/json
	// does; for the v2 semantics, it escapes U+2028 and U+2029 ( EscapeForJS of jsontext ).
	NormalizeUTF8Option OptionFlag = 1 << iota
	HTMLEscapeOption
	// TextEscapeOption escapes the strings as jsontext does, for the v2 semantics.
	TextEscapeOption
	// RejectInvalidUTF8Option, with TextEscapeOption, fails a string of invalid UTF-8, which is written with
	// U+FFFD otherwise: the escaper records the output before the string ( see RuntimeContext.InvalidUTF8Output ),
	// which the v2 json package reports.
	RejectInvalidUTF8Option
	IndentOption
	UnorderedMapOption
	DebugOption
	ColorizeOption
	ContextOption
	FieldQueryOption
	// OptimizeFieldOrderOption lets the encoder order the fields of a struct as it encodes them fastest:
	// the fields of the same kind together, and a recursive field last. The opcodes of a type are compiled
	// for it apart from the ones for the order of the struct.
	OptimizeFieldOrderOption
	// V2Option is the semantics of encoding/json/v2, which the v2 json package encodes by: the opcodes of a type
	// are compiled for it apart from the ones of the v1 semantics.
	V2Option
	// StringifyNumbersOption encodes a number as a JSON string, for the v2 semantics: the opcodes of the numbers
	// are compiled for it.
	StringifyNumbersOption
	// OmitZeroStructFieldsOption omits every field of a struct which is zero, for the v2 semantics: the opcodes of
	// the fields are compiled for it.
	OmitZeroStructFieldsOption
	// StringTagOption encodes the value as the value of a field of the `string` option, which applies to it, not to
	// the values in it, as encoding/json/v2 applies it: the opcodes of the value are compiled for it ( see
	// stringTagCode ).
	StringTagOption
	// The options of encoding/json/v2 which the opcodes of the v2 semantics look at as they encode: the ones which
	// may differ from a call to another for the same opcodes.
	//
	// FormatNilSliceAsNullOption encodes a nil slice as null, not [].
	FormatNilSliceAsNullOption
	// FormatNilMapAsNullOption encodes a nil map as null, not {}.
	FormatNilMapAsNullOption
	// AllowDuplicateNamesOption lets a JSON object have the same name twice, which is an error otherwise.
	AllowDuplicateNamesOption
	// MatchCaseInsensitiveNamesOption matches the names of an embedded fallback with the names of the fields case
	// insensitively, unless a field has the option case:strict.
	MatchCaseInsensitiveNamesOption
	// MarshalFuncsOption is the functions of WithMarshalers of encoding/json/v2 ( Option.Funcs ), whose opcodes
	// are compiled for them apart from the ones of the tables shared by every goroutine.
	MarshalFuncsOption
	// RawRewriteOption is the options of encoding/json/v2 which rewrite the raw values which the methods and the
	// functions of marshaling return, which AppendFormattedRaw doesn't follow: they are formatted by the v2 json
	// package ( see V2Hooks.FormatRaw ).
	RawRewriteOption
	// The options of the semantics of encoding/json which the v2 json package applies when marshaling ( see the
	// options of the root package ), in the order of their properties in internal/options, from
	// MatchCaseSensitiveDelimiter, so that they are copied at once ( see optionFlags of the v2 json package ). The
	// ones from CallMethodsWithLegacySemanticsOption change the opcodes of a type ( see v1OpcodeOptions ).
	//
	// MatchCaseSensitiveDelimiterOption restricts the case-insensitive matching of the names of an embedded fallback
	// ( by MatchCaseInsensitiveNamesOption or case:ignore ) to strings.EqualFold: an underscore or a dash is not
	// ignored.
	MatchCaseSensitiveDelimiterOption
	CallMethodsWithLegacySemanticsOption
	FormatByteArrayAsArrayOption
	FormatBytesWithLegacySemanticsOption
	FormatDurationAsNanoOption
	ReportErrorsWithLegacySemanticsOption
	StringifyWithLegacySemanticsOption
	OmitEmptyWithLegacySemanticsOption
)

type PtrCode added in v0.8.0

type PtrCode struct {
	// contains filtered or unexported fields
}

func (*PtrCode) Filter added in v0.9.0

func (c *PtrCode) Filter(query *FieldQuery) Code

func (*PtrCode) Kind added in v0.8.0

func (c *PtrCode) Kind() CodeKind

func (*PtrCode) ToAnonymousOpcode added in v0.8.0

func (c *PtrCode) ToAnonymousOpcode(ctx *compileContext) Opcodes

func (*PtrCode) ToOpcode added in v0.8.0

func (c *PtrCode) ToOpcode(ctx *compileContext) Opcodes

type RuntimeContext

type RuntimeContext struct {
	Buf        []byte
	MarshalBuf []byte
	Slots      []uintptr
	SeenPtr    []SeenValue

	BaseIndent uint32
	// RecursiveLevel and SlotOffset are the state of the VM which only the opcodes of an interface value and of
	// a recursive type use. They are here, not in the variables of the VM: the VM keeps its variables in the
	// registers across the opcodes, and it has to restore every one of them after each call in an opcode.
	RecursiveLevel int
	SlotOffset     uintptr
	// TailLevels is the number of the values of a recursive type which are being encoded in the current frame,
	// one after the other as the last field of the previous, without a frame of their own: see the cases of
	// OpRecursive and OpRecursiveEnd of the VM. Their braces are closed one by one when the last of them ends.
	TailLevels uint32
	Prefix     []byte
	IndentStr  []byte
	Option     *Option

	// Outer is the context of the encoding which a call of MarshalEncode by a method is nested in, for the call
	// ( see EnterNested ).
	Outer *RuntimeContext

	// KeyName is whether the key of a map is being written, by a method or a function of marshaling.
	KeyName bool
	// V2State is the state of the calls of the v2 json package which use the context, which is kept with it: a
	// pointer to its type, which the encoder doesn't know, read without the check of a type assertion.
	V2State unsafe.Pointer
	// RescanNames is whether the output is to be read again for the names which an object has twice, for the
	// v2 semantics: a name with invalid UTF-8 was written with U+FFFD.
	RescanNames bool
	// RewriteFrom is the first offset of the output which was written again, or shortened, since it was last
	// reset, or math.MaxInt: the v2 json package, which follows the output as it grows, reads it again from there.
	RewriteFrom int
	// ValueDepth is the number of the objects and the arrays which are open around the value which a function or a
	// method of the v2 semantics is called for, in the whole output ( see AppendMarshalJSON ): the encoder which it
	// is given, and the values which it writes in a context of their own ( see runInner ), count their levels after
	// it.
	ValueDepth uint32
	// contains filtered or unexported fields
}

func TakeRuntimeContext added in v0.4.13

func TakeRuntimeContext() *RuntimeContext

func (*RuntimeContext) EnterInterface added in v0.11.0

func (c *RuntimeContext) EnterInterface(code *Opcode, p unsafe.Pointer) (*Opcode, unsafe.Pointer, bool, error)

EnterInterface enters the frame of the value held by the interface value at p, which is the operand of code. It returns the first opcode of the frame and the base of its slots, or a nil opcode if the value is nil, which the caller writes as null.

If the value is a scalar, no frame is entered: it returns the opcode of the scalar, the address of the value and true, and the caller encodes the value by the opcode in its own frame. It saves the frame and two dispatches for the values which JSON has in a value of interface{}.

func (*RuntimeContext) EnterRecursive added in v0.11.0

func (c *RuntimeContext) EnterRecursive(code *Opcode, p unsafe.Pointer) (*Opcode, unsafe.Pointer, error)

EnterRecursive enters the frame of the value of the recursive type at p, which is the operand of code. It returns the first opcode of the frame and the base of its slots.

func (*RuntimeContext) HasInvalidUTF8 added in v0.12.0

func (c *RuntimeContext) HasInvalidUTF8() bool

HasInvalidUTF8 reports whether the encoding of RejectInvalidUTF8Option wrote a string of invalid UTF-8, which InvalidUTF8Output returns.

func (*RuntimeContext) Init

func (c *RuntimeContext) Init(p unsafe.Pointer, codelen int)

func (*RuntimeContext) InvalidUTF8Output added in v0.12.0

func (c *RuntimeContext) InvalidUTF8Output() ([]byte, bool)

InvalidUTF8Output returns the output before the first string of invalid UTF-8 which the encoding of RejectInvalidUTF8Option wrote, and true, and clears the record, which refers to the output; or false if it wrote none.

func (*RuntimeContext) LeaveFrame added in v0.11.0

func (c *RuntimeContext) LeaveFrame(end *Opcode) (*Opcode, unsafe.Pointer)

LeaveFrame leaves the frame which the end opcode ends, and returns the opcode to go on with and the base of the slots of the previous frame.

func (*RuntimeContext) Ptr

func (c *RuntimeContext) Ptr() unsafe.Pointer

Ptr returns the pointer to the slots. It is unsafe.Pointer, not uintptr, so that the address of a slot is calculated by unsafe.Add, which the compiler folds into the addressing mode of the load / store of the slot.

func (*RuntimeContext) RecentCodeSet added in v0.11.0

func (c *RuntimeContext) RecentCodeSet(typeptr uintptr) *OpcodeSet

RecentCodeSet returns the opcodes of the type if the context encoded it recently and has no context which may filter the fields, or nil: then, for a context which doesn't filter the fields, the first entry of the type in SharedCodeSets ( LoadFirst ), and CompileToGetCodeSet if that has another type.

A runtime context remembers the opcodes of the types it encoded last: the same types are encoded again and again in most of the programs, and this is cheaper than a lookup of the table shared by every goroutine. This is inlined into the callers: the values of interface{} come through it one by one.

func (*RuntimeContext) RecordMap added in v0.12.0

func (c *RuntimeContext) RecordMap(code *Opcode, p unsafe.Pointer, m *MapContext) error

RecordMap records the map at p of code, which the VM encodes past StartDetectingMapCyclesAfter, in m, for the detection of cycles, as encoding/json records a map: a cycle through the values of a map, which are copies, has the map alone as the value which it reaches again. The maps are recorded apart from the values of the frames, which a map is not compared with.

func (*RuntimeContext) RecordSeen added in v0.11.0

func (c *RuntimeContext) RecordSeen(code *Opcode, p unsafe.Pointer) error

RecordSeen records the value of a recursive type at p for the detection of cycles: the VM calls it before it begins a value of a list, when the level is deep enough for the detection.

func (*RuntimeContext) RememberCodeSet added in v0.12.0

func (c *RuntimeContext) RememberCodeSet(typeptr uintptr, codeSet *OpcodeSet)

RememberCodeSet puts the opcodes of the type in the first entry of its set in the context: the one encoded before it is kept in the second.

func (*RuntimeContext) ReserveSlots added in v0.11.0

func (c *RuntimeContext) ReserveSlots(length uintptr)

ReserveSlots makes the context have the slots of the frames up to the length.

func (*RuntimeContext) Rewrote added in v0.12.0

func (c *RuntimeContext) Rewrote(at int)

Rewrote records that the output was written again, or shortened, from the offset at.

func (*RuntimeContext) SetEscaper added in v0.12.0

func (c *RuntimeContext) SetEscaper()

SetEscaper sets the escaper of the strings of the options, which the VM writes them by ( see StringEscaper ), for an encoding by the context. The VM is run by the run package, which sets it itself for the options which most encodings have, without a call: it calls SetStrictEscaper for RejectInvalidUTF8Option.

func (*RuntimeContext) SetStrictEscaper added in v0.12.0

func (c *RuntimeContext) SetStrictEscaper()

SetStrictEscaper sets the escaper of RejectInvalidUTF8Option: one of the context, which records the first string of invalid UTF-8 ( see InvalidUTF8Output ).

It is not inlined into the run of the VM, which most encodings, of other options, run without its code.

func (*RuntimeContext) SharedCodeSets added in v0.12.0

func (c *RuntimeContext) SharedCodeSets() *runtime.TypeCache[OpcodeSet]

SharedCodeSets returns the table shared by every goroutine which has the opcodes of the context, of its compile mode. Its opcodes are not filtered by a field query, nor of the options of encoding/json, which have no such table: a context of them ( see UncachedOption ) is left to CompileToGetCodeSet, and the callers look at this table only for the other contexts.

Which types share a set of the recent opcodes depends on where the binary has them, and three types of a set encoded by turns, as the values of a map[string]interface{} are, evict each other. The VM looks such a type up in the entry it is hashed to in this table ( LoadFirst ), without a call, and gives the opcodes it finds to RememberCodeSet; only a type which another type has that entry of goes on to CompileToGetCodeSet, whose lookup of this table looks at the next entries without a call as well ( Load ). A full lookup in the VM measured slower even when the recent opcodes hit, as its loop changed the code of the VM around them.

func (*RuntimeContext) SortedKeysStart added in v0.12.0

func (c *RuntimeContext) SortedKeysStart() int

SortedKeysStart returns where the keys of the sorted map whose keys are being encoded start in the output, which are not entries yet ( see MapContext.SortEncodedKeys ): a method which writes a key sees the output before them.

func (*RuntimeContext) ValueAddr added in v0.11.0

func (c *RuntimeContext) ValueAddr(codeSet *OpcodeSet, dataWord unsafe.Pointer) unsafe.Pointer

ValueAddr returns the address of the value passed to Marshal, which the data word of its interface value represents.

The opcodes always take the address of a value. The data word of an interface value is the address for most of the types, but it is the value itself if the type is stored directly ( a pointer, a map, a struct of a single pointer, ... ). Such a value is copied to the context, and the address of the copy is returned.

type SeenValue added in v0.12.0

type SeenValue struct {
	// contains filtered or unexported fields
}

SeenValue is a value recorded to detect a cycle: its address, or the pointer which it is, the length of a slice, which another slice of the same array is not the same value as, or -1 for a struct recorded by the pointer it holds ( see recordSeenValue ), and its type, as values of other types at the same address, a struct and its first field, are other values. A cycle passes the same values again, of the same types.

type SliceCode added in v0.8.0

type SliceCode struct {
	// contains filtered or unexported fields
}

func (*SliceCode) Filter added in v0.9.0

func (c *SliceCode) Filter(_ *FieldQuery) Code

func (*SliceCode) Kind added in v0.8.0

func (c *SliceCode) Kind() CodeKind

func (*SliceCode) ToOpcode added in v0.8.0

func (c *SliceCode) ToOpcode(ctx *compileContext) Opcodes

type Slot added in v0.11.0

type Slot struct {
	Ptr unsafe.Pointer
	Int uintptr
}

Slot is the layout of a slot of the VM. The opcodes refer to a half of a slot by its offset from the head of the frame: Ptr is for a pointer ( the address of a value, the context of a map, the opcode to return to ) and Int is for the other values ( an index, a length, the offset of a frame, an indent ).

The slots are in the heap, and both halves are stored as uintptr there: a store of a pointer to the heap goes through the write barrier while the GC is marking, which made the encoding of a struct about 50% slower during that time. So the GC doesn't see the slots, and what they refer to is kept alive by others:

  • the value passed to Marshal is kept alive by its caller, and so is everything reachable from it
  • the value copied from an interface value is referred to by RuntimeContext
  • the context of a map is referred to by RuntimeContext

The opcodes are never freed.

type StringCode added in v0.8.0

type StringCode struct {
	// contains filtered or unexported fields
}

func (*StringCode) Filter added in v0.9.0

func (c *StringCode) Filter(_ *FieldQuery) Code

func (*StringCode) Kind added in v0.8.0

func (c *StringCode) Kind() CodeKind

func (*StringCode) ToOpcode added in v0.8.0

func (c *StringCode) ToOpcode(ctx *compileContext) Opcodes

type StructCode added in v0.8.0

type StructCode struct {
	// contains filtered or unexported fields
}

func (*StructCode) Filter added in v0.9.0

func (c *StructCode) Filter(query *FieldQuery) Code

func (*StructCode) Kind added in v0.8.0

func (c *StructCode) Kind() CodeKind

func (*StructCode) ToAnonymousOpcode added in v0.8.0

func (c *StructCode) ToAnonymousOpcode(ctx *compileContext) Opcodes

func (*StructCode) ToOpcode added in v0.8.0

func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes

type StructFieldCode added in v0.8.0

type StructFieldCode struct {
	// contains filtered or unexported fields
}

func (*StructFieldCode) ToAnonymousOpcode added in v0.8.0

func (c *StructFieldCode) ToAnonymousOpcode(ctx *compileContext, isFirstField bool) Opcodes

func (*StructFieldCode) ToOpcode added in v0.8.0

func (c *StructFieldCode) ToOpcode(ctx *compileContext, isFirstField, isEndField bool) Opcodes

type UintCode added in v0.8.0

type UintCode struct {
	// contains filtered or unexported fields
}

func (*UintCode) Filter added in v0.9.0

func (c *UintCode) Filter(_ *FieldQuery) Code

func (*UintCode) Kind added in v0.8.0

func (c *UintCode) Kind() CodeKind

func (*UintCode) ToOpcode added in v0.8.0

func (c *UintCode) ToOpcode(ctx *compileContext) Opcodes

type ValueShape added in v0.11.0

type ValueShape uint

ValueShape classifies a type by what a nil data word of an interface value of the type means.

const (
	// ValueShapePointer is the type whose nil data word is encoded as null: a pointer, a map, ...
	ValueShapePointer ValueShape = iota
	// ValueShapeAggregate is the type whose nil data word is a value to encode, if the type is stored directly
	// in an interface value:
	//   - a struct or an array which consists of a single pointer. The pointer is nil, not the value.
	//   - a map which has a marshaler. encoding/json writes null instead of calling the marshaler
	//     only for a nil pointer, so the marshaler of a nil map is called.
	//   - a channel, a function or an unsafe.Pointer, which has no JSON representation, nil or not: its
	//     compile fails, unless the type has a marshaler, which is called.
	ValueShapeAggregate
)

func ShapeOf added in v0.11.0

func ShapeOf(typ unsafe.Pointer) ValueShape

ShapeOf returns the shape of the type given by the pointer to its type descriptor.

ShapeOf and IfaceIndir are functions of their own, not a part of the VM, and the VM calls them in the same form as it did before, because any change of the code of the VM changes the register allocation of the whole VM.

type ZeroKind added in v0.11.1

type ZeroKind uint8

ZeroKind is what makes the value of a field zero for omitzero, as encoding/json decides it: by the IsZero method of the type if it has one, and else by reflect.Value.IsZero.

const (
	ZeroNever ZeroKind = iota
	// ZeroBits8 to ZeroBits64 are a value of 1 to 8 bytes whose bits are all zero: a bool, an integer,
	// a pointer, a map...
	ZeroBits8
	ZeroBits16
	ZeroBits32
	ZeroBits64
	// ZeroFloat32 and ZeroFloat64 are a float which is 0 or -0: reflect.Value.IsZero compares a float by its
	// value.
	ZeroFloat32
	ZeroFloat64
	ZeroString       // a string of no byte
	ZeroNilSlice     // a nil slice
	ZeroNilInterface // a nil interface value
	ZeroReflect      // a struct, an array or a complex number, as reflect.Value.IsZero decides
	ZeroMethod       // a type which has IsZero, which decides it
)

Directories

Path Synopsis
Package run drives the encoder: it compiles the opcodes of a value, sets up the runtime context and runs the VM which the options choose.
Package run drives the encoder: it compiles the opcodes of a value, sets up the runtime context and runs the VM which the options choose.
Code generated by internal/cmd/generator.
Code generated by internal/cmd/generator.
Code generated by internal/cmd/generator.
Code generated by internal/cmd/generator.
Code generated by internal/cmd/generator.
Code generated by internal/cmd/generator.
Code generated by internal/cmd/generator.
Code generated by internal/cmd/generator.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL